Repository navigation
Update channel #34
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: Update channel | |
| # The release host (docs/design/update-channel.md): the statement of what is | |
| # current, served by this repository's Pages site; the payload, among the | |
| # release's files; the statement key, in the KRYPTIK_LATEST_KEY secret. A | |
| # dispatch publishes a release into a channel, or with no release signs the | |
| # current statement again; the schedule signs it again daily, so a machine | |
| # that hears nothing for 30 days knows something is wrong. Before the first | |
| # release there is no key and no statement, and a scheduled run ends quietly. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release: | |
| description: "The release to publish, by tag (v1.0.0); empty signs the current statement again" | |
| default: "" | |
| channel: | |
| description: "The channel under the site" | |
| default: stable | |
| dry_run: | |
| description: "Prove the host with throwaway keys and a stand-in release under test/" | |
| type: boolean | |
| default: false | |
| schedule: | |
| - cron: '17 6 * * *' | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| # One run at a time: a reissue finishing after a publish would name the older release again. | |
| concurrency: | |
| group: update-channel | |
| cancel-in-progress: false | |
| jobs: | |
| channel: | |
| name: ${{ inputs.dry_run && 'Dry run' || (inputs.release && format('Publish {0}', inputs.release) || 'Reissue') }} | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 30 | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deploy.outputs.page_url }} | |
| steps: | |
| - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 | |
| - name: The statement key | |
| id: key | |
| if: ${{ !inputs.dry_run }} | |
| env: | |
| KEY: ${{ secrets.KRYPTIK_LATEST_KEY }} | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE: ${{ inputs.release }} | |
| CHANNEL: ${{ inputs.channel || 'stable' }} | |
| run: | | |
| if [ -n "$KEY" ]; then | |
| umask 077 | |
| printf '%s\n' "$KEY" > "$RUNNER_TEMP/kryptik-latest" | |
| exit 0 | |
| fi | |
| # Without the key a publish cannot sign, and a statement the site | |
| # already serves would go stale; a channel that serves none yet has | |
| # nothing to sign again. | |
| if [ -n "$RELEASE" ]; then | |
| echo "no KRYPTIK_LATEST_KEY secret: the statement key the ceremony made (docs/release-keys.md), without a passphrase" | |
| exit 1 | |
| fi | |
| site="$(gh api "repos/${GITHUB_REPOSITORY}/pages" --jq .html_url 2>/dev/null || true)" | |
| if [ -n "$site" ] && curl -fsSL -o /dev/null "${site%/}/${CHANNEL}/latest" 2>/dev/null; then | |
| echo "no KRYPTIK_LATEST_KEY secret, and ${site%/}/${CHANNEL}/latest is served: it will go stale. Put the statement key in the secret (docs/release-keys.md)" | |
| exit 1 | |
| fi | |
| echo "no KRYPTIK_LATEST_KEY secret and no statement served for ${CHANNEL}: nothing to sign again yet" | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| - name: The channel | |
| if: ${{ steps.key.outputs.skip != 'true' }} | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE: ${{ inputs.release }} | |
| CHANNEL: ${{ inputs.channel || 'stable' }} | |
| run: | | |
| if [ "${{ inputs.dry_run }}" = true ]; then | |
| tools/channel-host.sh dry-run --site site --channel test --repo "$GITHUB_REPOSITORY" | |
| elif [ -n "$RELEASE" ]; then | |
| tools/channel-host.sh publish --release "$RELEASE" --key "$RUNNER_TEMP/kryptik-latest" --site site --channel "$CHANNEL" --repo "$GITHUB_REPOSITORY" | |
| else | |
| tools/channel-host.sh reissue --key "$RUNNER_TEMP/kryptik-latest" --site site --channel "$CHANNEL" --repo "$GITHUB_REPOSITORY" | |
| fi | |
| rm -f "$RUNNER_TEMP/kryptik-latest" | |
| find site -type f | sort | |
| - if: ${{ steps.key.outputs.skip != 'true' }} | |
| uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 | |
| - if: ${{ steps.key.outputs.skip != 'true' }} | |
| uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 | |
| with: | |
| path: site | |
| - id: deploy | |
| if: ${{ steps.key.outputs.skip != 'true' }} | |
| uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 |