Modularity in CI/CD pipeline

Draft Disclaimer: Please note that this article is currently in draft form and may undergo revisions before final publication. The content, including information, opinions, and recommendations, is subject to change and may not represent the final version. We appreciate your understanding and patience as we work to refine and improve the quality of this article. Your feedback is valuable in shaping the final release.

Language Mismatch Disclaimer: Please be aware that the language of this article may not match the language settings of your browser or device.
Do you want to read articles in English instead ?

A bit of devops content

Intro

  • Some steps are repeated
  • some of those are long enough where it started to make sense to look into code reuse
  • shorter chunks, easier to read and understand even for a beginner
  • outline today
    • blocking action with needs for dependency between workflow
    • how to define local actions for reuse in many workflows
    • auto update with dependabots.yml and auto merge when build passes
    • auto merge PR when patches and minor version updates
    • concurrency: cancel previously running action when new one started (ie cancel previous deployment)
  • gotchas
    • do not use reserve words. github_token is reserved

Single deployment workflow = f(environment) (read that take environment as variable)

jobs:
  ReuseableMatrixJobForDeployment:
    strategy:
      matrix:
        target: [dev, stage, prod]
    uses: octocat/octo-repo/.github/workflows/deployment.yml@main
    with:
      target: ${{ matrix.target }}

Few examples:

  • https://github.com/spatie/laravel-activitylog/blob/main/.github/dependabot.yml
  • https://github.com/spatie/image/blob/main/.github/dependabot.yml
  • https://github.com/spatie/image/blob/main/.github/workflows/dependabot-auto-merge.yml#L36 You can modify the periodicity to weekly if you prefer. Then the following workflow on CI would do the automerging or when if: ${{steps.metadata.outputs.package-ecosystem == 'github_actions' && steps.metadata.outputs.update-type == 'version-update:semver-major' && steps.metadata.outputs.compatibility-score >= 90}}
on:
  pull_request:
    branches:
      - main
      
jobs:
  # Other jobs here
  # secrets.GITHUB_TOKEN exist by default I think, so change required for the following
  
  dependabot_auto_merge:
    runs-on: ubuntu-latest
    name: Automerge Dependabot PR
    needs: [php_lint, php_tests, php_static_analysis]
    if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}}
    steps:
      - name: Dependabot metadata
        id: metadata
        uses: dependabot/[email protected]
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Auto-merge Dependabot PRs for semver-minor updates
        if: ${{steps.metadata.outputs.update-type == 'version-update:semver-minor'}}
        run: gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Auto-merge Dependabot PRs for semver-patch updates
        if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
        run: gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CI run workflow on push, pull request and release

  • on push
    • build artifact
    • deploy
    • concurrency mode to prevent multiple deployments to same environment
  • on pull request to main branch
    • build
    • tests
      • lint
      • static code analysis
      • php tests
    • auto merge
      • when from dependabot but only minor and patch updates
      • and when tests passes