-
Notifications
You must be signed in to change notification settings - Fork 70
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
Minimize PR overhead for non-code changes #16279
Changes from all commits
1099557
d40c347
7bead95
774c156
3c43d79
cbade80
d0e8fdc
46c9108
e91ef24
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,105 @@ | ||
name: Set Test Statuses | ||
on: | ||
- pull_request_target | ||
permissions: | ||
pull-requests: write | ||
checks: write | ||
contents: write | ||
statuses: write | ||
jobs: | ||
# Tugboat tests are not automatically set pending, even though they are | ||
# required in branch protection rules (see #10553). | ||
# | ||
# Therefore, a PR can inappropriately appear to be ready to merge if, | ||
# for instance, a composer.lock merge conflict prevents the Tugboat | ||
# preview from successfully building. | ||
# | ||
# Additionally, CI tests are only run for code changes but they are | ||
# required checks, even for documentation only changes. In these cases, | ||
# the tests should be skipped since no functional changes have occured. | ||
# | ||
# To address these two issues, this action sets check statuses directly | ||
# to the appropriate states: | ||
# - For docs only changes, all required checks are set to 'success' | ||
# - For code changes, Tugboat tests are set to 'pending' so that we can | ||
# trust our automated code review processes more. | ||
set-test-statuses: | ||
name: Set Tests Statuses | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Check for documentation only changes | ||
id: docs-only | ||
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 | ||
with: | ||
script: | | ||
const opts = github.rest.pulls.listFiles.endpoint.merge({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
pull_number: context.payload.pull_request.number, | ||
}) | ||
const files = await github.paginate( | ||
opts, | ||
(response) => response.data.map( | ||
(file) => file.filename | ||
) | ||
) | ||
|
||
for (const file of files) { | ||
console.log(`Checking PR file: ${file}`) | ||
if (!file.endsWith('.md')) { | ||
console.log(`Code change found in: ${file}`) | ||
return "false" | ||
} | ||
} | ||
|
||
console.log(`No code change found.`) | ||
return "true" | ||
result-encoding: string | ||
- name: Set status for documentation changes. | ||
if: ${{ steps.docs-only.outputs.result == 'true' }} | ||
run: | | ||
test_names=( | ||
va/tests/cypress | ||
va/tests/phpunit | ||
va/tests/content-build-gql | ||
va/tests/status-error | ||
'Composer Validate' | ||
'Check Fields' | ||
ESLint | ||
Stylelint | ||
PHPStan | ||
PHPUnit | ||
PHP_CodeSniffer | ||
'PHP Lint' | ||
) | ||
for test_name in "${test_names[@]}"; do | ||
gh api \ | ||
--method POST \ | ||
-H "Accept: application/vnd.github+json" \ | ||
"/repos/${GITHUB_REPOSITORY}/statuses/${SHA}" \ | ||
-f state='success' \ | ||
-f context="${test_name}"; | ||
done; | ||
env: | ||
SHA: ${{ github.event.pull_request.head.sha }} | ||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Set status for code changes. | ||
if: ${{ steps.docs-only.outputs.result == 'false' }} | ||
run: | | ||
test_names=( | ||
va/tests/cypress | ||
va/tests/phpunit | ||
va/tests/content-build-gql | ||
va/tests/status-error | ||
) | ||
for test_name in "${test_names[@]}"; do | ||
gh api \ | ||
--method POST \ | ||
-H "Accept: application/vnd.github+json" \ | ||
"/repos/${GITHUB_REPOSITORY}/statuses/${SHA}" \ | ||
-f state='pending' \ | ||
-f context="${test_name}"; | ||
done; | ||
env: | ||
SHA: ${{ github.event.pull_request.head.sha }} | ||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Delete Tugboat Preview | ||
on: | ||
pull_request: | ||
types: | ||
- closed | ||
paths-ignore: | ||
- '**.md' | ||
|
||
jobs: | ||
tugboat_delete_preview: | ||
runs-on: self-hosted | ||
env: | ||
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt | ||
name: Delete Tugboat Preview | ||
steps: | ||
- name: Restore Preview ID | ||
uses: actions/cache/restore@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 | ||
with: | ||
path: .tugboat_preview.txt | ||
key: ${{ runner.os }}-tugboat-preview-id-pr-${{ github.event.pull_request.number }} | ||
- name: Set Preview ID | ||
run: | | ||
if ! [ -f .tugboat_preview.txt ]; then | ||
echo "Preview ID not found, please manually delete Tugboat Preview. Contact platform-cms-qa on Github or CMS QA Engineers in #cms-support on Slack for assistance." | ||
exit 1 | ||
fi | ||
PREVIEW_ID=$(cat .tugboat_preview.txt) | ||
echo "Preview ID: ${PREVIEW_ID}" | ||
echo "PREVIEW_ID=$PREVIEW_ID" >> $GITHUB_ENV | ||
- name: Cleanup temporary file | ||
JunTaoLuo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
run: rm .tugboat_preview.txt | ||
- name: Delete Tugboat Preview | ||
run: | | ||
curl --fail \ | ||
-H "Authorization: Bearer ${{ secrets.TUGBOAT_API_TOKEN }}" \ | ||
-H "Content-Type: application/json" \ | ||
-X DELETE \ | ||
-d '{ "force": "false" }' \ | ||
https://api.tugboat.vfs.va.gov/v3/previews/${{ env.PREVIEW_ID }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: Create Tugboat Preview | ||
on: | ||
pull_request: | ||
types: | ||
- opened | ||
- reopened | ||
paths-ignore: | ||
- '**.md' | ||
|
||
jobs: | ||
tugboat_create_preview: | ||
runs-on: self-hosted | ||
env: | ||
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt | ||
name: Create Tugboat Preview | ||
steps: | ||
- name: Create Tugboat Preview | ||
id: tugboat_pr_preview | ||
run: | | ||
curl --fail \ | ||
-H "Authorization: Bearer ${{ secrets.TUGBOAT_API_TOKEN }}" \ | ||
-H "Content-Type: application/json" \ | ||
-X POST \ | ||
-d '{ "repo": "${{ secrets.TUGBOAT_REPOSITORY }}", "ref": "${{ github.event.pull_request.number }}", "name": "${{ github.event.pull_request.title }}", "type": "pullrequest" }' \ | ||
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. If this is all of the information that we need to provide, this is fantastic! It seems like it'll resolve an issue we've had where the TIC interprets inline code (e.g. "Fixed a bug in 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. Fascinating. That was probably pretty hard to find haha. Though I suppose commit messages and even branch names theoretically can be unsafe if we used it in some shell commands. Hence
|
||
-o .tugboat_response.json \ | ||
https://api.tugboat.vfs.va.gov/v3/previews | ||
- name: Diagnostics | ||
run: cat .tugboat_response.json | ||
- name: Extract Preview ID | ||
run: jq -r .preview .tugboat_response.json > .tugboat_preview.txt | ||
- name: Delete Previous Preview ID | ||
continue-on-error: true | ||
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 | ||
with: | ||
script: | | ||
await github.rest.actions.deleteActionsCacheByKey({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
key: `${{ runner.os }}-tugboat-preview-id-pr-${{ github.event.pull_request.number }}`, | ||
}); | ||
- name: Save Preview ID | ||
uses: actions/cache/save@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 | ||
with: | ||
path: .tugboat_preview.txt | ||
key: ${{ runner.os }}-tugboat-preview-id-pr-${{ github.event.pull_request.number }} | ||
- name: Cleanup temporary file | ||
run: rm .tugboat_preview.txt |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Rebuild Tugboat Preview | ||
on: | ||
pull_request: | ||
types: | ||
- synchronize | ||
paths-ignore: | ||
- '**.md' | ||
|
||
jobs: | ||
tugboat_rebuild_preview: | ||
runs-on: self-hosted | ||
env: | ||
NODE_EXTRA_CA_CERTS: /etc/ssl/certs/ca-certificates.crt | ||
name: Rebuild Tugboat Preview | ||
steps: | ||
- name: Restore Preview ID | ||
uses: actions/cache/restore@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 | ||
with: | ||
path: .tugboat_preview.txt | ||
key: ${{ runner.os }}-tugboat-preview-id-pr-${{ github.event.pull_request.number }} | ||
- name: Set Preview ID | ||
run: | | ||
if ! [ -f .tugboat_preview.txt ]; then | ||
echo "Preview ID not found, please manually rebuild Tugboat Preview. Contact platform-cms-qa on Github or CMS QA Engineers in #cms-support on Slack for assistance." | ||
exit 1 | ||
fi | ||
PREVIEW_ID=$(cat .tugboat_preview.txt) | ||
echo "Preview ID: ${PREVIEW_ID}" | ||
echo "PREVIEW_ID=$PREVIEW_ID" >> $GITHUB_ENV | ||
- name: Cleanup temporary file | ||
run: rm .tugboat_preview.txt | ||
- name: Rebuild Tugboat Preview | ||
run: | | ||
curl --fail \ | ||
-H "Authorization: Bearer ${{ secrets.TUGBOAT_API_TOKEN }}" \ | ||
-H "Content-Type: application/json" \ | ||
-X POST \ | ||
-d '{ "children": "false", "force": "false" }' \ | ||
https://api.tugboat.vfs.va.gov/v3/previews/${{ env.PREVIEW_ID }}/rebuild |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
name: Refresh Tugboat Preview ID Cache | ||
on: | ||
# Every 6 hours. | ||
schedule: | ||
- cron: '0 */6 * * *' | ||
jobs: | ||
# Collects the cache keys that need to be refreshed | ||
collect_cache_keys: | ||
name: Collect Tugboat Preview ID cache keys that need to be refreshed | ||
outputs: | ||
matrix: ${{ steps.cache-keys.outputs.result }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Cross reference open PRs against cache keys in repo | ||
id: cache-keys | ||
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1 | ||
with: | ||
script: | | ||
const prs = await github.paginate( | ||
github.rest.pulls.list, | ||
{ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
state: 'open', | ||
}, | ||
(response) => response.data.map((pr) => pr.number) | ||
) | ||
|
||
for (const pr of prs) { | ||
console.log(`PR: ${pr}`) | ||
} | ||
|
||
const cacheKeys = await github.paginate( | ||
github.rest.actions.getActionsCacheList, | ||
{ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
}, | ||
(response) => response.data.map((cache) => cache.key) | ||
) | ||
|
||
for (const key of cacheKeys) { | ||
console.log(`Key: ${key}`) | ||
} | ||
|
||
const toRefresh = [] | ||
for (const pr of prs) { | ||
if (cacheKeys.includes(`${{ runner.os }}-tugboat-preview-id-pr-${pr}`)) { | ||
console.log(`Need to refresh: ${pr}`) | ||
toRefresh.push(pr) | ||
} | ||
} | ||
|
||
const result = JSON.stringify(toRefresh) | ||
console.log(`Refresh Keys: ${result}`) | ||
return result | ||
result-encoding: string | ||
|
||
# Refresh cache for given keys | ||
refresh_cache: | ||
name: Refresh cache for given keys | ||
needs: [ collect_cache_keys ] | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
value: ${{fromJSON(needs.collect_cache_keys.outputs.matrix)}} | ||
steps: | ||
- name: Refresh Preview ID | ||
uses: actions/cache/restore@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 | ||
with: | ||
path: .tugboat_preview.txt | ||
key: ${{ runner.os }}-tugboat-preview-id-pr-${{ matrix.value }} | ||
- name: Cleanup temporary file | ||
run: rm .tugboat_preview.txt |
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.
Currently we use the rule that any non-
.md
file is a code change, which is probably the safest method for now.