For this example, I merged two workflows provided by GitHub: .NET and Deploy to Amazon ECS. The idea is build a simple workflow like this:
Why Github Actions?
Github Actions offers workflows that can build the code in your repository and run your tests. Workflows can run on GitHub-hosted virtual machines, or on machines that you host yourself.
To start with Actions, create a new file in the .github/workflows directory named api-deployment.yml and copy the following YAML:
name: API workflow on: push: branches: [ main ] paths: - 'src/**' pull_request: branches: [ main ] paths: - 'src/**' jobs: build: name: Build API runs-on: ubuntu-latest env: working-directory: './src' steps: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 with: dotnet-version: '3.1.x' - name: Restore dependencies run: dotnet restore API.sln working-directory: ${{env.working-directory}} - run: dotnet build --no-restore working-directory: ${{env.working-directory}} - run: dotnet test --no-build --verbosity normal working-directory: ${{env.working-directory}} deploy-dev: name: Deploy to Dev if: github.event.ref == 'refs/heads/main' runs-on: ubuntu-latest needs: [build] steps: - name: Checkout uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-2 - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build, tag, and push image to Amazon ECR id: build-image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: your-ecr-name IMAGE_TAG: ${{ github.sha }} run: | # Build a docker container and # push it to ECR so that it can # be deployed to ECS. docker build -f src/api/Dockerfile -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG src/api docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" - 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: .github/task-definitions/your-api-task-definition.json container-name: your-container-name image: ${{ steps.build-image.outputs.image }} - name: Deploy Amazon ECS task definition uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.task-def.outputs.task-definition }} service: your-service-name cluster: your-cluster-name wait-for-service-stability: true
That is quite a long file, so let's start to dissect the most important lines.
Events
An event is an activity that triggers a workflow. To define the event (or events) we use the on keyword. Also, you can add constraints over those triggers.
Here we are setting that our action is going to be triggered on every push or pull request to main, and at least one modified file matches the configured paths.
Note: push and pull_request events support paths and paths-ignore filter, for more info read here
on: push: branches: [ main ] paths: - 'src/**' pull_request: branches: [ main ] paths: - 'src/**'
Jobs
A job is a set of steps that execute on the same runner. By default, a workflow with multiple jobs will run those jobs in parallel.
Build
Build is just a name for this job, you can set whatever you want. Here I'm using mostly the example from the .NET workflow. Will restore dependencies, build the code and run the unit tests.
build: name: Build API runs-on: ubuntu-latest env: working-directory: './src' steps: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 with: dotnet-version: '3.1.x' - name: Restore dependencies run: dotnet restore API.sln working-directory: ${{env.working-directory}} - run: dotnet build --no-restore working-directory: ${{env.working-directory}} - run: dotnet test --no-build --verbosity normal working-directory: ${{env.working-directory}}
Deploy-dev
Deploy-dev job is using the Github workflows templates,
an upcoming post will cover how to create this infrastructure in detail to complete a full deployment.
But I want to highlight the following block:
deploy-dev: name: Deploy to Dev if: github.event.ref == 'refs/heads/main' runs-on: ubuntu-latest needs: [build]
Using the needs keyword we define a dependency to the previous job build, only if the build was successfully completed this job is going to be executed. In that form, we change the default behavior of running the jobs in parallel to run sequentially.
On the other way, the if conditional allows avoiding the execution of a job unless a condition is met.
Here we use the github context to get the branch that is triggering the workflow, if the branch is "main" means that the PR was merged, so we can complete our deployment to our dev environment.
So that's it!
You can find a public repo with the example here
Top comments (0)