From f18ac92bd525808dbc327c5da17c0c23022ee3bf Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Wed, 30 Jul 2025 23:16:38 +0100 Subject: [PATCH] Adds blocker to release if any issue has release-blocker label Signed-off-by: Simon Davies --- .github/workflows/CreateRelease.yml | 11 ++++ .github/workflows/ReleaseBlockerCheck.yml | 38 +++++++++++ .../workflows/ReleaseBlockerLabelCleanUp.yml | 31 +++++++++ dev/check-release-blockers.sh | 63 +++++++++++++++++++ docs/github-labels.md | 3 +- 5 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ReleaseBlockerCheck.yml create mode 100644 .github/workflows/ReleaseBlockerLabelCleanUp.yml create mode 100755 dev/check-release-blockers.sh diff --git a/.github/workflows/CreateRelease.yml b/.github/workflows/CreateRelease.yml index 02a3796fe..e3a4894d6 100644 --- a/.github/workflows/CreateRelease.yml +++ b/.github/workflows/CreateRelease.yml @@ -13,10 +13,19 @@ permissions: jobs: + release-blocker-check: + # see https://github.com/orgs/community/discussions/26286#discussioncomment-3251208 for why we need to check the ref + if: ${{ contains(github.ref, 'refs/heads/release/') }} || ${{ github.ref=='refs/heads/main' }} + uses: ./.github/workflows/ReleaseBlockerCheck.yml + with: + repository: ${{ github.repository }} + secrets: inherit + build-rust-ubuntu: # see https://github.com/orgs/community/discussions/26286#discussioncomment-3251208 for why we need to check the ref if: ${{ contains(github.ref, 'refs/heads/release/') }} || ${{ github.ref=='refs/heads/main' }} runs-on: [self-hosted, Linux, X64, "1ES.Pool=hld-kvm-amd"] + needs: [release-blocker-check] steps: - uses: actions/checkout@v4 @@ -37,6 +46,7 @@ jobs: # see https://github.com/orgs/community/discussions/26286#discussioncomment-3251208 for why we need to check the ref if: ${{ contains(github.ref, 'refs/heads/release/') }} || ${{ github.ref=='refs/heads/main' }} runs-on: windows-2022 + needs: [release-blocker-check] steps: - uses: actions/checkout@v4 @@ -56,6 +66,7 @@ jobs: build-guest-binaries: uses: ./.github/workflows/dep_build_guest_binaries.yml secrets: inherit + needs: [release-blocker-check] benchmarks: needs: [build-guest-binaries] diff --git a/.github/workflows/ReleaseBlockerCheck.yml b/.github/workflows/ReleaseBlockerCheck.yml new file mode 100644 index 000000000..90ea4ff1e --- /dev/null +++ b/.github/workflows/ReleaseBlockerCheck.yml @@ -0,0 +1,38 @@ +name: Release Blocker Check + +on: + workflow_call: + inputs: + repository: + description: "Repository to check in format 'owner/repo'" + required: false + type: string + default: ${{ github.repository }} + workflow_dispatch: + inputs: + repository: + description: "Repository to check in format 'owner/repo'" + required: false + type: string + +permissions: + issues: read + contents: read + +jobs: + check-blockers: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check for Release Blocking Issues + run: | + REPO="${{ inputs.repository || github.repository }}" + echo "Checking repository: $REPO" + + if ! ./dev/check-release-blockers.sh "$REPO"; then + echo "::error::Release blocked by open issues with 'release-blocker' label" + exit 1 + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ReleaseBlockerLabelCleanUp.yml b/.github/workflows/ReleaseBlockerLabelCleanUp.yml new file mode 100644 index 000000000..306593e0d --- /dev/null +++ b/.github/workflows/ReleaseBlockerLabelCleanUp.yml @@ -0,0 +1,31 @@ +name: Release Blocker Cleanup + +on: + issues: + types: [closed] + +permissions: + issues: write + contents: read + +jobs: + remove-release-blocker: + runs-on: ubuntu-latest + steps: + - name: Remove release-blocker label from closed issue + run: | + ISSUE_NUMBER=${{ github.event.issue.number }} + echo "Checking if issue #$ISSUE_NUMBER has release-blocker label..." + + # Check if the issue has the release-blocker label + HAS_LABEL=$(gh issue view "$ISSUE_NUMBER" --json labels -q '.labels[] | select(.name == "release-blocker") | .name') + + if [ -n "$HAS_LABEL" ]; then + echo "✅ Issue #$ISSUE_NUMBER has release-blocker label, removing it..." + gh issue edit "$ISSUE_NUMBER" --remove-label "release-blocker" + echo "✅ Successfully removed release-blocker label from issue #$ISSUE_NUMBER" + else + echo "ℹ️ Issue #$ISSUE_NUMBER does not have release-blocker label, no action needed" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/dev/check-release-blockers.sh b/dev/check-release-blockers.sh new file mode 100755 index 000000000..cf7475c65 --- /dev/null +++ b/dev/check-release-blockers.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -e +set -u +set -o pipefail + +## DESCRIPTION: +## +## This script checks for open issues with the 'release-blocker' label +## in a given GitHub repository. It exits with code 1 if any blocking +## issues are found, or 0 if none are found. +## +## PRE-REQS: +## +## This script assumes that the gh cli is installed and in the PATH +## and that there is a GitHub PAT in the GITHUB_TOKEN env var +## with the following permissions: +## - repo (read) +## - issues (read) +## or that the user is logged into the gh cli with an account with those permissions + + +# Check if repository argument is provided +if [ -z "${1:-}" ]; then + echo "Error: Repository name not provided." + echo "Usage: $0 " + echo "Example: $0 hyperlight-dev/hyperlight" + exit 1 +fi + +REPO="$1" +echo "Checking for open issues with 'release-blocker' label in $REPO..." + +# Extract owner and repo name from the argument +OWNER=$(echo "$REPO" | cut -d'/' -f1) +REPO_NAME=$(echo "$REPO" | cut -d'/' -f2) + +# Get all open issues with release-blocker label +BLOCKING_ISSUES=$(gh api graphql -f query=' + query($owner: String!, $repo: String!) { + repository(owner: $owner, name: $repo) { + issues(first: 100, states: OPEN, labels: ["release-blocker"]) { + totalCount + nodes { + number + title + url + } + } + } + }' -f owner="$OWNER" -f repo="$REPO_NAME" --jq '.data.repository.issues') + +BLOCKER_COUNT=$(echo "$BLOCKING_ISSUES" | jq '.totalCount') + +if [ "$BLOCKER_COUNT" -gt 0 ]; then + echo "❌ Found $BLOCKER_COUNT open release-blocking issue(s):" + echo "$BLOCKING_ISSUES" | jq -r '.nodes[] | " - #\(.number): \(.title) (\(.url))"' + echo "" + echo "Release blocked by open issue(s) with 'release-blocker' label" + exit 1 +else + echo "✅ No open release blocking issues found" + exit 0 +fi diff --git a/docs/github-labels.md b/docs/github-labels.md index 888b0280d..5133f048a 100644 --- a/docs/github-labels.md +++ b/docs/github-labels.md @@ -39,6 +39,7 @@ In addition to lifecycle labels, we use the following labels to further categori - **good-first-issue** - The issue is suitable for new contributors or those looking for a simple task to start with. - **help-wanted** - The issue is a request for help or assistance. - **question** - The issue is a question or request for information. +- **release-blocker** - Critical issues that must be resolved before the next release can be made. The presence of this label on any open issue will prevent releases being created by the release workflow --- @@ -56,4 +57,4 @@ In addition to **kind/*** labels, we use optional **area/*** labels to specify t ## Notes -This document is a work in progress and may be updated as needed. The labels and categories are subject to change based on the evolving needs of the project and community feedback. \ No newline at end of file +This document is a work in progress and may be updated as needed. The labels and categories are subject to change based on the evolving needs of the project and community feedback.