Skip to content

CD: stabilize

CD: stabilize #630

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!"