Repository navigation
connect-client-release-published #22
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 Connect release | |
| on: | |
| repository_dispatch: | |
| types: [connect-client-release-published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: Published mdbase Connect release tag | |
| required: true | |
| type: string | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: connect-release-update | |
| cancel-in-progress: false | |
| jobs: | |
| update: | |
| name: Verify release and open pull request | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Select release tag | |
| id: release | |
| env: | |
| DISPATCH_TAG: ${{ github.event.client_payload.tag }} | |
| MANUAL_TAG: ${{ inputs.tag }} | |
| run: | | |
| tag="${DISPATCH_TAG:-$MANUAL_TAG}" | |
| if [[ ! "$tag" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$ ]]; then | |
| echo "Invalid Connect release tag." >&2 | |
| exit 1 | |
| fi | |
| echo "tag=$tag" >> "$GITHUB_OUTPUT" | |
| echo "branch=automation/connect-release-$tag" >> "$GITHUB_OUTPUT" | |
| - name: Check out website | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: main | |
| persist-credentials: false | |
| - name: Read specification source identity | |
| id: specification | |
| run: | | |
| echo "repository=$(jq -r '.specification.repository' site-sources.json)" >> "$GITHUB_OUTPUT" | |
| echo "ref=$(jq -r '.specification.ref' site-sources.json)" >> "$GITHUB_OUTPUT" | |
| - name: Check out specification | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| repository: ${{ steps.specification.outputs.repository }} | |
| ref: ${{ steps.specification.outputs.ref }} | |
| path: .sources/mdbase-spec | |
| persist-credentials: false | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| with: | |
| version: 10 | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: 22 | |
| cache: pnpm | |
| - name: Install cosign | |
| uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 | |
| - name: Install website dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build specification artifact | |
| working-directory: .sources/mdbase-spec/site | |
| run: npm ci && npm run build | |
| - name: Verify public evidence and generate release record | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| MDBASE_RELEASE_NPM_ATTEMPTS: "15" | |
| MDBASE_RELEASE_NPM_DELAY_MS: "60000" | |
| run: node scripts/update-connect-release.mjs '${{ steps.release.outputs.tag }}' | |
| - name: Validate generated website | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| MDBASE_SPEC_DIR: .sources/mdbase-spec | |
| run: pnpm test | |
| - name: Require a release-only change | |
| id: changes | |
| run: | | |
| mapfile -t changed < <(git diff --name-only) | |
| if [ "${#changed[@]}" -eq 0 ]; then | |
| echo "present=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| printf '%s\n' "${changed[@]}" | sort > "$RUNNER_TEMP/changed" | |
| printf '%s\n' site-sources.json src/data/connect-release.json | sort > "$RUNNER_TEMP/expected" | |
| diff -u "$RUNNER_TEMP/expected" "$RUNNER_TEMP/changed" | |
| echo "present=true" >> "$GITHUB_OUTPUT" | |
| - name: Create website automation token | |
| if: steps.changes.outputs.present == 'true' | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| client-id: ${{ vars.RELEASE_AUTOMATION_CLIENT_ID }} | |
| private-key: ${{ secrets.RELEASE_AUTOMATION_APP_PRIVATE_KEY }} | |
| owner: mdbase-dev | |
| repositories: mdbase.dev | |
| permission-contents: write | |
| permission-pull-requests: write | |
| - name: Open release update pull request | |
| if: steps.changes.outputs.present == 'true' | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| BRANCH: ${{ steps.release.outputs.branch }} | |
| TAG: ${{ steps.release.outputs.tag }} | |
| run: | | |
| existing="$(gh pr list --repo "$GITHUB_REPOSITORY" --state all --head "$BRANCH" --json url,state --jq '.[0] // empty')" | |
| if [ -n "$existing" ]; then | |
| state="$(jq -r .state <<<"$existing")" | |
| url="$(jq -r .url <<<"$existing")" | |
| if [ "$state" = "OPEN" ] || [ "$state" = "MERGED" ]; then | |
| echo "Release update already represented by $url" | |
| exit 0 | |
| fi | |
| echo "The deterministic release PR was closed without merging: $url" >&2 | |
| exit 1 | |
| fi | |
| if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then | |
| echo "Remote branch $BRANCH exists without a pull request; refusing to overwrite it." >&2 | |
| exit 1 | |
| fi | |
| git switch -c "$BRANCH" | |
| git config user.name "mdbase release automation[bot]" | |
| git config user.email "mdbase-release-automation[bot]@users.noreply.github.com" | |
| git add site-sources.json src/data/connect-release.json | |
| git commit -m "Update Connect downloads to $TAG" | |
| git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" | |
| git push --set-upstream origin "$BRANCH" | |
| url="$(gh pr create \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --base main \ | |
| --head "$BRANCH" \ | |
| --title "Update Connect downloads to $TAG" \ | |
| --body "Updates the Downloads release record from the published, Sigstore-verified mdbase Connect channel for [$TAG](https://github.com/mdbase-dev/mdbase-connect/releases/tag/$TAG).\n\nThe website release checks and full test suite passed before this PR was opened.")" | |
| echo "Opened $url" | |
| # An open update for an older release can only be merged over this | |
| # one, so close it. Newer releases' updates are never touched. | |
| prefix=automation/connect-release- | |
| gh pr list --repo "$GITHUB_REPOSITORY" --state open --json number,headRefName \ | |
| --jq ".[] | select(.headRefName | startswith(\"$prefix\")) | \"\\(.number) \\(.headRefName)\"" | | |
| while read -r number head; do | |
| older="${head#"$prefix"}" | |
| [ "$older" != "$TAG" ] || continue | |
| [ "$(printf '%s\n%s\n' "${older#v}" "${TAG#v}" | sort -V | head -1)" = "${older#v}" ] || continue | |
| gh pr close "$number" --repo "$GITHUB_REPOSITORY" --delete-branch --comment "Superseded by $url." | |
| done |