Skip to content

Commit 4c5a05f

Browse files
authored
Merge branch 'awslabs:main' into main
2 parents d0262ad + 7deb0bf commit 4c5a05f

7 files changed

Lines changed: 359 additions & 33 deletions

File tree

.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: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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+
env:
86+
GH_TOKEN: ${{ github.token }}
87+
steps:
88+
- run: |
89+
PR_NUMBER="${{ needs.get-pr-info.outputs.pr_number }}"
90+
# Default to 0 (allow all) if not set
91+
if [ -z "$HALT_MERGES" ]; then
92+
HALT_MERGES=0
93+
fi
94+
echo "::debug::HALT_MERGES value: $HALT_MERGES"
95+
echo "::debug::This PR number: $PR_NUMBER"
96+
echo "::group::Open Release Pull Requests"
97+
gh pr list --state "open" --repo "${{ github.repository }}" --json "number,headRefName"
98+
OPEN_RELEASES=$(gh pr list --state "open" --repo "${{ github.repository }}" --json "number,headRefName" | \
99+
jq '[.[] | select(.headRefName | startswith("release/"))]')
100+
echo $OPEN_RELEASES
101+
echo "::endgroup::"
102+
echo $OPEN_RELEASES | jq --exit-status '[.[] | select(.number != '$PR_NUMBER')] | length == 0' && \
103+
echo "No other open release pull requests" || \
104+
(echo "::warning::⚠️ Merges are rejected while there are open release pull requests" && exit 1)
105+
if [ "$HALT_MERGES" = "0" ]; then
106+
echo "✅ All merges are allowed (HALT_MERGES=0)"
107+
exit 0
108+
elif [ "$HALT_MERGES" = "$PR_NUMBER" ]; then
109+
echo "✅ This PR #$PR_NUMBER is explicitly allowed"
110+
exit 0
111+
else
112+
echo "::debug::🛑 Merges are blocked. HALT_MERGES is set to $HALT_MERGES"
113+
if [ "$HALT_MERGES" -lt 0 ]; then
114+
echo "::error::🛑 All merges are blocked"
115+
else
116+
echo "::warning::⚠️ Only PR #$HALT_MERGES is allowed to merge"
117+
fi
118+
exit 1
119+
fi
120+
121+
fail-by-label:
122+
name: Fail by Label
123+
runs-on: ubuntu-latest
124+
needs: get-pr-info
125+
if: always()
126+
steps:
127+
- run: |
128+
echo "::group::Debug Output Values"
129+
echo "PR_LABELS: ${{ needs.get-pr-info.outputs.pr_labels }}"
130+
echo "::endgroup::"
131+
- name: When PR has the "${{ env.DO_NOT_MERGE_LABEL }}" label
132+
id: pr-has-label
133+
if: contains(needs.get-pr-info.outputs.pr_labels, env.DO_NOT_MERGE_LABEL)
134+
run: |
135+
echo "::error::❌ The label \"${{ env.DO_NOT_MERGE_LABEL }}\" is used to prevent merging."
136+
exit 1
137+
- name: When PR does not have the "${{ env.DO_NOT_MERGE_LABEL }}" label
138+
id: pr-missing-label
139+
if: ! contains(needs.get-pr-info.outputs.pr_labels, env.DO_NOT_MERGE_LABEL)
140+
run: |
141+
echo "✅ The label \"${{ env.DO_NOT_MERGE_LABEL }}\" is absent"
142+
exit 0
143+
144+
validate:
145+
name: Validate PR title
146+
runs-on: ubuntu-latest
147+
permissions:
148+
pull-requests: read
149+
if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target')
150+
steps:
151+
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 #v6.1.1
152+
env:
153+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154+
with:
155+
types: |-
156+
fix
157+
feat
158+
build
159+
chore
160+
ci
161+
docs
162+
style
163+
refactor
164+
perf
165+
test
166+
requireScope: false
167+
168+
contributorStatement:
169+
name: Require Contributor Statement
170+
runs-on: ubuntu-latest
171+
permissions:
172+
pull-requests: read
173+
env:
174+
PR_BODY: ${{ github.event.pull_request.body }}
175+
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).
176+
HELP: Contributor statement missing from PR description. Please include the following text in the PR description
177+
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]')
178+
steps:
179+
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0
180+
with:
181+
script: |-
182+
const actual = process.env.PR_BODY.replace(/\r?\n/g, "\n");
183+
const expected = process.env.EXPECTED.replace(/\r?\n/g, "\n");
184+
if (!actual.includes(expected)) {
185+
console.log("%j", actual);
186+
console.log("%j", expected);
187+
core.setFailed(`${process.env.HELP}: ${expected}`);
188+
}

