CD: stabilize #630
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 'CD: stabilize' | |
| on: | |
| create: | |
| push: | |
| branches: [ 'release/**' ] | |
| jobs: | |
| version: | |
| if: ${{ startsWith(github.ref, 'refs/heads/release/') }} | |
| secrets: inherit | |
| uses: './.github/workflows/find-releases.yml' | |
| notify-start: | |
| needs: | |
| - version | |
| uses: './.github/workflows/zulip.yml' | |
| secrets: inherit | |
| with: | |
| topic: "${{ needs.version.outputs.current_minor }} release" | |
| content: | | |
| :catspinq: `${{ needs.version.outputs.current_branch }}` branch workflow is [running #${{github.run_number}}](${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}) for [diff](${{ github.event.compare }}), see the next message in 1-40min. Last commit: | |
| - $COMMIT_TITLE | |
| changes: | |
| needs: | |
| - version | |
| if: ${{ !cancelled() && !failure() && needs.version.result == 'success' }} | |
| runs-on: ubuntu-24.04 | |
| permissions: { pull-requests: read } | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - id: filter | |
| uses: dorny/paths-filter@v3 | |
| name: Detect changed files | |
| with: { filters: .github/filters.yml } | |
| outputs: | |
| all: ${{ steps.filter.outputs.all }} | |
| darker: ${{ steps.filter.outputs.darker }} | |
| biome: ${{ steps.filter.outputs.biome }} | |
| openapi: ${{ steps.filter.outputs.openapi }} | |
| pytest: ${{ steps.filter.outputs.pytest }} | |
| npm-test: ${{ steps.filter.outputs.npm-test }} | |
| darker: | |
| needs: changes | |
| if: needs.changes.outputs.all == 'true' || needs.changes.outputs.darker == 'true' | |
| uses: ./.github/workflows/darker.yml | |
| biome: | |
| needs: changes | |
| if: needs.changes.outputs.all == 'true' || needs.changes.outputs.biome == 'true' | |
| uses: ./.github/workflows/biome.yml | |
| openapi: | |
| needs: changes | |
| if: needs.changes.outputs.all == 'true' || needs.changes.outputs.openapi == 'true' | |
| uses: ./.github/workflows/openapi.yml | |
| pytest: | |
| needs: changes | |
| if: needs.changes.outputs.all == 'true' || needs.changes.outputs.pytest == 'true' | |
| uses: ./.github/workflows/pytest.yml | |
| npm-test: | |
| needs: changes | |
| if: needs.changes.outputs.all == 'true' || needs.changes.outputs.npm-test == 'true' | |
| uses: ./.github/workflows/npm-test.yml | |
| changelog: | |
| needs: | |
| - version | |
| - changes | |
| - darker | |
| - biome | |
| - openapi | |
| - pytest | |
| - npm-test | |
| if: ${{ !cancelled() && !failure() && needs.version.result == 'success' }} | |
| runs-on: ubuntu-24.04 | |
| env: | |
| PREV_BRANCH: ${{ needs.version.outputs.prev_branch }} | |
| CURRENT_BRANCH: ${{ needs.version.outputs.current_branch }} | |
| CURRENT_PATCH: ${{ needs.version.outputs.current_patch }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: ./.github/actions/checkout-with-github-app-token | |
| with: | |
| app-id: ${{ secrets.KOBO_BOT_APP_ID }} | |
| private-key: ${{ secrets.KOBO_BOT_PRIVATE_KEY }} | |
| - name: draft a changelog | |
| run: | | |
| set -xe | |
| npx git-cliff -u $(git log --format=format:%H origin/$PREV_BRANCH..origin/$CURRENT_BRANCH | tail -1)..origin/$CURRENT_BRANCH --tag $CURRENT_PATCH | |
| - name: commit the changelog to a dedicated branch | |
| run: | | |
| set -xe | |
| git config user.name '${{ steps.app-token.outputs.app-slug }}[bot]' | |
| git config user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' | |
| git checkout -B changelog/$CURRENT_PATCH | |
| git add -f CHANGELOG.md | |
| git commit -m "chore(releases): generate CHANGELOG.md for $CURRENT_PATCH" | |
| git push -f --set-upstream origin changelog/$CURRENT_PATCH | |
| # Note: deploy only the latest release branch instead of all cascading release branches. | |
| deploy-to-beta: | |
| needs: | |
| - version | |
| - changes | |
| - darker | |
| - biome | |
| - openapi | |
| - pytest | |
| - npm-test | |
| if: ${{ !cancelled() && !failure() && needs.version.result == 'success' && needs.version.outputs.next_branch == 'main' }} | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: ./.github/actions/checkout-with-github-app-token | |
| with: | |
| app-id: ${{ secrets.KOBO_BOT_APP_ID }} | |
| private-key: ${{ secrets.KOBO_BOT_PRIVATE_KEY }} | |
| - name: deploy to beta | |
| run: | | |
| set -xe | |
| git checkout -B public-beta | |
| git push -f --set-upstream origin public-beta | |
| merge-forward: | |
| name: Merge forward | |
| needs: | |
| - version | |
| - changes | |
| - darker | |
| - biome | |
| - openapi | |
| - pytest | |
| - npm-test | |
| if: ${{ !cancelled() && !failure() && needs.version.result == 'success' }} | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: ./.github/actions/checkout-with-github-app-token | |
| with: | |
| app-id: ${{ secrets.KOBO_BOT_APP_ID }} | |
| private-key: ${{ secrets.KOBO_BOT_PRIVATE_KEY }} | |
| - name: Merge | |
| env: | |
| current_branch: ${{ needs.version.outputs.current_branch }} | |
| next_branch: ${{ needs.version.outputs.next_branch }} | |
| run: | | |
| git checkout "$next_branch" | |
| echo 'TODO: squash migrations, if any' | |
| git merge --no-ff "$current_branch" | |
| git push | |
| notify-success: | |
| needs: | |
| - version | |
| - darker | |
| - biome | |
| - openapi | |
| - pytest | |
| - npm-test | |
| - changelog | |
| - deploy-to-beta | |
| - merge-forward | |
| if: ${{ !cancelled() && needs.version.result == 'success' }} | |
| uses: './.github/workflows/zulip.yml' | |
| secrets: inherit | |
| with: | |
| topic: "${{ needs.version.outputs.current_minor }} release" | |
| content: | | |
| :working_on_it: `${{ needs.version.outputs.current_branch }}` branch workflow has been completed: | |
| - ${{ ( | |
| needs.darker.result == 'failure' || needs.darker.result == 'timed_out' || | |
| needs.openapi.result == 'failure' || needs.openapi.result == 'timed_out' || | |
| needs.pytest.result == 'failure' || needs.pytest.result == 'timed_out' ) | |
| && format(':warning: failed to pass backend automated tests: @*backend* please investigate [run #{0}]({1}/{2}/actions/runs/{3})!', github.run_number, github.server_url, github.repository, github.run_id) | |
| || (needs.darker.result == 'skipped' && needs.openapi.result == 'skipped' && needs.pytest.result == 'skipped') | |
| && ':skip_forward: all backend jobs skipped due no changes in backend relates files.' | |
| || format(':check: passed backend automated tests ({0} darker, {1} openapi, {2} pytest)', needs.darker.result, needs.openapi.result, needs.pytest.result) | |
| }} | |
| - ${{ ( | |
| needs.biome.result == 'failure' || needs.biome.result == 'timed_out' || | |
| needs.npm-test.result == 'failure' || needs.npm-test.result == 'timed_out' ) | |
| && format(':warning: failed to pass automated tests: @*frontend* please investigate [run #{0}]({1}/{2}/actions/runs/{3})!', github.run_number, github.server_url, github.repository, github.run_id) | |
| || (needs.biome.result == 'skipped' && needs.npm-test.result == 'skipped') | |
| && ':skip_forward: all frontend jobs skipped due no changes in frontend relates files.' | |
| || format(':check: passed frontend automated tests ({0} biome, {1} npm-test)', needs.biome.result, needs.npm-test.result) | |
| }} | |
| - ${{ (needs.merge-forward.result == 'failure' || needs.merge-forward.result == 'timed_out') | |
| && format(':warning: failed to merge forward: @*devs* please investigate [run #{0}]({1}/{2}/actions/runs/{3}), it likely requires a manual merge to `{4}`!', github.run_number, github.server_url, github.repository, github.run_id, needs.version.outputs.next_branch) | |
| || needs.merge-forward.result == 'skipped' | |
| && ':skip_forward: merged forward skipped due failed automated tests.' | |
| || format(':check: merged forward into `{0}`', needs.version.outputs.next_branch) | |
| }} | |
| - ${{ (needs.changelog.result == 'failure' || needs.changelog.result == 'timed_out') | |
| && format(':warning: failed to update changelog: @*devs* please investigate [run #{0}]({1}/{2}/actions/runs/{3})!', github.run_number, github.server_url, github.repository, github.run_id) | |
| || needs.changelog.result == 'skipped' | |
| && ':skip_forward: changelog update skipped due failed automated tests.' | |
| || format(':check: updated [changelog](https://github.com/kobotoolbox/kpi/blob/changelog/{0}/CHANGELOG.md)', needs.version.outputs.current_patch) | |
| }} | |
| - ${{ (needs.deploy-to-beta.result == 'failure' || needs.deploy-to-beta.result == 'timed_out') | |
| && format(':warning: failed to queue to deploy to beta: @*devs* please investigate [run #{0}]({1}/{2}/actions/runs/{3})!', github.run_number, github.server_url, github.repository, github.run_id) | |
| || needs.deploy-to-beta.result == 'skipped' | |
| && ':skip_forward: deploy to beta skipped due failed automated tests or due not being the latest release.' | |
| || ':check: triggered a deploy to [beta](kf.beta.kbtdev.org), see #**Kobo Dev>deployments to public-beta** for deployment status' | |
| }} | |
| notify-failure: | |
| needs: | |
| - version | |
| - changes | |
| if: ${{ !cancelled() && failure() }} | |
| secrets: inherit | |
| uses: './.github/workflows/zulip.yml' | |
| with: | |
| topic: "${{ needs.version.outputs.current_minor }} release" | |
| content: ":warning: `${{ needs.version.outputs.current_branch }}` branch workflow [run #${{github.run_number}}](${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}}) failed `${{ github.head_ref || github.ref_name }}`, @*devs* please investigate!" |