Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions .github/workflows/bump-version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,26 +169,46 @@ jobs:
echo "Failed to push bumped versions; tried $TRY times."
exit 1
working-directory: self
# Stamp metadata into the GitHub release body so downstream workflows (docker.yaml, deploy.yaml)
# can recover context that would otherwise be lost. Once this workflow creates the release using
# WORKFLOW_PAT, every subsequent event (release:created, release:released) is triggered
# by leeroy-travis (the PAT owner), washing out information like who actually clicked the button
# and which PR produced this commit. We encode it here so it survives the handoff.
#
# Output is a compact JSON object, e.g.:
# {"triggered_by":"leeroy-travis","latest_pr":1234}
- name: Generate release text
id: release-body
run: |
set -x
# Get the most recent commit. Hopefully it was a PR merge.

# --- triggered_by: who actually kicked off this run ---
# Always recorded. deploy.yaml reads this to decide whether to apply the auto-promote label:
# scheduled rebuilds dispatch bump-version via rebuild.yaml's PAT (leeroy-travis), while
# humans clicking workflow_dispatch in the UI show up as themselves.
METADATA=$(jq -cn --arg triggered_by "${{ github.triggering_actor }}" \
'{triggered_by: $triggered_by}')

# --- latest_pr: the PR that produced the commit we're about to release ---
# Best-effort. deploy.yaml uses it to comment back on the original PR and assign reviewers.
# May be absent when:
# - Triggered by workflow_dispatch (the `push` event payload's `.after` field doesn't exist).
# - The commit landed on main without a PR (direct push, admin override of branch protection).
COMMIT=$(jq -r '.after' ${{ github.event_path }})
if [ "${COMMIT}" = "null" ] || [ -z "${COMMIT}" ] ; then
exit 0
fi
# Get the most recent PRs; hopefully ours is one of them.
curl -fSs -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.WORKFLOW_PAT }}" \
https://api.github.com/repos/${{ github.repository }}/pulls?state=all\&base=${{ github.ref }}\&sort=updated\&direction=desc > /tmp/prs.json
# Find a PR that resulted in our commit.
PR=$(jq -r ".[] | select(.merge_commit_sha == \"${COMMIT}\") | .number" /tmp/prs.json)
if [ "${PR}" = "null" ] || [ -z "${PR}" ] ; then
exit 0
if [ "${COMMIT}" != "null" ] && [ -n "${COMMIT}" ] ; then
# GitHub's PRs API has no "find by merge commit" endpoint, so we list the most recently
# updated PRs against this branch and look for one whose merge_commit_sha matches ours.
# If the merge happened long enough ago that it's fallen off the first page, we miss it.
curl -fSs -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.WORKFLOW_PAT }}" \
https://api.github.com/repos/${{ github.repository }}/pulls?state=all\&base=${{ github.ref }}\&sort=updated\&direction=desc > /tmp/prs.json
PR=$(jq -r ".[] | select(.merge_commit_sha == \"${COMMIT}\") | .number" /tmp/prs.json)
if [ "${PR}" != "null" ] && [ -n "${PR}" ] ; then
METADATA=$(echo "$METADATA" | jq -c --argjson pr "$PR" '. + {latest_pr: $pr}')
fi
fi
# Build the string we'll use as the description of the release.
echo "body=latest_pr:${PR}" >> "$GITHUB_OUTPUT"

echo "body=${METADATA}" >> "$GITHUB_OUTPUT"
working-directory: self
# This triggers the Docker workflow's `release: created`
- name: Create GitHub Release
Expand Down
32 changes: 22 additions & 10 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,25 @@ jobs:
with:
ref: ${{ inputs.tag }}
path: software
# Find the original PR to the software repo. The git tag should correspond to a GitHub release, which should have a
# description pointing to the PR number.
- name: Get original PR
# Pull metadata out of the GitHub release body. bump-version stamps a JSON object containing
# `triggered_by` and (when discoverable) `latest_pr` so downstream workflows can recover context
# that the WORKFLOW_PAT-driven release event would otherwise lose.
- name: Get release metadata
id: software-pr
working-directory: software
run: |
set -x
gh release view ${{ inputs.tag }} --json body --jq '.body' | sed 's/.*latest_pr:\([0-9]*\).*/\1/' > /tmp/pr
PR=$(cat /tmp/pr)
if [ -z "${PR}" ] || [ "${PR}" = "null" ] ; then
BODY=$(gh release view ${{ inputs.tag }} --json body --jq '.body')
# Releases predating the JSON format have plain-text bodies; treat them as having no metadata.
if ! echo "$BODY" | jq -e . >/dev/null 2>&1 ; then
exit 0
fi
TRIGGERED_BY=$(echo "$BODY" | jq -r '.triggered_by // empty')
if [ -n "$TRIGGERED_BY" ] ; then
echo "triggered_by=$TRIGGERED_BY" >> "$GITHUB_OUTPUT"
fi
PR=$(echo "$BODY" | jq -r '.latest_pr // empty')
if [ -z "${PR}" ] ; then
exit 0
fi
echo "pr=$PR" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -136,10 +145,13 @@ jobs:
git commit -m "${COMMIT_MSG}"
git push -u origin "${NEW_BRANCH}"

# If we can't find the originating PR, it must mean the change came from automation, and we should auto-promote.
if [ -z "${{ steps.software-pr.outputs.pr }}" ] ; then
LABELS="--label auto-promote"
fi
# Auto-promote only when bump-version was triggered by a known automation actor (e.g.,
# leeroy-travis from rebuild.yaml). Manual workflow_dispatch by a human is intentionally excluded.
case "${{ steps.software-pr.outputs.triggered_by }}" in
leeroy-travis)
LABELS="--label auto-promote"
;;
esac
AUTHOR="${{ steps.software-pr.outputs.author }}"
if [ -n "$AUTHOR" ] && [ "$AUTHOR" != "app/dependabot" ]; then
ASSIGNEE="--assignee $AUTHOR --reviewer $AUTHOR"
Expand Down
Loading