Files
pristontale-eu-linux/.gitea/workflows/release.yml

165 lines
5.9 KiB
YAML

name: Publish launcher release
# Manual-release mode is active. Restore the v* tag-push trigger when automatic
# Gitea publication is wanted again.
on:
workflow_dispatch:
concurrency:
group: launcher-release-publication
cancel-in-progress: false
jobs:
release:
name: Build, verify, and publish tagged release
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
steps:
- name: Check out the exact tag
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.ref }}
- name: Validate and derive release metadata
id: release
shell: bash
run: |
set -euo pipefail
TAG="${GITHUB_REF_NAME:?GITHUB_REF_NAME is required}"
if [[ "$(git cat-file -t "$TAG")" != "tag" ]]
then
printf 'Release tag must be annotated: %s\n' "$TAG" >&2
exit 1
fi
python3 -m ptlinux.update_resolver inspect-tag "$TAG" > release-metadata.json
VERSION="$(jq -er '.version' release-metadata.json)"
CHANNEL="$(jq -er '.channel' release-metadata.json)"
PRERELEASE="$(jq -er '.prerelease' release-metadata.json)"
COMMIT="$(git rev-parse "${TAG}^{commit}")"
if [[ "$COMMIT" != "$(git rev-parse HEAD)" ]]
then
printf 'Checkout does not match tagged commit %s.\n' "$COMMIT" >&2
exit 1
fi
mapfile -t OTHER_RELEASE_TAGS < <(
git tag --list | while IFS= read -r candidate
do
[[ "$candidate" == "$TAG" ]] || printf '%s\n' "$candidate"
done
)
python3 -m ptlinux.update_resolver validate-next \
"$CHANNEL" "$VERSION" "${OTHER_RELEASE_TAGS[@]}"
{
printf 'tag=%s\n' "$TAG"
printf 'version=%s\n' "$VERSION"
printf 'channel=%s\n' "$CHANNEL"
printf 'prerelease=%s\n' "$PRERELEASE"
printf 'commit=%s\n' "$COMMIT"
} >> "$GITHUB_OUTPUT"
- name: Recover the previewed release notes
shell: bash
run: |
set -euo pipefail
NOTES_FILE="${RUNNER_TEMP}/release-notes.md"
git for-each-ref --format='%(contents)' \
"refs/tags/${{ steps.release.outputs.tag }}" > "$NOTES_FILE"
if [[ ! -s "$NOTES_FILE" ]]
then
printf '%s\n' 'Annotated release tag has no release notes.' >&2
exit 1
fi
printf 'RELEASE_NOTES_FILE=%s\n' "$NOTES_FILE" >> "$GITHUB_ENV"
- name: Run release preflight checks
shell: bash
run: |
set -euo pipefail
for command in git bash curl jq python3 tar gzip sha256sum rsync openssl base64 realpath stat
do
command -v "$command" >/dev/null || {
printf 'Required release command is unavailable: %s\n' "$command" >&2
exit 1
}
done
python3 -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)'
python3 -m compileall -q ptlinux ptdiag scripts
python3 -m unittest discover -s release_tests -p 'test_*.py'
python3 -m unittest discover -s tests -p 'test_*.py'
bash -n scripts/release.sh scripts/build-release.sh \
scripts/verify-release.sh scripts/publish-gitea-release.sh \
scripts/publish-release-history.sh
- name: Materialize the protected manifest signing key
shell: bash
env:
MANIFEST_SIGNING_KEY: ${{ secrets.MANIFEST_SIGNING_KEY }}
run: |
set -euo pipefail
if [[ -z "${MANIFEST_SIGNING_KEY:-}" ]]
then
printf '%s\n' 'MANIFEST_SIGNING_KEY is required for release publication.' >&2
exit 1
fi
umask 077
SIGNING_KEY_FILE="${RUNNER_TEMP}/launcher-manifest-signing-key.pem"
printf '%s\n' "$MANIFEST_SIGNING_KEY" > "$SIGNING_KEY_FILE"
chmod 0600 "$SIGNING_KEY_FILE"
printf 'PTLINUX_SIGNING_KEY=%s\n' "$SIGNING_KEY_FILE" >> "$GITHUB_ENV"
- name: Build deterministic release artifacts
shell: bash
env:
RELEASE_COMMIT: ${{ steps.release.outputs.commit }}
RELEASE_TAG: ${{ steps.release.outputs.tag }}
REPOSITORY_URL: ${{ github.server_url }}/${{ github.repository }}
REQUIRE_RELEASE_SIGNATURE: "1"
run: |
set -euo pipefail
export SOURCE_DATE_EPOCH
SOURCE_DATE_EPOCH="$(git show -s --format=%ct '${{ steps.release.outputs.commit }}')"
./scripts/build-release.sh \
'${{ steps.release.outputs.version }}' \
'${{ steps.release.outputs.channel }}' \
./dist
- name: Verify complete release artifacts
shell: bash
env:
REQUIRE_RELEASE_SIGNATURE: "1"
run: |
set -euo pipefail
./scripts/verify-release.sh \
'${{ steps.release.outputs.version }}' \
'${{ steps.release.outputs.channel }}' \
./dist
- name: Create Gitea release, upload assets, and update channel metadata
shell: bash
env:
RELEASE_BRANCH: main
RELEASE_COMMIT: ${{ steps.release.outputs.commit }}
RELEASE_PRERELEASE: ${{ steps.release.outputs.prerelease }}
RELEASE_TAG: ${{ steps.release.outputs.tag }}
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
set -euo pipefail
./scripts/publish-gitea-release.sh \
'${{ steps.release.outputs.version }}' \
'${{ steps.release.outputs.channel }}' \
./dist \
"$RELEASE_NOTES_FILE"
- name: Remove signing key
if: always()
shell: bash
run: |
if [[ -n "${PTLINUX_SIGNING_KEY:-}" ]]
then
rm -f -- "$PTLINUX_SIGNING_KEY"
fi