Both the Release and Rollback workflows leverage other workflows as reusable jobs for efficiency:
I follow a naming convention where reusable workflows are prefixed with wc-*.yml, where wc stands for workflow_call.
Check out .github/workflows/wc-deploy.yml file.
# This workflow will be called in release and rollback workflows
name: Deploy
on:
workflow_call:
inputs:
rollback:
description: "Set to true to perform a rollback deployment."
default: false
type: boolean
download-artifact-name:
description: "Name of the artifact to download for deployment."
default: ""
type: string
download-artifact-path:
description: "Path to store the downloaded artifact."
default: ""
type: string
aws-region:
description: "AWS region where resources are deployed."
default: us-east-1
type: string
role-to-assume:
description: "AWS IAM role to assume for deployment."
required: true
type: string
ecr-repository:
description: "ECR repository name where the Docker image is stored."
required: true
type: string
image-tag:
description: "Tag of the Docker image to deploy."
default: latest
type: string
task-definition:
description: "ECS task definition used for deployment."
required: true
type: string
container-name:
description: "Name of the container within the ECS task."
required: true
type: string
ecs-cluster:
description: "Name of the ECS cluster for deployment."
required: true
type: string
ecs-service:
description: "Name of the ECS service to update."
required: true
type: string
codedeploy-application:
description: "AWS CodeDeploy application name."
required: true
type: string
codedeploy-application-group:
description: "AWS CodeDeploy deployment group name."
required: true
type: string
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
env:
allow-download-artifact: ${{ !inputs.rollback && inputs.download-artifact-name != '' && inputs.download-artifact-path != '' }}
steps:
- if: ${{ fromJSON(env.allow-download-artifact) }}
name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.download-artifact-name }}
path: ${{ inputs.download-artifact-path }}
- if: ${{ fromJSON(env.allow-download-artifact) }}
name: Load image
run: docker load --input ${{ inputs.download-artifact-path }}/${{ inputs.download-artifact-name }}.tar
- name: Checkout appspec.yml
uses: actions/checkout@v4
with:
sparse-checkout: appspec.yml
sparse-checkout-cone-mode: false
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ inputs.aws-region }}
role-to-assume: ${{ inputs.role-to-assume }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Create image name
id: image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ inputs.ecr-repository }}
IMAGE_TAG: ${{ inputs.image-tag }}
run: |
echo "name=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
- if: ${{ !inputs.rollback }}
name: Tag image for releasing
run: docker tag localbuild/prepared-image:latest ${{ steps.image.outputs.name }}
- if: ${{ !inputs.rollback }}
name: Push Docker image to Amazon ECR
run: docker push ${{ steps.image.outputs.name }}
- if: ${{ inputs.rollback }}
name: Pull Docker image from Amazon ECR
run: docker pull ${{ steps.image.outputs.name }}
- name: Download task definition ${{ inputs.task-definition }}
run: |
aws ecs describe-task-definition \
--task-definition ${{ inputs.task-definition }} \
--query taskDefinition > task-definition.json
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: ${{ inputs.container-name }}
image: ${{ steps.image.outputs.name }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
cluster: ${{ inputs.ecs-cluster }}
service: ${{ inputs.ecs-service }}
task-definition: ${{ steps.task-def.outputs.task-definition }}
wait-for-service-stability: true
codedeploy-appspec: appspec.yml
codedeploy-application: ${{ inputs.codedeploy-application }}
codedeploy-deployment-group: ${{ inputs.codedeploy-application-group }}
This GitHub Actions workflow is designed to manage deployments to AWS ECS and integrates rollback capabilities. It is intended to be invoked by other workflows (e.g., Release and Rollback workflows) through the workflow_call event trigger, which allows input parameters to be passed to it.
workflow_call: it is called by other workflows, typically during a release or rollback process, with required inputs.
Deploy
Check out .github/workflows/wc-validate-version-format.yml file.
# This workflow will be called in release and rollback workflows
name: Validate format of semantic version
on:
workflow_call:
inputs:
version:
description: "Specify semantic version tag of the Docker image to check."
required: true
type: string
jobs:
validate-version-format:
name: Validate semantic version format
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: |
.github
sparse-checkout-cone-mode: false
- name: Create path to scripts
id: scripts
run: |
echo "path=./.github/scripts" >> $GITHUB_OUTPUT
- name: Validate format of semantic version ${{ inputs.version }}
run: |
chmod +x -R ./.github/scripts
${{ steps.scripts.outputs.path }}/validate-version-format.sh ${{ inputs.version }}
This GitHub Actions workflow is designed to validate the format of a semantic version string (for example, versions like 1.0.0) that is passed in as an input.
workflow_call: it is called by other workflows, typically during a release or rollback process, with the required input version.
validate-version-format