Skip to content

Commit c803e9e

Browse files
feat: update pull request linting conditions (#131)
* feat: update pull request linting conditions * doc(pull request): create pull request template Add a pull request template for contributors to follow. * fix: update commit parser to match conventional commits * feat: checking merge status and failing by label * feat: Add check for merge status and fail by label don't merge when other release prs are open * fix: macOS error capture httpx.RemoteProtocolError Signed-off-by: Scott Schreckengaust <345885+scottschreckengaust@users.noreply.github.com> * style: clean up pull-request-lint.yml by removing blank lines Removed unnecessary blank lines in pull request lint workflow. * fix: refactor order Removed redundant checks for open release pull requests in the pull request lint workflow. * fix: add pull request target event in workflow * fix: add build group to cliff.toml * docs: update administrative guide for pull-request-lint workflow - Add Pull Request Validation Workflow section with all 5 jobs documented - Add Pipeline 3 mermaid diagram for PR validation gate - Add pull_request_template.md and pull-request-lint.yml to directory tree - Update workflow count from four to five - Add DO_NOT_MERGE_LABEL and HALT_MERGES to repository variables - Add pull-request-lint.yml to permissions model (workflow + job level) - Add pull_request_target safety note to security posture - Add amannn/action-semantic-pull-request and actions/github-script to SHA-pinned actions - Fix changelog prefix typo: doc -> docs to match cliff.toml - Add build prefix to changelog commit groups to match cliff.toml --------- Signed-off-by: Scott Schreckengaust <345885+scottschreckengaust@users.noreply.github.com> Co-authored-by: Scott Schreckengaust <345885+scottschreckengaust@users.noreply.github.com>
1 parent 091d423 commit c803e9e

File tree

5 files changed

+322
-23
lines changed

5 files changed

+322
-23
lines changed

.github/pull_request_template.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Summary
2+
3+
> replace with your summary...
4+
5+
## Changes
6+
7+
> replace with a description of the changes
8+
9+
## User experience
10+
11+
> Please share what the user experience looks like before and after this change
12+
13+
## Checklist
14+
15+
If your change doesn't seem to apply, please leave them unchecked.
16+
17+
* [ ] I have reviewed the [contributing guidelines](https://github.com/awslabs/aidlc-workflows/blob/main/CONTRIBUTING.md)
18+
* [ ] I have performed a self-review of this change
19+
* [ ] Changes have been tested
20+
* [ ] Changes are documented
21+
22+
## Test Plan
23+
24+
> replace with instructions or a checklist for reviewers to verify
25+
26+
## Acknowledgment
27+
28+
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the [project license](https://github.com/awslabs/aidlc-workflows/blob/main/LICENSE).
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
name: Pull Request Validation
2+
3+
on:
4+
pull_request_target:
5+
branches: [ "main" ]
6+
types:
7+
- edited
8+
- labeled
9+
- opened
10+
- ready_for_review
11+
- reopened
12+
- synchronize
13+
- unlabeled
14+
merge_group:
15+
types:
16+
- checks_requested
17+
18+
permissions:
19+
actions: none
20+
attestations: none
21+
checks: none
22+
contents: none
23+
deployments: none
24+
discussions: none
25+
id-token: none
26+
issues: none
27+
models: none
28+
packages: none
29+
pages: none
30+
pull-requests: none
31+
repository-projects: none
32+
security-events: none
33+
statuses: none
34+
35+
concurrency:
36+
group: ${{ github.workflow }}-${{ github.ref }}
37+
cancel-in-progress: true
38+
39+
env:
40+
DO_NOT_MERGE_LABEL: ${{ vars.DO_NOT_MERGE_LABEL || 'do-not-merge' }}
41+
HALT_MERGES: ${{ vars.HALT_MERGES || '0' }}
42+
43+
jobs:
44+
get-pr-info:
45+
permissions:
46+
contents: read
47+
pull-requests: read
48+
# id-token: write
49+
runs-on: ubuntu-latest
50+
outputs:
51+
pr_number: ${{ steps.get-pr.outputs.pr-number }}
52+
pr_labels: ${{ steps.get-pr.outputs.pr-labels }}
53+
env:
54+
GH_TOKEN: ${{ github.token }}
55+
PR_LABELS_JSON: ${{ toJson(github.event.pull_request.labels.*.name) }}
56+
steps:
57+
- name: Get PR info
58+
id: get-pr
59+
run: |
60+
if [ "${{ github.event_name }}" == "merge_group" ]; then
61+
PR_NUMBER=$(echo "${{ github.ref }}" | grep -oP '(?<=/pr-)\d+' || echo "")
62+
PR_LABELS=$(gh api repos/${{ github.repository }}/pulls/$PR_NUMBER | jq -c '[.labels[].name] // []')
63+
echo "::group::Getting Information"
64+
gh api repos/${{ github.repository }}/pulls/$PR_NUMBER
65+
echo $PR_LABELS
66+
echo "::endgroup::"
67+
elif [ "${{ github.event_name }}" == "pull_request" -o "${{ github.event_name }}" == "pull_request_target" ]; then
68+
PR_NUMBER="${{ github.event.pull_request.number }}"
69+
PR_LABELS=$(echo "$PR_LABELS_JSON" | jq -c '.')
70+
fi
71+
echo "::group::Debug Output Values"
72+
echo "PR_NUMBER: $PR_NUMBER"
73+
echo "PR_LABELS: $PR_LABELS"
74+
echo "::endgroup::"
75+
echo "pr-number=$PR_NUMBER" >> $GITHUB_OUTPUT
76+
echo "pr-labels=$PR_LABELS" >> $GITHUB_OUTPUT
77+
78+
check-merge-status:
79+
name: Check Merge Status
80+
runs-on: ubuntu-latest
81+
needs: get-pr-info
82+
permissions:
83+
pull-requests: read
84+
if: always()
85+
steps:
86+
- run: |
87+
PR_NUMBER="${{ needs.get-pr-info.outputs.pr_number }}"
88+
# Default to 0 (allow all) if not set
89+
if [ -z "$HALT_MERGES" ]; then
90+
HALT_MERGES=0
91+
fi
92+
echo "::debug::HALT_MERGES value: $HALT_MERGES"
93+
echo "::debug::This PR number: $PR_NUMBER"
94+
echo "::group::Open Release Pull Requests"
95+
OPEN_RELEASES=$(gh pr list --state "open" --repo "${{ github.repository }}" --json "number,headRefName" | \
96+
jq '[.[] | select(.headRefName | startswith("release/"))]')
97+
echo $OPEN_RELEASES
98+
echo "::endgroup::"
99+
echo $OPEN_RELEASES | jq --exit-status '[.[] | select(.number != '$PR_NUMBER')] | length == 0' && \
100+
echo "No other open release pull requests" || \
101+
(echo "::warning::⚠️ Merges are rejected while there are open release pull requests" && exit 1)
102+
if [ "$HALT_MERGES" = "0" ]; then
103+
echo "✅ All merges are allowed (HALT_MERGES=0)"
104+
exit 0
105+
elif [ "$HALT_MERGES" = "$PR_NUMBER" ]; then
106+
echo "✅ This PR #$PR_NUMBER is explicitly allowed"
107+
exit 0
108+
else
109+
echo "::debug::🛑 Merges are blocked. HALT_MERGES is set to $HALT_MERGES"
110+
if [ "$HALT_MERGES" -lt 0 ]; then
111+
echo "::error::🛑 All merges are blocked"
112+
else
113+
echo "::warning::⚠️ Only PR #$HALT_MERGES is allowed to merge"
114+
fi
115+
exit 1
116+
fi
117+
118+
fail-by-label:
119+
name: Fail by Label
120+
runs-on: ubuntu-latest
121+
needs: get-pr-info
122+
if: always()
123+
steps:
124+
- run: |
125+
echo "::group::Debug Output Values"
126+
echo "PR_LABELS: ${{ needs.get-pr-info.outputs.pr_labels }}"
127+
echo "::endgroup::"
128+
- name: When PR has the "${{ env.DO_NOT_MERGE_LABEL }}" label
129+
id: pr-has-label
130+
if: contains(needs.get-pr-info.outputs.pr_labels, env.DO_NOT_MERGE_LABEL)
131+
run: |
132+
echo "::error::❌ The label \"${{ env.DO_NOT_MERGE_LABEL }}\" is used to prevent merging."
133+
exit 1
134+
- name: When PR does not have the "${{ env.DO_NOT_MERGE_LABEL }}" label
135+
id: pr-missing-label
136+
if: ! contains(needs.get-pr-info.outputs.pr_labels, env.DO_NOT_MERGE_LABEL)
137+
run: |
138+
echo "✅ The label \"${{ env.DO_NOT_MERGE_LABEL }}\" is absent"
139+
exit 0
140+
141+
validate:
142+
name: Validate PR title
143+
runs-on: ubuntu-latest
144+
permissions:
145+
pull-requests: read
146+
if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target')
147+
steps:
148+
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 #v6.1.1
149+
env:
150+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
151+
with:
152+
types: |-
153+
fix
154+
feat
155+
build
156+
chore
157+
ci
158+
docs
159+
style
160+
refactor
161+
perf
162+
test
163+
requireScope: false
164+
165+
contributorStatement:
166+
name: Require Contributor Statement
167+
runs-on: ubuntu-latest
168+
permissions:
169+
pull-requests: read
170+
env:
171+
PR_BODY: ${{ github.event.pull_request.body }}
172+
EXPECTED: By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the [project license](https://github.com/${{ github.repository }}/blob/main/LICENSE).
173+
HELP: Contributor statement missing from PR description. Please include the following text in the PR description
174+
if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && !(github.event.pull_request.user.login == 'aidlc-workflows' || github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'github-actions' || github.event.pull_request.user.login == 'github-actions[bot]')
175+
steps:
176+
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0
177+
with:
178+
script: |-
179+
const actual = process.env.PR_BODY.replace(/\r?\n/g, "\n");
180+
const expected = process.env.EXPECTED.replace(/\r?\n/g, "\n");
181+
if (!actual.includes(expected)) {
182+
console.log("%j", actual);
183+
console.log("%j", expected);
184+
core.setFailed(`${process.env.HELP}: ${expected}`);
185+
}

cliff.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ commit_parsers = [
3535
{ message = "^docs: update changelog", skip = true },
3636
{ message = "^feat", group = "Features" },
3737
{ message = "^fix", group = "Bug Fixes" },
38-
{ message = "^doc", group = "Documentation" },
38+
{ message = "^docs", group = "Documentation" },
3939
{ message = "^perf", group = "Performance" },
4040
{ message = "^refactor", group = "Refactoring" },
4141
{ message = "^style", group = "Style" },
4242
{ message = "^test", group = "Tests" },
43+
{ message = "^build", group = "CI/CD" },
4344
{ message = "^ci", group = "CI/CD" },
4445
{ message = "^chore", group = "Miscellaneous" },
4546
]

0 commit comments

Comments
 (0)