-
Notifications
You must be signed in to change notification settings - Fork 7
Quality Gates: PR Title standardization and LOC #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
bf3d8e6
2441a3b
d72a870
9940a32
6af1f48
eae85c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| ## CHANGELOG | ||
| REPLACE_ME_WITH_CHANGELOG | ||
|
|
||
| ## SUMMARY | ||
| REPLACE_ME_WITH_SUMMARY_OF_THE_CHANGES | ||
|
|
||
| ## FUNCTIONAL AUTOMATION CHANGES PR | ||
| - [ ] Yes | ||
| - If Yes, PR : | ||
| - [ ] No | ||
| - If No, Reason: | ||
|
|
||
| ## AUTOMATION TEST REPORT URL | ||
| REPLACE_ME_WITH_TEST_REPORT_URL | ||
|
|
||
| ## AREAS OF IMPACT | ||
| REPLACE_ME_WITH_AREAS_OF_IMPACT_OR_NA | ||
|
|
||
| ## TYPE OF CHANGE | ||
| - [ ] 🐞 Bugfix | ||
| - [ ] 🌟 Feature | ||
| - [ ] ✨ Enhancement | ||
| - [ ] 🧪 Unit Test Cases | ||
| - [ ] 📔 Documentation | ||
| - [ ] ⚙️ Chore - Build Related / Configuration / Others | ||
|
|
||
|
|
||
| ## DOCUMENTATION | ||
| REPLACE_ME_WITH_DOCUMENTATION_LINK_OR_NA |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Scripts | ||
|
|
||
| ## Generate changelog | ||
|
|
||
| Lists PRs merged into a branch (excludes "Parent branch sync" and bot-authored PRs). | ||
|
|
||
| **Prerequisites:** `jq`, and GitHub credentials as env vars. | ||
|
|
||
| ### Set credentials (once per terminal) | ||
|
|
||
| ```bash | ||
| export GH_USERNAME=your-github-username | ||
| export GH_PAT=your-github-personal-access-token | ||
| ``` | ||
|
|
||
| ### Commands | ||
|
|
||
| From repo root: | ||
|
|
||
| | What you want | Command | | ||
| |---------------|---------| | ||
| | PRs merged into **current branch** (last 30 days) | `./.github/scripts/generate-changelog.sh` | | ||
| | PRs merged into **master** (last 30 days) | `./.github/scripts/generate-changelog.sh master` | | ||
| | PRs merged into **master** since a date | `./.github/scripts/generate-changelog.sh master "merged:>=2025-01-01"` | | ||
|
|
||
| ### Arguments | ||
|
|
||
| 1. **Branch** (optional) — default: current branch | ||
| 2. **Date filter** (optional) — default: last 30 days (e.g. `merged:>=2025-01-01`) | ||
|
|
||
| Output includes a GitHub search URL to verify results. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -e | ||
|
|
||
| # Check required environment variables | ||
| if [[ -z "$GH_USERNAME" ]]; then | ||
| echo "❌ Error: Environment variable GH_USERNAME not found" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [[ -z "$GH_PAT" ]]; then | ||
| echo "❌ Error: Environment variable GH_PAT not found" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Optional: Branch name (defaults to current branch if not provided) | ||
| SOURCE_BRANCH="${1:-$(git branch --show-current)}" | ||
| # Optional: Date filter (defaults to last 30 days if not provided) | ||
| DATE_FILTER="${2:-merged:>=$(date -u -v-30d +%Y-%m-%d 2>/dev/null || date -u -d '30 days ago' +%Y-%m-%d)}" | ||
|
|
||
| # Repo is set per-repo when this file is pushed (placeholder replaced by upload script) | ||
| REPO="chargebee/chargebee-android" | ||
|
|
||
| echo "🔍 Searching for PRs merged into $SOURCE_BRANCH..." | ||
|
|
||
| # GitHub API call with error handling | ||
| HTTP_STATUS=$(curl -s -w "%{http_code}" -G -u "$GH_USERNAME:$GH_PAT" \ | ||
| "https://api.github.com/search/issues" \ | ||
| --data-urlencode "q=NOT \"Parent branch sync\" in:title is:pr repo:$REPO is:merged base:$SOURCE_BRANCH merged:$DATE_FILTER -author:app/distributed-gitflow-app" \ | ||
| -o /tmp/curl_output.json \ | ||
| 2>/tmp/curl_error.log) | ||
|
|
||
| CURL_EXIT_CODE=$? | ||
|
|
||
| echo "🌐 API call status: $HTTP_STATUS" | ||
|
|
||
| if [ $CURL_EXIT_CODE -ne 0 ]; then | ||
| echo "❌ Error: curl request failed with exit code $CURL_EXIT_CODE" | ||
| echo "Error details: $(cat /tmp/curl_error.log)" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ "$HTTP_STATUS" -ne 200 ]; then | ||
| echo "❌ Error: API returned HTTP status $HTTP_STATUS" | ||
| echo "Response: $(cat /tmp/curl_output.json)" | ||
| exit 1 | ||
| fi | ||
|
|
||
| PR_LIST_RESPONSE=$(cat /tmp/curl_output.json) | ||
|
|
||
| # Clean invalid control characters from JSON response | ||
| if ! echo "$PR_LIST_RESPONSE" | jq . >/dev/null 2>&1; then | ||
| echo "⚠️ Invalid JSON detected — cleaning control characters..." | ||
| PR_LIST_RESPONSE=$(echo "$PR_LIST_RESPONSE" | tr -d '\000-\037') | ||
|
|
||
| if ! echo "$PR_LIST_RESPONSE" | jq . >/dev/null 2>&1; then | ||
| echo "$PR_LIST_RESPONSE" > /tmp/invalid_json_debug.json | ||
| echo "❌ Error: JSON is still invalid after cleaning control characters" | ||
| echo "💡 Use 'cat /tmp/invalid_json_debug.json' to inspect the JSON" | ||
| exit 1 | ||
| fi | ||
| fi | ||
|
|
||
| PR_MERGED_COUNT=$(echo "$PR_LIST_RESPONSE" | jq '.total_count') | ||
|
|
||
| # Color codes | ||
| GREEN='\033[0;32m' | ||
| YELLOW='\033[0;33m' | ||
| NOCOLOR='\033[0m' | ||
|
|
||
| echo "==============================================================================" | ||
| echo -e "Found ${GREEN}$PR_MERGED_COUNT${NOCOLOR} PR(s) merged into $SOURCE_BRANCH (filter: $DATE_FILTER)" | ||
| echo "==============================================================================" | ||
| echo -e "## ${GREEN}CHANGELOG${NOCOLOR}" | ||
| echo "$PR_LIST_RESPONSE" | jq -r '.items[] | (.title) + " (" + (.user.login) + ") [#" + (.number | tostring) + "]"' | sort | ||
| printf "\n" | ||
| echo "==============================================================================" | ||
| echo -e "${GREEN}GitHub Search URL (to verify, if required)${NOCOLOR}" | ||
| BRANCH_ENCODED=$(echo "$SOURCE_BRANCH" | sed 's/ /%20/g') | ||
| echo "https://github.com/$REPO/pulls?q=NOT+%22Parent+branch+sync%22+in%3Atitle+is%3Apr+is%3Amerged+base%3A$BRANCH_ENCODED+merged%3A$DATE_FILTER+-author%3Aapp%2Fdistributed-gitflow-app" | ||
| echo "==============================================================================" | ||
|
|
||
| # Clean up temporary files | ||
| rm -f /tmp/curl_output.json /tmp/curl_error.log | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| name: Common PR Lint | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [master, main,staging, dev,develop] | ||
| types: [ready_for_review, reopened, review_requested, review_request_removed, opened, edited] | ||
|
|
||
| jobs: | ||
| pr-lint: | ||
| name: Common PR Lint Checks | ||
| if: github.base_ref == 'main' || github.base_ref == 'master' | ||
| uses: chargebee/cb-cicd-pipelines/.github/workflows/pr-lint.yml@main | ||
| secrets: inherit |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,81 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: PR Size Check | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull_request: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| types: [ reopened, opened, synchronize, edited, labeled, unlabeled ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| branches: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - master | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pre-approval-comment: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Announce pending bypass approval | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: ${{ github.event.pull_request.user.login != 'distributed-gitflow-app[bot]' && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| !startsWith(github.head_ref, 'revert-') && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| !startsWith(github.head_ref, 'parent-branch-sync/') && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contains(github.event.pull_request.labels.*.name, 'pr-size-exception') }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: graviton-small-runner | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/github-script@v7 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| script: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const owner = context.repo.owner; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const repo = context.repo.repo; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const issue_number = context.payload.pull_request.number; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const marker = '<!-- pr-size-bypass-pending -->'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const pending = `${marker} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 🛑 The \`pr-size-exception\` label is present. This workflow is **waiting for approvals** from the **[cb-Billing-CAB-reviewers](https://github.com/orgs/chargebee/teams/cb-billing-cab-approvers)**.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // create a new comment when the workflow runs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await github.rest.issues.createComment({ owner, repo, issue_number, body: pending }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pr-size-check: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Priority: 🟡 MEDIUM Problem: The Why: Each How to Fix: Before creating the comment, list existing issue comments and only create a new one if no comment containing the marker is already present.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Check PR size | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: ${{ (github.base_ref == 'master') && github.event.pull_request.user.login != 'distributed-gitflow-app[bot]' && !startsWith(github.head_ref, 'revert-') && !startsWith(github.head_ref, 'parent-branch-sync/') }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: graviton-small-runner | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id-token: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BYPASS_LABEL: pr-size-exception | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| environment: ${{ contains(github.event.pull_request.labels.*.name, 'pr-size-exception') && 'cb-billing-reviewers' || '' }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: chargebee/cb-cicd-pipelines/.github/actions/pr-size-check@v4.20.3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: ${{ !contains(github.event.pull_request.labels.*.name, env.BYPASS_LABEL) }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| githubToken: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorSize: 250 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warningSize: 200 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| excludePaths: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .github/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .cursor/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Ensure required check passes when bypassed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: ${{ contains(github.event.pull_request.labels.*.name, env.BYPASS_LABEL) }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: echo "Bypass active — marking job successful." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Configure OIDC authentication | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: ${{ contains(github.event.pull_request.labels.*.name, env.BYPASS_LABEL) }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: aws-actions/configure-aws-credentials@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| role-to-assume: arn:aws:iam::127322177288:role/OIDC_S3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| role-session-name: GithubActionsSession | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| role-duration-seconds: 900 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| aws-region: us-east-1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Record bypass approval to S3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: ${{ contains(github.event.pull_request.labels.*.name, env.BYPASS_LABEL) }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| REPO="${{ github.repository }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PR_LINK="https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WF_ID="${{ github.run_id }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| S3_KEY="${REPO}/datas/${WF_ID}.json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| printf '{"repo":"%s","date":"%s","pr_link":"%s","wf_id":"%s"}\n' "$REPO" "$DATE" "$PR_LINK" "$WF_ID" | \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| aws s3 cp - "s3://prsizebypassdata/${S3_KEY}" --content-type application/json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Recorded to s3://prsizebypassdata/${S3_KEY}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Priority: 🟠 HIGH
Problem: The default
DATE_FILTERvalue already includes themerged:qualifier, but it is later interpolated into the search query asmerged:$DATE_FILTER, resulting in a malformed query likemerged:merged:>=YYYY-MM-DD.Why: The malformed
merged:merged:...qualifier can cause the GitHub Search API to return incorrect results (or none at all), breaking the core purpose of this script: reliably generating a changelog of merged PRs.How to Fix: Change the default
DATE_FILTERto contain only the date expression (e.g.>=YYYY-MM-DD) rather than the fullmerged:qualifier, so thatmerged:$DATE_FILTERbecomes a validmerged:>=YYYY-MM-DDsearch qualifier in both the API call and the verification URL.