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
104 changes: 104 additions & 0 deletions .github/workflows/ci-ready.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: CI Ready Signal

on:
repository_dispatch:
types: [ci-ready]

# client_payload schema:
# repo: "getsentry/sentry-native" (full owner/repo)
# version: "0.13.4"
# sha: "abc123..." (the release branch HEAD SHA)

permissions:
contents: read
issues: read

jobs:
signal:
runs-on: ubuntu-latest
name: Process CI-ready signal
steps:
- name: Find matching publish issue
id: find-issue
env:
REPO: ${{ github.event.client_payload.repo }}
VERSION: ${{ github.event.client_payload.version }}
run: |
title="publish: ${REPO}@${VERSION}"
echo "Looking for issue: ${title}"

# Find matching open issue by exact title match.
# Use --limit 200 to handle active repos with many open issues.
issue=$(gh issue list -R "$GITHUB_REPOSITORY" \
--state open \
--limit 200 \
--json number,title,labels \
| jq -r --arg t "$title" \
'[.[] | select(.title == $t)] | first // empty')

if [[ -z "$issue" ]]; then
# Retry a few times in case the issue hasn't been created yet
for i in 1 2 3; do
echo "Issue not found, retry ${i}/3 in 10s..."
sleep 10
issue=$(gh issue list -R "$GITHUB_REPOSITORY" \
--state open \
--limit 200 \
--json number,title,labels \
| jq -r --arg t "$title" \
'[.[] | select(.title == $t)] | first // empty')
if [[ -n "$issue" ]]; then break; fi
done
fi

if [[ -z "$issue" ]]; then
echo "::warning::No open issue found with title: ${title}"
exit 0
fi

number=$(echo "$issue" | jq -r '.number')
has_ci_pending=$(echo "$issue" | jq '[.labels[].name] | any(. == "ci-pending")')

if [[ "$has_ci_pending" != "true" ]]; then
echo "::warning::Issue #${number} does not have ci-pending label. Ignoring signal."
exit 0
fi

has_accepted=$(echo "$issue" | jq '[.labels[].name] | any(. == "accepted")')

echo "number=${number}" >> "$GITHUB_OUTPUT"
echo "has_accepted=${has_accepted}" >> "$GITHUB_OUTPUT"
echo "Found issue #${number} with ci-pending label (accepted=${has_accepted})"

# Use a GitHub App token so the label change triggers publish.yml.
# GITHUB_TOKEN events are deliberately suppressed by GitHub and
# would not create new workflow runs.
- name: Get auth token
if: steps.find-issue.outputs.number
id: token
uses: actions/create-github-app-token@v2.2.1
with:
app-id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
private-key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
Comment on lines +81 to +82
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

niche: probably better to use release-bot here to unify the app usage, release bot is also managed more tightly and less likely to break or affected by other changes


- name: Add ci-ready label
if: steps.find-issue.outputs.number
env:
# Override the default GITHUB_TOKEN with the app token so the
# label event triggers publish.yml (GITHUB_TOKEN events are
# suppressed by GitHub and would not start new workflow runs).
GH_TOKEN: ${{ steps.token.outputs.token }}
ISSUE_NUMBER: ${{ steps.find-issue.outputs.number }}
SHA: ${{ github.event.client_payload.sha }}
REPO: ${{ github.event.client_payload.repo }}
run: |
gh issue edit "$ISSUE_NUMBER" -R "$GITHUB_REPOSITORY" \
--remove-label "ci-pending" \
--add-label "ci-ready"

if [[ "${{ steps.find-issue.outputs.has_accepted }}" == "true" ]]; then
comment="CI checks passed for ${REPO} (\`${SHA:0:8}\`). Publishing is starting now."
else
comment="CI checks passed for ${REPO} (\`${SHA:0:8}\`). Publishing will start once the **accepted** label is also present."
fi
gh issue comment "$ISSUE_NUMBER" -R "$GITHUB_REPOSITORY" --body "$comment"
31 changes: 30 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,46 @@ on:
issues:
types: [labeled]

concurrency:
# Use the issue title (e.g. "publish: getsentry/foo@1.2.3") so duplicate
# issues for the same repo@version share a concurrency group.
group: ${{ github.event.issue.title }}
cancel-in-progress: false

permissions:
contents: read
issues: write
packages: write

jobs:
# Lightweight job: comment when approved but CI hasn't finished yet
waiting-for-ci:
runs-on: ubuntu-latest
name: Waiting for CI
if: >-
github.event.label.name == 'accepted'
&& github.event.issue.state == 'open'
&& contains(github.event.issue.labels.*.name, 'ci-pending')
steps:
- name: Comment on issue
run: |
gh issue comment "${{ github.event.issue.number }}" \
-R "$GITHUB_REPOSITORY" \
--body "Approved, but CI is still running on the release branch. Publishing will start automatically when CI passes."

publish:
runs-on: ubuntu-latest
environment: production
name: Publish a new version
if: github.event.label.name == 'accepted' && github.event.issue.state == 'open'
# Run when:
# - accepted (with no ci-pending blocking), OR
# - ci-ready added (and accepted is already present)
# In all cases accepted must be present and ci-pending must not be.
if: >-
github.event.issue.state == 'open'
&& contains(github.event.issue.labels.*.name, 'accepted')
&& !contains(github.event.issue.labels.*.name, 'ci-pending')
&& (github.event.label.name == 'accepted' || github.event.label.name == 'ci-ready')
timeout-minutes: 90
env:
SENTRY_DSN: "https://303a687befb64dc2b40ce4c96de507c5@o1.ingest.sentry.io/6183838"
Expand Down
Loading