-
Notifications
You must be signed in to change notification settings - Fork 0
178 lines (160 loc) · 7.39 KB
/
pr_validation.yml
File metadata and controls
178 lines (160 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
name: Package PR Validation
on:
pull_request_target:
types: [opened, synchronize, reopened]
branches:
- packages #only run on PRs to the packages branch
paths:
- '*/hatch_metadata.json' #only run on PRs that change hatch_metadata.json files, meaning any change leads to at least a version bump.
jobs:
check-org-membership:
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App token for Org Management
id: generate-org-token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.HATCH_ORG_MANAGEMENT_APP_ID }}
private_key: ${{ secrets.HATCH_ORG_MANAGEMENT_APP_PRIVATE_KEY }}
# Security Check: Only allow PRs from organization members
- name: Check organization membership
id: check-org-membership
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate-org-token.outputs.token }}
script: |
try {
const response = await github.rest.orgs.checkMembershipForUser({
org: 'CrackingShells',
username: context.payload.pull_request.user.login
});
if (response.status === 204) {
console.log('User is a member of CrackingShells organization');
return true;
}
} catch (error) {
console.log(`User is not a member of CrackingShells organization: ${error}`);
}
return false;
- name: Generate GitHub App token for workflow
id: generate-workflow-token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.HATCH_WORKFLOW_APP_ID }}
private_key: ${{ secrets.HATCH_WORKFLOW_APP_PRIVATE_KEY }}
- name: Comment and fail if not org member
if: ${{ steps.check-org-membership.outputs.result == 'false' }}
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate-workflow-token.outputs.token }}
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '⚠️ During Alpha development, only members of the CrackingShells organization can submit packages. 😖\nThis stage will last a couple more weeks, please wait until then before submitting again. 🙏'
});
core.setFailed('PR author is not a member of CrackingShells organization');
detect-changes:
needs: check-org-membership
runs-on: ubuntu-latest
outputs:
not_unique: ${{ steps.check-multiple.outputs.not_unique }}
package_name: ${{ steps.check-multiple.outputs.package_name }} #only if a unique package is found
steps:
- uses: actions/checkout@v4
- name: Detect changed package directories
id: detect-changed-paths
uses: dorny/paths-filter@v2
with:
list-files: json
filters: |
changes:
- added|modified: '*/hatch_metadata.json'
- name: Check for changes in multiple packages
if: ${{ steps.detect-changed-paths.outputs.changes == 'true' }}
id: check-multiple
run: |
# Extract base directories (package names) from the changed files using bash parameter expansion
# 'changes_files' gives the list of changed files from filter `changes` in previous step
CHANGED_FILES='${{ steps.detect-changed-paths.outputs.changes_files }}'
PACKAGE_DIRS=()
# Process each file path to extract package name using bash parameter expansion
for FILE in $(echo "$CHANGED_FILES" | jq -r '.[]'); do
# Extract package name (everything before the first slash)
PACKAGE=${FILE%%/*}
PACKAGE_DIRS+=("$PACKAGE")
done
# Get unique package directories
UNIQUE_PACKAGES=$(printf "%s\n" "${PACKAGE_DIRS[@]}" | sort -u)
PACKAGE_COUNT=$(echo "$UNIQUE_PACKAGES" | grep -v "^$" | wc -l)
echo "Package directories changed:"
echo "$UNIQUE_PACKAGES"
echo "Total unique package directories: $PACKAGE_COUNT"
# Set output if multiple packages were changed
if [ "$PACKAGE_COUNT" -ne 1 ]; then
echo "not_unique=true" >> $GITHUB_OUTPUT
if [ "$PACKAGE_COUNT" -gt 1 ]; then
echo "::error::PR contains changes to multiple packages: $UNIQUE_PACKAGES. Please submit separate PRs for each package."
else
echo "::error::PR contains no changes to any package. Please ensure you are modifying a valid package."
fi
exit 1
else
echo "not_unique=false" >> $GITHUB_OUTPUT
echo "package_name=$(echo "$UNIQUE_PACKAGES" | grep -v "^$")" >> $GITHUB_OUTPUT
fi
send-package-for-validation:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.not_unique == 'false' && needs.detect-changes.outputs.package_name != '' }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }} # Explicitly checkout the PR code
fetch-depth: 0 # Fetch all history to ensure we have the package files
- name: Upload package as artifact
id: upload-artifact
uses: actions/upload-artifact@v4
with:
name: hatch-package-${{ needs.detect-changes.outputs.package_name }}
path: "./${{ needs.detect-changes.outputs.package_name }}"
retention-days: 1
if-no-files-found: error
- name: Generate GitHub App token
id: generate-token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.HATCH_WORKFLOW_APP_ID }}
private_key: ${{ secrets.HATCH_WORKFLOW_APP_PRIVATE_KEY }}
- name: Trigger Validation Package Workflow in Registry
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ steps.generate-token.outputs.token }}
repository: CrackingShells/Hatch-Registry
event-type: validate-package
client-payload: |-
{
"run_id": "${{ github.run_id }}",
"workflow_id": "${{ github.workflow }}",
"repository": "${{ github.repository }}",
"pr_number": "${{ github.event.pull_request.number }}",
"artifact_name": "hatch-package-${{ needs.detect-changes.outputs.package_name }}",
"package_name": "${{ needs.detect-changes.outputs.package_name }}"
}
- name: Send Message to PR
# if no cancellation or failure occurs, send a message to the PR
if: ${{ cancelled() == false && failure() == false }}
uses: actions/github-script@v7
with:
script: |
const pr_number = "${{ github.event.pull_request.number }}"
const package_name = "${{ needs.detect-changes.outputs.package_name }}"
const message = `Package **${package_name}** sent to **Hatch-Registry** for validation.\nThe validation process may take a few minutes.`
await github.rest.issues.createComment({
issue_number: pr_number,
owner: context.repo.owner,
repo: context.repo.repo,
body: message
})