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
108 changes: 108 additions & 0 deletions .github/actions/dispatch-and-watch-workflow/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: Dispatch and watch workflow
description: Dispatches a workflow_dispatch in another repository and waits for it to complete.

inputs:
repo:
description: Target repository in `owner/name` form.
required: true
workflow:
description: Workflow filename (e.g. `release.yaml`) or ID.
required: true
ref:
description: Git ref to dispatch the workflow against.
required: false
default: main
version:
description: Version passed as the `version` input to the dispatched workflow.
required: true
is_stable:
description: Whether the release is a stable (X.Y.Z) version. Forwarded to the dispatched workflow.
required: true
is_active_major:
description: Whether the release targets the top lane (version.major >= highest stable major). Forwarded to the dispatched workflow.
required: true
token:
description: "Token with `actions: write` on the target repository."
required: true
locate-attempts:
description: How many times to poll for the dispatched run before giving up.
required: false
default: "30"
locate-interval:
description: Seconds to wait between locate polls.
required: false
default: "5"

outputs:
run-id:
description: Numeric ID of the dispatched run.
value: ${{ steps.locate.outputs.run-id }}
run-url:
description: HTML URL of the dispatched run.
value: ${{ steps.locate.outputs.run-url }}

Comment thread
tobias-tengler marked this conversation as resolved.
runs:
using: composite
steps:
- name: 🚀 Dispatch workflow
id: dispatch
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
REPO: ${{ inputs.repo }}
WORKFLOW: ${{ inputs.workflow }}
REF: ${{ inputs.ref }}
VERSION: ${{ inputs.version }}
IS_STABLE: ${{ inputs.is_stable }}
IS_ACTIVE_MAJOR: ${{ inputs.is_active_major }}
run: |
set -euo pipefail
CORR=$(uuidgen)
echo "correlation-id=$CORR" >> "$GITHUB_OUTPUT"

gh workflow run "$WORKFLOW" --repo "$REPO" --ref "$REF" \
-f version="$VERSION" \
-f is_stable="$IS_STABLE" \
-f is_active_major="$IS_ACTIVE_MAJOR" \
-f correlation_id="$CORR"

- name: 🔎 Locate dispatched run
id: locate
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
REPO: ${{ inputs.repo }}
WORKFLOW: ${{ inputs.workflow }}
CORR: ${{ steps.dispatch.outputs.correlation-id }}
Comment thread
tobias-tengler marked this conversation as resolved.
ATTEMPTS: ${{ inputs.locate-attempts }}
INTERVAL: ${{ inputs.locate-interval }}
run: |
set -euo pipefail
RUN_ID=""
RUN_URL=""
for _ in $(seq 1 "$ATTEMPTS"); do
read -r RUN_ID RUN_URL < <(gh run list --repo "$REPO" --workflow "$WORKFLOW" \
--limit 20 --json databaseId,name,url \
--jq "[.[] | select(.name | contains(\"$CORR\"))][0] | \"\(.databaseId) \(.url)\"")
Comment thread
tobias-tengler marked this conversation as resolved.
Comment thread
tobias-tengler marked this conversation as resolved.
if [ -n "$RUN_ID" ] && [ "$RUN_ID" != "null" ]; then
break
fi
sleep "$INTERVAL"
done

if [ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ]; then
echo "::error::Could not locate dispatched run for $REPO ($WORKFLOW) with correlation_id=$CORR"
exit 1
fi

echo "run-id=$RUN_ID" >> "$GITHUB_OUTPUT"
echo "run-url=$RUN_URL" >> "$GITHUB_OUTPUT"
echo "Dispatched run: $RUN_URL"

- name: 👀 Watch run
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
REPO: ${{ inputs.repo }}
RUN_ID: ${{ steps.locate.outputs.run-id }}
run: gh run watch "$RUN_ID" --repo "$REPO" --exit-status
Loading
Loading