Skip to content
Closed
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
18 changes: 18 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ on:
type: string
required: false
default: 'false'
ci_ready:
description: >
Use event-driven CI signaling instead of polling.
When true (the default), the publish issue is created with a
"ci-pending" label. The target repo should call the signal-ready
action after CI passes. Set to 'false' to fall back to legacy polling.
type: string
required: false
default: 'true'
outputs:
version:
description: The resolved version being released
Expand All @@ -72,6 +81,12 @@ on:
changelog:
description: The changelog for this release (may be truncated for large repos)
value: ${{ jobs.release.outputs.changelog }}
issue_url:
description: The URL of the created publish request issue
value: ${{ jobs.release.outputs.issue_url }}
publish_issue_number:
description: The number of the created/updated publish issue
value: ${{ jobs.release.outputs.publish_issue_number }}

jobs:
# Build job only for Craft's own releases (dogfooding)
Expand All @@ -96,6 +111,8 @@ jobs:
sha: ${{ steps.craft-local.outputs.sha || steps.craft-action.outputs.sha }}
previous_tag: ${{ steps.craft-local.outputs.previous_tag || steps.craft-action.outputs.previous_tag }}
changelog: ${{ steps.craft-local.outputs.changelog || steps.craft-action.outputs.changelog }}
issue_url: ${{ steps.craft-local.outputs.issue_url || steps.craft-action.outputs.issue_url }}
publish_issue_number: ${{ steps.craft-local.outputs.publish_issue_number || steps.craft-action.outputs.publish_issue_number }}
steps:
# For Craft repo: use the release bot token
- name: Get auth token
Expand Down Expand Up @@ -140,3 +157,4 @@ jobs:
git_user_email: ${{ inputs.git_user_email }}
path: ${{ inputs.path }}
craft_config_from_merge_target: ${{ inputs.craft_config_from_merge_target }}
ci_ready: ${{ inputs.ci_ready }}
46 changes: 44 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ inputs:
Defaults to the action ref (e.g., "v2") if not specified.
required: false
default: ''
ci_ready:
description: >
Use event-driven CI signaling instead of polling.
When true (the default), the publish issue is created with a
"ci-pending" label, and the target repo is expected to send a
repository_dispatch event (via the signal-ready action) when CI
passes. The publish workflow will not start the job until CI
signals readiness, avoiding wasted runner minutes from idle
polling. Set to 'false' to fall back to the legacy polling behavior.
required: false
default: 'true'
Comment on lines +53 to +54
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The ci_ready input defaults to 'true' instead of the intended 'false', causing release workflows to stall for any repository that has not explicitly opted into the new CI signaling mechanism.
Severity: CRITICAL

Suggested Fix

Change the default value for the ci_ready input to 'false' in action.yml and the reusable workflow in .github/workflows/release.yml to align with the intended opt-in behavior. This ensures existing workflows are not affected unless they explicitly set ci_ready: 'true'.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: action.yml#L53-L54

Potential issue: The `ci_ready` input in `action.yml` defaults to `'true'`, but the
feature is designed to be opt-in with a default of `'false'`. This causes the action to
add a `ci-pending` label to publish issues for all repositories by default. Repositories
that have not adopted the corresponding `signal-ready` action will have their release
process blocked indefinitely, as they will be waiting for a signal that is never sent.
This affects both external repositories using the action and the project's own
dogfooding release workflow, which does not pass the `ci_ready` input and thus uses the
incorrect default.

Did we get this right? 👍 / 👎 to inform future reviews.


outputs:
version:
Expand All @@ -64,6 +75,9 @@ outputs:
issue_url:
description: The URL of the created publish request issue
value: ${{ steps.request-publish.outputs.issue_url }}
publish_issue_number:
description: The number of the created/updated publish issue (for use with signal-ready)
value: ${{ steps.request-publish.outputs.issue_number }}

runs:
using: 'composite'
Expand Down Expand Up @@ -202,6 +216,7 @@ runs:
SUBDIRECTORY: ${{ inputs.path != '.' && format('/{0}', inputs.path) || '' }}
MERGE_TARGET: ${{ inputs.merge_target || '(default)' }}
PUBLISH_REPO: ${{ inputs.publish_repo || format('{0}/publish', github.repository_owner) }}
CI_READY: ${{ inputs.ci_ready }}
run: |
# Resolve "self" to the current repository
if [[ "$PUBLISH_REPO" == "self" ]]; then
Expand Down Expand Up @@ -307,6 +322,12 @@ runs:
Checked targets will be skipped (either already published or user-requested skip). Uncheck to retry a target.
${CHANGELOG_SECTION}"

# Build label args for ci-ready opt-in
LABEL_ARGS=""
if [[ "$CI_READY" == "true" ]]; then
LABEL_ARGS="--label ci-pending"
fi

if [[ -n "$existing_issue_number" ]]; then
# Try to update existing issue with fresh body (preserving checked target states)
# This may fail if the token doesn't have permission to update issues in the publish repo
Expand All @@ -315,10 +336,31 @@ runs:
else
echo "::warning::Could not update existing issue (permission denied). Using existing issue as-is."
fi

# For ci-ready opt-in: ensure ci-pending label is present (unless ci-ready already set)
if [[ "$CI_READY" == "true" ]]; then
existing_labels=$(gh issue view "$existing_issue_number" -R "$PUBLISH_REPO" --json labels -q '.labels[].name' 2>/dev/null || true)
if ! echo "$existing_labels" | grep -q '^ci-ready$'; then
gh issue edit "$existing_issue_number" -R "$PUBLISH_REPO" --add-label "ci-pending" 2>/dev/null || true
fi
fi

echo "issue_url=${existing_issue_url}" >> "$GITHUB_OUTPUT"
echo "issue_number=${existing_issue_number}" >> "$GITHUB_OUTPUT"
else
# Create new issue
issue_url=$(gh issue create -R "$PUBLISH_REPO" --title "$title" --body "$body")
# Create new issue (with ci-pending label if ci_ready is enabled)
issue_url=$(gh issue create -R "$PUBLISH_REPO" --title "$title" --body "$body" $LABEL_ARGS)
echo "::notice::Created publish request: ${issue_url}"
echo "issue_url=${issue_url}" >> "$GITHUB_OUTPUT"

# Extract issue number from the URL (last path segment)
issue_number=$(echo "$issue_url" | grep -oE '[0-9]+$')
echo "issue_number=${issue_number}" >> "$GITHUB_OUTPUT"
fi

# Trigger the CI status poller so it checks immediately rather than
# waiting for the next scheduled run.
if [[ "$CI_READY" == "true" ]]; then
gh api -X POST "repos/${PUBLISH_REPO}/dispatches" \
-f event_type=check-ci-status 2>/dev/null || true
fi
Loading