Skip to content

Set up maintenance to automatically track main #7320

Set up maintenance to automatically track main

Set up maintenance to automatically track main #7320

Workflow file for this run

---
name: Checks
on: # yamllint disable-line rule:truthy
push:
branches:
- main
pull_request_target:
types:
- opened
- synchronize
merge_group:
env:
node_version: 23
jobs:
typecheck:
# Can run untrusted code so disable all permissions.
permissions: {}
name: Type Check Code Base
runs-on: ubuntu-latest
steps:
# This pattern is reused a couple of times.
# It's so verbose because of `pull_request_target`.
# For security reasons by deafult it won't check out the branch the PR is coming from.
- name: Checkout Branch
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.head_ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 1
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.node_version }}
- name: Cache Node.js modules
uses: actions/cache@v4
with:
path: .npm
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-node-
${{ runner.OS }}-
- run: npm ci --cache .npm --prefer-offline
- name: Type Check
run: npm run typecheck
lint:
# Can run untrusted code so disable all permissions.
permissions: {}
name: Lint Code Base
runs-on: ubuntu-latest
steps:
- name: Checkout Branch
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.head_ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 1
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.node_version }}
- name: Cache Node.js modules
uses: actions/cache@v4
with:
path: .npm
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-node-
${{ runner.OS }}-
- run: npm ci --cache .npm --prefer-offline
- name: Run Lints
run: npm run lint:ci
test:
# Can run untrusted code so disable all permissions.
permissions: {}
name: Test Code Base
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Checkout Branch
uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.head_ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 1
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.node_version }}
- name: Cache Node.js modules
uses: actions/cache@v4
with:
path: .npm
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-node-
${{ runner.OS }}-
- run: npm ci --cache .npm --prefer-offline
- name: Execute Tests
run: npm test -- --run --reporter github-actions --reporter=./.github/workflows/testsReporter.ts
- name: Upload Main Test Results
if: always() && github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: actions/upload-artifact@v4
with:
name: main-test-results
path: test-results/vitest-report.json
- name: Upload Test Results
if: always() && github.event_name == 'pull_request_target' && github.head_ref != 'refs/heads/main'
uses: actions/upload-artifact@v4
with:
name: pr-test-results
path: test-results/vitest-report.json
checkCanMergeToMaintenance:
# Can run untrusted code so disable all permissions.
permissions: {}
name: Check Merge to Maintenance
if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event.pull_request
outputs:
should_skip: ${{ steps.should_skip.outputs.should_skip }}
runs-on: ubuntu-latest
steps:
- uses: 8BitJonny/[email protected]
if: github.event.pull_request == null
id: PR
# Sets should_skip if this change wasn't made through a PR or if the PR is labeled as breaking.
- name: Check if should skip
id: should_skip
if: contains(github.event.pull_request.labels.*.name, 'breaking') || steps.PR.outputs.pr_found == 'false' || contains(steps.PR.outputs.pr_labels.*.name, 'breaking')
run: |
echo "Skipping the rest of the job because this change wasn't made through a PR or the PR is labeled as breaking."
echo "${{ toJSON(fromJSON(steps.PR.outputs.pr)) }}"
echo "should_skip=true" >> "$GITHUB_OUTPUT"
- name: Get fetch depth
id: fetch_depth
if: steps.should_skip.outputs.should_skip != 'true'
env:
GITHUB_EVENT_COMMITS: ${{ toJSON(github.event.commits) }}
run: |
if [[ $GITHUB_EVENT_COMMITS == "null" ]]; then
# There simply isn't enough information to do anything but completely unshallow the repo.
echo "fetch_depth=0" >> "$GITHUB_OUTPUT"
exit 0
fi
commitCount=$(jq length <<< "$GITHUB_EVENT_COMMITS")
echo "fetch_depth=$(( commitCount + 1 ))" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v4
if: steps.should_skip.outputs.should_skip != 'true'
with:
ref: ${{ github.head_ref || github.ref }}
fetch-depth: ${{ steps.fetch_depth.outputs.fetch_depth }}
- name: Check for merge conflicts
if: steps.should_skip.outputs.should_skip != 'true'
run: |
git remote add upstream https://github.com/${{ github.repository }}
git fetch --no-tags upstream main maintenance
# This is its own command so that if the current branch is `maintenance` it'll be overridden.
# If it wasn't, instead it could cause failure.
git checkout -B maintenance upstream/maintenance
baseRef="${{github.head_ref}}"
before=""
if [[ $baseRef != "" ]]; then
before=$(git merge-base upstream/main "$baseRef")
else
before="${{ github.event.before }}"
fi
git cherry-pick --allow-empty --no-commit -m 1 "$before".."${{ github.sha }}" || (
echo "Merge conflicts detected with the maintenance branch!" && exit 1
)
- name: Install Node
if: steps.should_skip.outputs.should_skip != 'true'
uses: actions/setup-node@v4
with:
node-version: ${{ env.node_version }}
- name: Cache Node.js modules
if: steps.should_skip.outputs.should_skip != 'true'
uses: actions/cache@v4
with:
path: .npm
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.OS }}-node-
${{ runner.OS }}-
- if: steps.should_skip.outputs.should_skip != 'true'
run: npm ci --cache .npm --prefer-offline
- name: Run Lints on maintenance
if: steps.should_skip.outputs.should_skip != 'true'
run: npm run lint:ci
- name: Type Check maintenance
if: steps.should_skip.outputs.should_skip != 'true'
run: npm run typecheck
mergeToMaintenance:
name: Merge To Maintenance
needs: [checkCanMergeToMaintenance]
if: needs.checkCanMergeToMaintenance.outputs.should_skip != 'true'
runs-on: ubuntu-latest
steps:
- name: Get fetch depth
id: fetch_depth
env:
GITHUB_EVENT_COMMITS: ${{ toJSON(github.event.commits) }}
run: |
commitCount=$(jq length <<< "$GITHUB_EVENT_COMMITS")
echo "fetch_depth=$(( commitCount + 1 ))" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v4
with:
fetch-depth: ${{ steps.fetch_depth.outputs.fetch_depth }}
- name: Cherry pick commits onto maintenance
run: |
git fetch origin maintenance:maintenance
git switch maintenance
# Commit using the GitHub Actions bot user.
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Pick the freshly added commits onto the maintenance branch.
git cherry-pick --allow-empty -m 1 "${{ github.event.before }}".."${{ github.event.after }}" || (
echo "Merge conflicts detected with maintenance branch! This can only happen if checkCanMergeToMaintenance is written incorrectly or someone pushed in between!" && exit 1
)
- name: Push changes
uses: ad-m/github-push-action@master
with:
branch: maintenance
github_token: ${{ secrets.GITHUB_TOKEN }}
reportTestResults:
name: Report Test Results
needs: [test]
runs-on: ubuntu-latest
if: github.event_name == 'pull_request_target' || (github.event_name == 'push' && github.event.pull_request != null)
steps:
# This must check out main.
# If it didn't someone could edit `postOrUpdateTestsReport.js` to easily run arbitrary code.
- uses: actions/checkout@v4
with:
ref: refs/heads/main
fetch-depth: 1
- name: Download Main Test Results
uses: dawidd6/action-download-artifact@v7
with:
branch: main
name: main-test-results
path: main-test-results
- name: Download Test Results
uses: actions/download-artifact@v4
with:
name: pr-test-results
path: pr-test-results
- name: Post or Update Report
uses: actions/github-script@v7
with:
script: |
const { default: postOrUpdateTestsReport } = await import("/home/runner/work/foundry-vtt-types/foundry-vtt-types/.github/workflows/postOrUpdateTestsReport.js");
await postOrUpdateTestsReport({ github, context, core });
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}