.github/workflows/release-pr.yml

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ jobs:
7171
echo "WARNING: No conventional commits detected — falling back to patch bump: $VERSION"
7272
else
7373
echo "::warning::No conventional commits and no existing tags — nothing to release"
74-
exit 0
74+
exit 1
7575
fi
7676
fi
7777
fi
@@ -110,7 +110,7 @@ jobs:
110110
# Check if branch already exists (local or remote)
111111
if git ls-remote --exit-code --heads origin "$BRANCH" &>/dev/null; then
112112
echo "::warning::Branch '$BRANCH' already exists. A release PR may already be open — close it and delete the branch to re-run."
113-
exit 0
113+
exit 1
114114
fi
115115
116116
git config --local user.email "github-actions[bot]@users.noreply.github.com"
@@ -119,24 +119,48 @@ jobs:
119119
git add CHANGELOG.md
120120
if git diff --cached --quiet CHANGELOG.md; then
121121
echo "No changes to CHANGELOG.md"
122-
exit 0
122+
exit 1
123123
fi
124124
125125
git checkout -b "$BRANCH"
126126
git commit -m "docs: update changelog for $TAG"
127127
git push origin "$BRANCH"
128128
129129
LABEL_FLAG=""
130-
if gh label list --search "release" --json name --jq '.[].name' | grep -qx "release"; then
131-
LABEL_FLAG="--label release"
132-
fi
130+
for LABEL in "release"; do
131+
if gh label list --search "$LABEL" --json name --jq '.[].name' | grep -qx "$LABEL"; then
132+
LABEL_FLAG="$LABEL_FLAG --label $LABEL"
133+
fi
134+
done
133135
136+
# Draft PR because the github-actions[bot] does not trigger a pull_request_target workflow
134137
gh pr create \
135-
--title "release: $TAG" \
138+
--title "docs: update changelog for $BRANCH" \
139+
--draft \
136140
--body "$(cat <<EOF
137-
## Release $TAG
141+
# Release $TAG
142+
143+
> [!WARNING]
144+
> All other pull requests are blocked until merged or closed
145+
146+
This pull request is for the $TAG release.
147+
148+
## Checklist (in order)
149+
150+
1. [ ] Mark the pull request "Ready for review" to trigger required workflows
151+
2. [ ] Inspect the CHANGELOG.md and "Approve" or "Reject" the pending [CodeBuild](https://github.com/awslabs/aidlc-workflows/actions/workflows/codebuild.yml) GitHub Action
152+
3. [ ] Evaluate the artifacts
153+
4. [ ] Review the pull request (if approved set the "Merge when ready")
154+
155+
## Post Merge
156+
157+
* [ ] Verify $TAG tag
158+
* [ ] Approve "Approve" or "Reject" the pending [CodeBuild](https://github.com/awslabs/aidlc-workflows/actions/workflows/codebuild.yml) GitHub Action
159+
* [ ] Review the drafted release artifacts for completion
160+
* [ ] Publish the release
138161
139-
This PR updates CHANGELOG.md for the $TAG release.
162+
> [!CAUTION]
163+
> Simply closing this will block a subsequent $TAG release, so delete the branch or reopen the pull request if necessary
140164
141165
**When merged**, the merge commit will be automatically tagged as \`$TAG\`, which triggers:
142166
- \`release.yml\` — creates a draft GitHub Release with the rules zip

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ Here's the general flow once an extension is enabled:
529529
The workflow currently ships with a baseline security extension.
530530

531531
> [!IMPORTANT]
532-
> The security extension rules are based on the [OWASP Top 10](https://owasp.org/www-project-top-ten/) and have been tested through controlled experimentation (see [PR #80](https://github.com/awslabs/aidlc-workflows/pull/80)). They are provided as a directional reference for building effective security rules within AI-DLC workflows. Each organization should build, customize, and thoroughly test their own security rules before deploying in production workflows.
532+
> The security extension rules are provided as a directional reference for building effective security rules within AI-DLC workflows. Each organization should build, customize, and thoroughly test their own security rules before deploying in production workflows.
533533
534534
```
535535
aws-aidlc-rule-details/

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)