Build #69670
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build | |
on: | |
push: | |
branches: | |
- main | |
pull_request: | |
types: | |
- opened | |
- synchronize | |
- reopened | |
- ready_for_review | |
merge_group: | |
workflow_dispatch: | |
inputs: | |
dryRun: | |
description: 'Dry-Run' | |
default: 'true' | |
required: false | |
permissions: | |
contents: read | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.number || github.ref }} | |
cancel-in-progress: ${{ github.ref_name != 'main' }} | |
env: | |
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} | |
NODE_VERSION: 22 | |
PDM_VERSION: 2.22.1 # renovate: datasource=pypi depName=pdm | |
DRY_RUN: true | |
TEST_LEGACY_DECRYPTION: true | |
SPARSE_CHECKOUT: |- | |
.github/actions/ | |
data/ | |
patches/ | |
tools/ | |
package.json | |
pnpm-lock.yaml | |
jobs: | |
setup: | |
runs-on: ubuntu-latest | |
outputs: | |
os-matrix: ${{ steps.os-matrix.outputs.os-matrix }} | |
os-matrix-is-full: ${{ steps.os-matrix-is-full.outputs.os-matrix-is-full }} | |
os-matrix-prefetch: ${{ steps.os-matrix-prefetch.outputs.matrix }} | |
test-shard-matrix: ${{ steps.schedule-test-shards.outputs.test-shard-matrix }} | |
test-matrix-empty: ${{ steps.schedule-test-shards.outputs.test-matrix-empty }} | |
steps: | |
- name: Calculate `os-matrix-is-full` output | |
id: os-matrix-is-full | |
env: | |
IS_FULL: >- | |
${{ | |
( | |
github.event_name != 'pull_request' || | |
contains(github.event.pull_request.labels.*.name, 'ci:fulltest') | |
) && 'true' || '' | |
}} | |
run: | | |
echo 'OS_MATRIX_IS_FULL=${{ env.IS_FULL }}' >> "$GITHUB_ENV" | |
echo 'os-matrix-is-full=${{ env.IS_FULL }}' >> "$GITHUB_OUTPUT" | |
- name: Calculate `os-matrix` output | |
id: os-matrix | |
env: | |
OS_ALL: '["ubuntu-latest", "macos-latest", "windows-latest"]' | |
OS_LINUX_ONLY: '["ubuntu-latest"]' | |
run: | | |
echo 'os-matrix=${{ | |
env.OS_MATRIX_IS_FULL && env.OS_ALL || env.OS_LINUX_ONLY | |
}}' >> "$GITHUB_OUTPUT" | |
- name: Detect changed files | |
if: ${{ github.event_name == 'pull_request' }} | |
id: changed-files | |
env: | |
GH_TOKEN: ${{ github.token }} | |
GH_REPO: ${{ github.event.repository.full_name }} | |
PR_URL: >- | |
https://api.github.com/repos/{owner}/{repo}/compare/${{ | |
github.event.pull_request.base.sha | |
}}...${{ | |
github.event.pull_request.head.sha | |
}} | |
JQ_FILTER: >- | |
"changed-files=" + ([.files[].filename] | tostring) | |
run: gh api ${{ env.PR_URL }} | jq -rc '${{ env.JQ_FILTER }}' >> "$GITHUB_OUTPUT" | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
filter: blob:none # we don't need all blobs | |
sparse-checkout: ${{ env.SPARSE_CHECKOUT }} | |
show-progress: false | |
- name: Calculate matrix for `node_modules` prefetch | |
uses: ./.github/actions/calculate-prefetch-matrix | |
id: os-matrix-prefetch | |
with: | |
repo: ${{ github.event.repository.full_name }} | |
token: ${{ github.token }} | |
node-version: ${{ env.NODE_VERSION }} | |
- name: Prefetch test modules for `ubuntu-latest` | |
id: setup-node | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
os: ${{ runner.os }} | |
save-cache: true | |
- name: Schedule test shards | |
id: schedule-test-shards | |
env: | |
ALL_PLATFORMS: ${{ env.OS_MATRIX_IS_FULL }} | |
FILTER_SHARDS: ${{ github.event.pull_request.draft && 'true' || '' }} | |
CHANGED_FILES: ${{ steps.changed-files.outputs.changed-files }} | |
run: | | |
echo "$(pnpm -s schedule-test-shards)" >> "$GITHUB_OUTPUT" | |
setup-build: | |
runs-on: ubuntu-latest | |
outputs: | |
node-version: ${{ env.NODE_VERSION }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
filter: blob:none # we don't need all blobs | |
sparse-checkout: ${{ env.SPARSE_CHECKOUT }} | |
show-progress: false | |
- name: Prefetch build modules for `ubuntu-latest` | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
os: ${{ runner.os }} | |
save-cache: true | |
prefetch: | |
needs: [setup] | |
# We can't check `needs.setup.outputs.os-matrix-is-full` here, | |
# as it will lead to further complications that aren't solvable | |
# with current GitHub Actions feature set. | |
# | |
# Although this job sometimes may act as short-lived `no-op`, | |
# it's actually the best option available. | |
# | |
# However, in draft mode we can skip this step. | |
if: | | |
!(github.event.pull_request.draft == true && | |
needs.setup.outputs.test-matrix-empty == 'true') | |
strategy: | |
matrix: | |
os: ${{ fromJSON(needs.setup.outputs.os-matrix-prefetch) }} | |
runs-on: ${{ matrix.os }} | |
timeout-minutes: 10 | |
steps: | |
- name: Checkout code | |
if: needs.setup.outputs.os-matrix-is-full && runner.os != 'Linux' | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
filter: blob:none # we don't need all blobs | |
sparse-checkout: ${{ env.SPARSE_CHECKOUT }} | |
show-progress: false | |
- name: Setup Node.js | |
if: needs.setup.outputs.os-matrix-is-full && runner.os != 'Linux' | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
os: ${{ runner.os }} | |
save-cache: true | |
lint-eslint: | |
needs: | |
- setup-build | |
runs-on: ubuntu-latest | |
timeout-minutes: 15 | |
permissions: | |
actions: write | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- name: Restore eslint cache | |
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 | |
with: | |
path: .cache/eslint | |
key: eslint-main-cache | |
- name: Lint | |
run: pnpm eslint-ci | |
- name: Remove cache | |
if: github.event_name == 'push' | |
env: | |
GH_TOKEN: ${{ github.token }} | |
GH_REPO: ${{ github.event.repository.full_name }} | |
run: | | |
gh api --method DELETE /repos/{owner}/{repo}/actions/caches?key=eslint-main-cache || | |
echo "Cache not found" | |
- name: Save eslint cache | |
if: github.event_name == 'push' | |
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 | |
with: | |
path: .cache/eslint | |
key: eslint-main-cache | |
lint-prettier: | |
needs: | |
- setup-build | |
runs-on: ubuntu-latest | |
timeout-minutes: 7 | |
permissions: | |
actions: write | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- name: Restore prettier cache | |
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 | |
with: | |
path: .cache/prettier | |
key: prettier-main-cache | |
- name: Lint | |
run: | | |
pnpm prettier --write --cache-location .cache/prettier | |
git diff --quiet || { | |
echo "[ERROR] Please apply the changes prettier suggests:" | |
git diff --color=always | |
exit 1 | |
} | |
- name: Remove cache | |
if: github.event_name == 'push' | |
env: | |
GH_TOKEN: ${{ github.token }} | |
GH_REPO: ${{ github.event.repository.full_name }} | |
run: | | |
gh api --method DELETE /repos/{owner}/{repo}/actions/caches?key=prettier-main-cache || | |
echo "Cache not found" | |
- name: Save prettier cache | |
if: github.event_name == 'push' | |
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 | |
with: | |
path: .cache/prettier | |
key: prettier-main-cache | |
lint-docs: | |
needs: | |
- setup-build | |
runs-on: ubuntu-latest | |
timeout-minutes: 7 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- name: Lint markdown | |
uses: DavidAnson/markdownlint-cli2-action@eb5ca3ab411449c66620fe7f1b3c9e10547144b0 # v18.0.0 | |
- name: Lint fenced code blocks | |
run: pnpm doc-fence-check | |
- name: Lint documentation | |
run: pnpm lint-documentation | |
- name: Markdown lint | |
run: pnpm markdown-lint | |
lint-other: | |
needs: | |
- setup-build | |
runs-on: ubuntu-latest | |
timeout-minutes: 7 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- name: Type check | |
run: pnpm type-check | |
- name: Lint project file structure | |
run: pnpm ls-lint | |
- name: Check git version | |
run: pnpm git-check | |
- name: Test schema | |
run: pnpm test-schema | |
test: | |
needs: [setup, prefetch] | |
if: | | |
!(github.event.pull_request.draft == true && | |
needs.setup.outputs.test-matrix-empty == 'true') | |
name: ${{ matrix.name }} | |
runs-on: ${{ matrix.os }} | |
timeout-minutes: ${{ matrix.runner-timeout-minutes }} | |
strategy: | |
matrix: | |
include: ${{ fromJSON(needs.setup.outputs.test-shard-matrix) }} | |
steps: | |
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
os: ${{ runner.os }} | |
- name: Cache jest | |
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 | |
with: | |
path: .cache/jest | |
key: | | |
jest-cache-${{ | |
runner.os | |
}}-${{ | |
env.NODE_VERSION | |
}}-${{ | |
hashFiles('pnpm-lock.yaml') | |
}}-${{ | |
matrix.cache-key | |
}} | |
- name: Unit tests | |
shell: bash | |
run: | | |
for shard in ${{ matrix.shards }}; | |
do | |
TEST_SHARD="$shard" pnpm jest \ | |
--ci \ | |
--test-timeout ${{ matrix.test-timeout-milliseconds }} \ | |
--coverage ${{ matrix.coverage }} | |
done | |
- name: Move coverage files | |
if: (success() || failure()) && github.event.pull_request.draft != true && matrix.coverage | |
run: | | |
mkdir -p ./coverage/lcov | |
mkdir -p ./coverage/json | |
for shard in ${{ matrix.shards }}; | |
do | |
mv ./coverage/shard/$shard/lcov.info ./coverage/lcov/$shard.lcov | |
mv ./coverage/shard/$shard/coverage-final.json ./coverage/json/$shard.json | |
done | |
- name: Save coverage artifacts | |
if: (success() || failure()) && github.event.pull_request.draft != true && matrix.coverage | |
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 | |
with: | |
name: ${{ matrix.upload-artifact-name }} | |
path: | | |
./coverage/lcov | |
./coverage/json | |
codecov: | |
needs: [test] | |
runs-on: ubuntu-latest | |
timeout-minutes: 3 | |
if: (success() || failure()) && github.event_name != 'merge_group' && github.event.pull_request.draft != true | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
filter: blob:none # we don't need all blobs | |
show-progress: false | |
- name: Download coverage reports | |
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
pattern: coverage-* | |
path: coverage | |
merge-multiple: true | |
- name: Codecov | |
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 | |
with: | |
token: ${{ secrets.CODECOV_TOKEN }} | |
directory: coverage/lcov | |
fail_ci_if_error: github.event_name != 'pull_request' | |
verbose: true | |
coverage-threshold: | |
needs: | |
- test | |
- setup-build | |
runs-on: ubuntu-latest | |
timeout-minutes: 3 | |
if: (success() || failure()) && github.event.pull_request.draft != true | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
filter: blob:none # we don't need all blobs | |
sparse-checkout: ${{ env.SPARSE_CHECKOUT }} | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- name: Download coverage reports | |
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
pattern: coverage-* | |
path: coverage | |
merge-multiple: true | |
- name: Merge coverage reports | |
run: pnpm nyc merge ./coverage/json ./coverage/nyc/coverage.json | |
- name: Report coverage | |
run: pnpm nyc report -t ./coverage/nyc --skip-full -r text -r text-summary | |
- name: Check coverage threshold | |
run: | | |
pnpm nyc check-coverage -t ./coverage/nyc \ | |
--branches 100 \ | |
--functions 100 \ | |
--lines 100 \ | |
--statements 100 | |
# Catch-all required check for test matrix and coverage | |
test-success: | |
needs: | |
- setup | |
- test | |
- codecov | |
- coverage-threshold | |
runs-on: ubuntu-latest | |
timeout-minutes: 1 | |
if: always() | |
steps: | |
- name: Fail for failed or cancelled tests | |
if: | | |
needs.test.result == 'failure' || | |
needs.test.result == 'cancelled' | |
run: exit 1 | |
- name: Fail for skipped tests when PR is ready for review | |
if: | | |
github.event_name == 'pull_request' && | |
github.event.pull_request.draft != true && | |
needs.test.result == 'skipped' | |
run: exit 1 | |
- name: Fail for failed or cancelled codecov | |
if: | | |
needs.codecov.result == 'failure' || | |
needs.codecov.result == 'cancelled' | |
run: exit 1 | |
- name: Fail for skipped codecov when PR is ready for review | |
if: | | |
github.event_name == 'pull_request' && | |
github.event.pull_request.draft != true && | |
needs.codecov.result == 'skipped' | |
run: exit 1 | |
- name: Fail for failed or cancelled coverage-threshold | |
if: | | |
needs.coverage-threshold.result == 'failure' || | |
needs.coverage-threshold.result == 'cancelled' | |
run: exit 1 | |
- name: Fail for skipped coverage-threshold when PR is ready for review | |
if: | | |
github.event_name == 'pull_request' && | |
github.event.pull_request.draft != true && | |
needs.coverage-threshold.result == 'skipped' | |
run: exit 1 | |
build: | |
needs: | |
- setup-build | |
runs-on: ubuntu-latest | |
timeout-minutes: 15 | |
if: github.event.pull_request.draft != true | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- name: Build | |
run: pnpm build | |
- name: Build docker | |
run: pnpm build:docker build --tries=3 | |
env: | |
LOG_LEVEL: debug | |
- name: Pack | |
run: pnpm test-e2e:pack | |
- name: Upload | |
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 | |
with: | |
name: renovate-package | |
path: renovate-0.0.0-semantic-release.tgz | |
build-docs: | |
needs: | |
- lint-docs | |
- setup-build | |
runs-on: ubuntu-latest | |
timeout-minutes: 5 | |
if: github.event.pull_request.draft != true | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- name: Setup PDM | |
uses: pdm-project/setup-pdm@b2472ca4258a9ea3aee813980a0100a2261a42fc # v4.2 | |
with: | |
python-version-file: .python-version | |
version: ${{ env.PDM_VERSION }} | |
cache: true | |
- name: Install pdm dependencies | |
run: pdm install | |
- name: Build | |
run: pnpm build:docs | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
SKIP_GITHUB_ISSUES: ${{ (github.event_name == 'pull_request' || github.event_name == 'merge_group') && 'true' || '' }} | |
- name: Test docs | |
run: pnpm test:docs | |
- name: Upload | |
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 | |
with: | |
name: docs | |
path: tmp/docs/ | |
- name: Build mkdocs | |
run: pnpm mkdocs build --no-build | |
test-e2e: | |
needs: [build] | |
runs-on: 'ubuntu-latest' | |
timeout-minutes: 7 | |
if: github.event.pull_request.draft != true | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
show-progress: false | |
- name: Setup pnpm | |
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 | |
with: | |
standalone: true | |
- name: Setup Node.js | |
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 | |
with: | |
node-version: ${{ env.NODE_VERSION }} | |
- name: Download package | |
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: renovate-package | |
- name: Install dependencies | |
run: pnpm test-e2e:install | |
- name: E2E Test | |
run: pnpm test-e2e:run | |
release: | |
needs: | |
- setup-build | |
- lint-eslint | |
- lint-prettier | |
- lint-docs | |
- lint-other | |
- test-e2e | |
- test-success | |
- build-docs | |
- codecov | |
- coverage-threshold | |
if: github.repository == 'renovatebot/renovate' && github.event_name != 'pull_request' | |
runs-on: ubuntu-latest | |
timeout-minutes: 60 | |
permissions: | |
contents: write | |
issues: write | |
pull-requests: write | |
id-token: write | |
packages: write | |
steps: | |
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
fetch-depth: 0 # zero stands for full checkout, which is required for semantic-release | |
filter: blob:none # we don't need all blobs, only the full tree | |
show-progress: false | |
- name: docker-config | |
uses: containerbase/internal-tools@081e077becfd4a1a5f6c45271583b857e88bdbb4 # v3.5.14 | |
with: | |
command: docker-config | |
- name: Setup Node.js | |
uses: ./.github/actions/setup-node | |
with: | |
node-version: ${{ needs.setup-build.outputs.node-version }} | |
os: ${{ runner.os }} | |
- uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 | |
- name: Docker registry login | |
run: | | |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin | |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin | |
- name: Check dry run | |
run: | | |
if [[ "${{github.event_name}}" == "workflow_dispatch" && "${{ github.event.inputs.dryRun }}" != "true" ]]; then | |
echo "DRY_RUN=false" >> "$GITHUB_ENV" | |
elif [[ "${{github.ref}}" == "refs/heads/${{env.DEFAULT_BRANCH}}" ]]; then | |
echo "DRY_RUN=false" >> "$GITHUB_ENV" | |
elif [[ "${{github.ref}}" =~ ^refs/heads/v[0-9]+(\.[0-9]+)?$ ]]; then | |
echo "DRY_RUN=false" >> "$GITHUB_ENV" | |
fi | |
- name: semantic-release | |
run: | | |
pnpm semantic-release --dry-run ${{env.DRY_RUN}} | |
env: | |
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} # TODO: use action token? | |
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
LOG_LEVEL: debug |