From 928a326cee78313df3fc7085e2e113edc06bc98c Mon Sep 17 00:00:00 2001 From: William Martin Date: Mon, 16 Jun 2025 17:09:04 +0200 Subject: [PATCH] Add workflow to check `help wanted` labelling (#11105) Co-authored-by: Kynan Ware <47394200+BagToad@users.noreply.github.com> Co-authored-by: Babak K. Shandiz Co-authored-by: Andy Feller --- .github/workflows/codeql.yml | 9 +- .github/workflows/pr-help-wanted.yml | 29 ++++++ .../workflows/scripts/check-help-wanted.sh | 93 +++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pr-help-wanted.yml create mode 100755 .github/workflows/scripts/check-help-wanted.sh diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8cd5ecbee..d74e1c142 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -18,6 +18,10 @@ permissions: jobs: CodeQL-Build: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: ['go', 'actions'] steps: - name: Check out code @@ -26,13 +30,16 @@ jobs: - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: - languages: go + languages: ${{ matrix.language }} queries: security-and-quality - name: Setup Go + if: matrix.language == 'go' uses: actions/setup-go@v5 with: go-version-file: 'go.mod' - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/pr-help-wanted.yml b/.github/workflows/pr-help-wanted.yml new file mode 100644 index 000000000..5475d2eff --- /dev/null +++ b/.github/workflows/pr-help-wanted.yml @@ -0,0 +1,29 @@ +name: PR Help Wanted Check +on: + pull_request_target: + types: [opened] + +permissions: + contents: none + issues: read + pull-requests: write + +jobs: + check-help-wanted: + runs-on: ubuntu-latest + steps: + - name: Check for issues without help-wanted label + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + PR_AUTHOR_TYPE: ${{ github.event.pull_request.user.type }} + if: !github.event.pull_request.draft + run: | + # Skip if PR is from a bot or org member + if [ "$PR_AUTHOR_TYPE" = "Bot" ] || "gh api orgs/cli/public_members/${PR_AUTHOR}" --silent 2>/dev/null + then + exit 0 + fi + + # Run the script to check for issues without help-wanted label + bash .github/scripts/check-help-wanted.sh ${{ github.event.pull_request.html_url }} diff --git a/.github/workflows/scripts/check-help-wanted.sh b/.github/workflows/scripts/check-help-wanted.sh new file mode 100755 index 000000000..59c12fecd --- /dev/null +++ b/.github/workflows/scripts/check-help-wanted.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +set -e + +PR_URL="$1" + +if [ -z "$PR_URL" ]; then + echo "Usage: $0 " + echo "" + echo "Check if the PR references any non-help-wanted issues and, if so, comment" + echo "on it explaining why the team might close/dismiss it." + exit 1 +fi + +# Extract PR number from URL for logging +PR_NUM="$(basename "$PR_URL")" + +# Extract cli/cli closing issues references from PR +CLOSING_ISSUES="$(gh pr view "$PR_URL" --json closingIssuesReferences --jq '.closingIssuesReferences[] | select(.repository.name == "cli" and .repository.owner.login == "cli") | .number')" + +if [ -z "$CLOSING_ISSUES" ]; then + echo "No closing issues found for PR #$PR_NUM" + exit 0 +fi + +# Check each closing issue for 'help-wanted' label +ISSUES_WITHOUT_HELP_WANTED=() + +for issue_num in $CLOSING_ISSUES; do + echo "Checking issue #$issue_num for 'help wanted' label..." + + # Get issue labels + LABELS=$(gh issue view "$issue_num" --json labels --jq '.labels[].name') + + # Skip if the issue has the gh-attestion or gh-codespace label + # This is because the codeowners for these commands may not be public + # cli org members, and so unless we authenticate with a PAT, we can't + # know who is an external contributor or not. + # So we skip these issues to avoid falsely writing a comment + # on each PR opened by these codeowners. + if echo "$LABELS" | grep -q -e "gh-attestation" -e "gh-codespace"; then + echo "Issue #$issue_num is skipped due to labels" + continue + fi + + # Check if 'help wanted' label exists + if ! echo "$LABELS" | grep -q "help wanted"; then + ISSUES_WITHOUT_HELP_WANTED+=("$issue_num") + echo "Issue #$issue_num does not have 'help wanted' label" + else + echo "Issue #$issue_num has 'help wanted' label" + fi +done + +# If we found issues without 'help wanted' label, post a comment +if [ ${#ISSUES_WITHOUT_HELP_WANTED[@]} -gt 0 ]; then + echo "Found ${#ISSUES_WITHOUT_HELP_WANTED[@]} issues without 'help wanted' label" + + # Build issue list for comment + ISSUE_LIST="" + for issue_num in "${ISSUES_WITHOUT_HELP_WANTED[@]}"; do + ISSUE_LIST="$ISSUE_LIST- #$issue_num"$'\n' + done + + # Create comment message + gh pr comment "$PR_URL" --body-file - <