Migrate release pipeline from azure to github actions (#10643)

Related to https://github.com/certbot/certbot/issues/10581

Following up on https://github.com/certbot/certbot/pull/10631,
https://github.com/certbot/certbot/pull/10622, and
https://github.com/certbot/certbot/pull/10634, this PR converts the
release
[pipeline](https://dev.azure.com/certbot/certbot/_build?definitionId=3)
from Azure to Github Actions.

While this is the last migration PR, I don't think we should close the
issue, as we're still using launchpad for armhf builds. I plan to
continue investigating that and at minimum write up my findings.

To test
[notifications](https://opensource.eff.org/eff-open-source/pl/nfgh6obi8tfqikn4ydp7dshakr)
and creating a [github
release](https://github.com/ohemorange/Things-that-are-gr9/releases/tag/v1.0.19),
I ran workflows that no-oped most the other jobs [in a test
repo](https://github.com/ohemorange/Things-that-are-gr9/actions/runs/25938082721)
(I've made minor changes to names and comments since then, but no code
changes). Everything else is basically the same as nightly, with
different tags. For the docker deployment, `${{ github.ref_name }}` is
the tag name, so `v1.2.3`.

Why not parametrize the tests a bit more, by putting an `env` at the top
with `dockerTag: ${{ github.ref_name }}` and `snapReleaseChannel: beta`?
Because the `env` context is [not
available](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#context-availability)
to `with`; only `github, needs, strategy, matrix, inputs, vars`. We
could use `vars`, by creating `docker_tag_release` or whatever in the
[variable
section](https://github.com/certbot/certbot/settings/variables/actions)
of the repo settings by using the web interface, but that seems worse to
me than having it in the file but twice.

You will note that the contents of `release.yml` are very similar to
`nightly.yml`. While it would be nice to factor that out and reuse the
code, github actions would then flatten everything in the grouped code
together, making the results much harder to check. You can see what that
flattening would look like
[here](https://github.com/ohemorange/Things-that-are-gr9/actions/runs/25941524972)
(if we put them all in one workflow). Currently, it will look something
like
[this](https://github.com/certbot/certbot/actions/runs/25688414262),
which is much more readable.

We could split it into "stages" like we had in azure pipelines (probably
1. standard and extended tests (and changelog?), 2. snap package and
deploy (depend on tests), 3. docker package and deploy (depend on
tests), 4. github release (depend on snap package and deploy), 5-6.
notify (depend on github release)), but in addition to a minor slowdown
(currently github release only depends on snap and docker package, not
deploy, just so we're trying to do all the deployments simultaneously
and not partially in case of build failures), it would still be only
like three fewer jobs, since we'd still want all the info passing and
dependency relationships.

While it would be nice from a UX perspective to group the two
notification jobs together, you can't do that cleanly using the built-in
`if` key, and I don't think it's worth switching to a messier github
api-based version just to group them.

For mattermost notifications, we currently get the person to tag by
running `AUTHOR_NAME="$(git log -1 --pretty=format:'%an')"` and mapping
that to mattermost username. We could instead use `github.actor` to get
the github handle, and map that instead. I didn't bother since we
already have working, tested code, but can if a reviewer thinks it's
worth it.

---------

Co-authored-by: Will Greenberg <willg@eff.org>
Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
This commit is contained in:
ohemorange
2026-06-10 11:43:49 -07:00
committed by GitHub
co-authored by Will Greenberg Brad Warren
parent e9273a1269
commit cb02885928
18 changed files with 239 additions and 808 deletions
+2 -2
View File
@@ -9,7 +9,7 @@ jobs:
name: Changelog
runs-on: ubuntu-latest
steps:
# If we change the output filename from `release_notes.md`, it should also be changed in tools/create_github_release.py
# If we change the output filename from `release_notes.md`, it should also be changed in .github/workflows/release.yml
- name: checkout
uses: actions/checkout@v6.0.2
with:
@@ -22,6 +22,6 @@ jobs:
- name: Publish changelog
uses: actions/upload-artifact@v7.0.0
with:
# If we change the artifact's name, it should also be changed in tools/create_github_release.py
# If we change the artifact's name, it should also be changed in .github/workflows/release.yml
name: changelog
path: "${{ runner.temp }}/release_notes.md"
+2 -1
View File
@@ -7,7 +7,8 @@ on:
jobs:
# While many of these jobs could be grouped in a separate workflow, the github actions UI
# is much nicer if they are instead listed explicitly here.
# is much nicer if they are instead listed explicitly here. As a result, changes made here
# may need to be mirrored in .github/workflows/release.yml.
###########################
#### testing jobs ###
###########################
+40
View File
@@ -0,0 +1,40 @@
name: Notify release workflow finished
on:
workflow_call:
inputs:
success:
type: string
secrets:
MATTERMOST_PUBLIC_CERTBOT_CHANNEL_WEBHOOK:
required: true
permissions:
actions: read
contents: read
jobs:
notify_mattermost:
name: Notify mattermost
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6.0.2
with:
persist-credentials: false
- name: Generate message text
shell: bash
id: message
env:
SUCCESS: "${{ inputs.success }}"
run: |-
AUTHOR_NAME="$(git log -1 --pretty=format:'%an')"
MESSAGE=$(tools/release_message.py "${AUTHOR_NAME}" "${SUCCESS}")
echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$MESSAGE" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Send to mattermost
uses: mattermost/action-mattermost-notify@ae31bb6f9e26a54336e79696f108a2c91cf55b4e
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_PUBLIC_CERTBOT_CHANNEL_WEBHOOK }}
TEXT: "${{ steps.message.outputs.result }}"
+129
View File
@@ -0,0 +1,129 @@
# Release pipeline to run our full test suite, build artifacts, and deploy them
# for GitHub release tags.
name: Release
run-name: Release Certbot ${{ github.ref_name }}
on:
push:
tags:
- v*
permissions:
contents: read
jobs:
# While many of these jobs could be grouped in a separate workflow, the github actions UI
# is much nicer if they are instead listed explicitly here. As a result, changes made here
# may need to be mirrored in .github/workflows/nightly.yml.
###########################
#### testing jobs ###
###########################
standard_tests_jobs:
name: Standard tests
uses: "./.github/workflows/standard_tests_jobs.yml"
extended_tests_jobs:
name: Extended tests
uses: "./.github/workflows/extended_tests_jobs.yml"
secrets:
AWS_TEST_FARM_PEM: "${{ secrets.AWS_TEST_FARM_PEM }}"
AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
###########################
#### packaging jobs ###
###########################
docker_packaging_jobs:
name: Docker packaging
uses: "./.github/workflows/docker_packaging_jobs.yml"
with:
dockerTag: "${{ github.ref_name }}"
snap_packaging_jobs:
name: Snap packaging
uses: "./.github/workflows/snap_packaging_jobs.yml"
with:
snapBuildTimeout: 19800
secrets:
LAUNCHPAD_CREDENTIALS: "${{ secrets.LAUNCHPAD_CREDENTIALS }}"
create_changelog:
name: Create changelog
uses: "./.github/workflows/create_changelog.yml"
############################
#### deploy jobs ###
############################
docker_deploy_jobs:
name: Deploy docker images
needs:
- standard_tests_jobs
- extended_tests_jobs
- docker_packaging_jobs
uses: "./.github/workflows/deploy_docker_images.yml"
secrets:
DOCKERHUB_TOKEN: "${{ secrets.DOCKERHUB_TOKEN }}"
with:
dockerTag: "${{ github.ref_name }}"
snap_deploy_jobs:
name: Deploy snaps
needs:
- standard_tests_jobs
- extended_tests_jobs
- snap_packaging_jobs
uses: "./.github/workflows/deploy_snaps.yml"
secrets:
SNAPCRAFTCFG: "${{ secrets.SNAPCRAFTCFG }}"
with:
snapReleaseChannel: beta
create_github_release:
name: Create GitHub release
needs:
- standard_tests_jobs
- extended_tests_jobs
- docker_packaging_jobs
- snap_packaging_jobs
- create_changelog
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v6.0.2
with:
persist-credentials: false
- name: Download changelog
uses: actions/download-artifact@v8.0.1
with:
name: changelog
path: "${{ github.workspace }}"
- name: GitHub release
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
run: |-
gh release create "$TAG" "${GITHUB_WORKSPACE}/packages/"{*.tar.gz,SHA256SUMS*} \
--title "Certbot ${TAG#v}" \
--notes-file "$GITHUB_WORKSPACE/release_notes.md"
###########################
#### notify ###
###########################
notify_success:
name: Notify success
with:
success: 'True'
needs: &notify_needs
- docker_deploy_jobs
- snap_deploy_jobs
- create_github_release
uses: &notify_uses "./.github/workflows/notify_release.yml"
permissions: &notify_permissions
actions: read
contents: read
secrets: &notify_secrets
MATTERMOST_PUBLIC_CERTBOT_CHANNEL_WEBHOOK: "${{ secrets.MATTERMOST_PUBLIC_CERTBOT_CHANNEL_WEBHOOK }}"
notify_failure:
name: Notify failure
with:
success: 'False'
if: ${{ failure() }}
needs: *notify_needs
uses: *notify_uses
permissions: *notify_permissions
secrets: *notify_secrets