mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-27 07:50:47 +00:00
fd6f04874c
chore(deps): update dependency astral-sh/uv to v0.12.18 | datasource | package | from | to | | --------------- | ------------ | ------- | ------- | | github-releases | astral-sh/uv | 0.12.17 | 0.12.18 | Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1050 lines
34 KiB
YAML
1050 lines
34 KiB
YAML
name: Build
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- next
|
|
- maint/**
|
|
|
|
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.event_name == 'pull_request' || github.event_name == 'merge_group' }}
|
|
|
|
env:
|
|
# are we on a release branch?
|
|
DO_RELEASE: ${{ github.ref_name == github.event.repository.default_branch || github.ref_name == 'next' || startsWith(github.ref_name, 'maint/')}}
|
|
NODE_VERSION: 24
|
|
DRY_RUN: true
|
|
SPARSE_CHECKOUT: |-
|
|
.github/actions/
|
|
data/
|
|
patches/
|
|
tools/
|
|
package.json
|
|
pnpm-workspace.yaml
|
|
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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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: |
|
|
pnpm -s --config.verify-deps-before-run=false schedule-test-shards >> "$GITHUB_OUTPUT"
|
|
|
|
setup-build:
|
|
runs-on: ubuntu-latest
|
|
|
|
outputs:
|
|
node-version: ${{ steps.setup-outputs.outputs.node-version }}
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
filter: blob:none # we don't need all blobs
|
|
sparse-checkout: ${{ env.SPARSE_CHECKOUT }}
|
|
show-progress: false
|
|
|
|
- name: Setup outputs
|
|
id: setup-outputs
|
|
run: |
|
|
echo "node-version=${{ env.NODE_VERSION }}" >> "$GITHUB_OUTPUT"
|
|
|
|
- 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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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-oxlint:
|
|
needs:
|
|
- setup-build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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 with oxlint
|
|
run: pnpm oxlint -f github
|
|
|
|
- name: Lint with biome
|
|
run: pnpm biome-ci
|
|
|
|
lint-prettier:
|
|
needs:
|
|
- setup-build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 7
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: .cache/prettier
|
|
# we need to add the hash because prettier cache doesn't detect plugin changes
|
|
key: prettier-cache-${{ hashFiles('pnpm-lock.yaml', 'package.json') }}
|
|
restore-keys: prettier-cache-${{ hashFiles('pnpm-lock.yaml', 'package.json') }}-
|
|
|
|
- name: Lint
|
|
run: |
|
|
pnpm prettier-fix --cache-location .cache/prettier
|
|
git diff --quiet || {
|
|
echo "[ERROR] Please apply the changes prettier suggests:"
|
|
git diff --color=always
|
|
exit 1
|
|
}
|
|
|
|
- name: Save prettier cache
|
|
if: github.event_name == 'push'
|
|
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: .cache/prettier
|
|
key: prettier-cache-${{ hashFiles('pnpm-lock.yaml', 'package.json') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
|
|
|
lint-docs:
|
|
needs:
|
|
- setup-build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 7
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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
|
|
run: pnpm markdown-lint
|
|
|
|
- name: Generate JSON schema
|
|
run: pnpm create-json-schema
|
|
|
|
- name: Lint fenced code blocks
|
|
run: pnpm doc-fence-check
|
|
|
|
- name: Lint documentation
|
|
run: pnpm lint-documentation
|
|
|
|
lint-other:
|
|
needs:
|
|
- setup-build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 7
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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 tsbuildinfo cache
|
|
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: .cache/tsbuildinfo
|
|
key: tsbuildinfo-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: |
|
|
tsbuildinfo-${{ hashFiles('pnpm-lock.yaml') }}-
|
|
tsbuildinfo-
|
|
|
|
- name: Type check
|
|
run: pnpm type-check
|
|
|
|
- name: Save tsbuildinfo cache
|
|
if: github.event_name == 'push'
|
|
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: .cache/tsbuildinfo
|
|
key: tsbuildinfo-${{ hashFiles('pnpm-lock.yaml') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
|
|
|
- name: Lint project file structure
|
|
run: pnpm ls-lint
|
|
|
|
- name: Check git version
|
|
run: pnpm git-check
|
|
|
|
- name: Test schema
|
|
run: pnpm test-schema
|
|
|
|
- name: Lint other
|
|
run: pnpm lint-other
|
|
|
|
lint-actions:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 7
|
|
permissions:
|
|
security-events: write
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
show-progress: false
|
|
# include local composite actions, so that actionlint validates
|
|
# their metadata, and zizmor audits them
|
|
sparse-checkout: .github/
|
|
|
|
- name: Check workflow files
|
|
uses: docker://rhysd/actionlint:1.7.12@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667
|
|
with:
|
|
args: -color -ignore "invalid activity type \"destroyed\" for \"merge_group\" Webhook event. available types are \"checks_requested\""
|
|
|
|
- name: Run zizmor
|
|
uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4
|
|
with:
|
|
version: 1.30.1
|
|
|
|
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 }}
|
|
|
|
permissions:
|
|
id-token: write # required for codecov OIDC
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include: ${{ fromJSON(needs.setup.outputs.test-shard-matrix) }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
show-progress: false
|
|
|
|
- name: Setup Node.js
|
|
uses: ./.github/actions/setup-node
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
os: ${{ runner.os }}
|
|
|
|
- name: Cache vitest
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: .cache/vitest
|
|
# the shard cache key comes before the lockfile hash so that
|
|
# `restore-keys` can fall back to the same shard's cache after
|
|
# a lockfile change
|
|
key: |
|
|
vitest-cache-${{
|
|
runner.os
|
|
}}-${{
|
|
env.NODE_VERSION
|
|
}}-${{
|
|
matrix.cache-key
|
|
}}-${{
|
|
hashFiles('pnpm-lock.yaml')
|
|
}}
|
|
restore-keys: |
|
|
vitest-cache-${{
|
|
runner.os
|
|
}}-${{
|
|
env.NODE_VERSION
|
|
}}-${{
|
|
matrix.cache-key
|
|
}}-
|
|
|
|
- name: Unit tests
|
|
shell: bash
|
|
run: |
|
|
for shard in ${{ matrix.shards }};
|
|
do
|
|
TEST_SHARD="$shard" pnpm vitest \
|
|
--test-timeout ${{ matrix.test-timeout-milliseconds }} \
|
|
--coverage ${{ matrix.coverage }}
|
|
done
|
|
|
|
- name: Codecov Test
|
|
if: github.event_name != 'merge_group' && !cancelled()
|
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
|
with:
|
|
use_oidc: true
|
|
report_type: test_results
|
|
directory: ./coverage/shard
|
|
# TODO: compute proper flags per job
|
|
# flags: ${{ matrix.name }}
|
|
verbose: true
|
|
|
|
- name: Move coverage files
|
|
if: success() && 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() && github.event.pull_request.draft != true && matrix.coverage
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: ${{ matrix.upload-artifact-name }}
|
|
path: |
|
|
./coverage/lcov
|
|
./coverage/json
|
|
|
|
codecov:
|
|
needs: [test]
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 3
|
|
if: success() && github.event_name != 'merge_group' && github.event.pull_request.draft != true
|
|
permissions:
|
|
id-token: write # required for codecov OIDC
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
filter: blob:none # we don't need all blobs
|
|
show-progress: false
|
|
|
|
- name: Download coverage reports
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
pattern: coverage-*
|
|
path: coverage
|
|
merge-multiple: true
|
|
|
|
- name: Codecov Coverage
|
|
if: github.event_name != 'merge_group'
|
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
|
with:
|
|
use_oidc: true
|
|
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() && github.event.pull_request.draft != true
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
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 \
|
|
--statements 100 \
|
|
--branches 100 \
|
|
--functions 100 \
|
|
--lines 100 \
|
|
|
|
# Catch-all required check for test matrix and coverage
|
|
test-success:
|
|
needs:
|
|
- setup
|
|
- test
|
|
- codecov
|
|
- coverage-threshold
|
|
- lint-actions
|
|
- lint-docs
|
|
- lint-other
|
|
- lint-oxlint
|
|
- lint-prettier
|
|
- build-docker
|
|
- build-docs
|
|
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
|
|
|
|
- name: Fail for failed or cancelled Actions linting
|
|
if: |
|
|
needs.lint-actions.result == 'failure' ||
|
|
needs.lint-actions.result == 'cancelled'
|
|
run: exit 1
|
|
|
|
- name: Fail for skipped Actions linting when PR is ready for review
|
|
if: |
|
|
github.event_name == 'pull_request' &&
|
|
github.event.pull_request.draft != true &&
|
|
needs.lint-actions.result == 'skipped'
|
|
run: exit 1
|
|
|
|
- name: Fail for failed or cancelled linting
|
|
if: |
|
|
needs.lint-docs.result == 'failure' ||
|
|
needs.lint-docs.result == 'cancelled' ||
|
|
needs.lint-other.result == 'failure' ||
|
|
needs.lint-other.result == 'cancelled' ||
|
|
needs.lint-oxlint.result == 'failure' ||
|
|
needs.lint-oxlint.result == 'cancelled' ||
|
|
needs.lint-prettier.result == 'failure' ||
|
|
needs.lint-prettier.result == 'cancelled'
|
|
run: exit 1
|
|
|
|
- name: Fail for skipped linting when PR is ready for review
|
|
if: |
|
|
github.event_name == 'pull_request' &&
|
|
github.event.pull_request.draft != true &&
|
|
(
|
|
needs.lint-docs.result == 'skipped' ||
|
|
needs.lint-other.result == 'skipped' ||
|
|
needs.lint-oxlint.result == 'skipped' ||
|
|
needs.lint-prettier.result == 'skipped'
|
|
)
|
|
run: exit 1
|
|
|
|
- name: Fail for failed or cancelled docs build
|
|
if: |
|
|
needs.build-docs.result == 'failure' ||
|
|
needs.build-docs.result == 'cancelled'
|
|
run: exit 1
|
|
|
|
- name: Fail for skipped docs build when PR is ready for review
|
|
if: |
|
|
github.event_name == 'pull_request' &&
|
|
github.event.pull_request.draft != true &&
|
|
needs.build-docs.result == 'skipped'
|
|
run: exit 1
|
|
|
|
- name: Fail for skipped or failed docker build when needed
|
|
if: |
|
|
(
|
|
github.event_name != 'pull_request' ||
|
|
(github.event.pull_request.draft != true && contains(github.event.pull_request.labels.*.name, 'ci:fulltest'))
|
|
) &&
|
|
(needs.build-docker.result == 'skipped' || needs.build-docker.result == 'failure')
|
|
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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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: Upload dist
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: renovate-dist
|
|
path: dist/
|
|
|
|
build-docker:
|
|
needs:
|
|
- setup-build # we need the outputs
|
|
- build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
if: github.event_name != 'pull_request' || (github.event.pull_request.draft != true && contains(github.event.pull_request.labels.*.name, 'ci:fulltest'))
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
show-progress: false
|
|
|
|
- name: Setup Docker
|
|
uses: ./.github/actions/setup-docker
|
|
|
|
- name: Download dist
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: renovate-dist
|
|
path: dist/
|
|
|
|
- name: Setup Node.js
|
|
uses: ./.github/actions/setup-node
|
|
with:
|
|
node-version: ${{ needs.setup-build.outputs.node-version }}
|
|
os: ${{ runner.os }}
|
|
|
|
- name: Build docker
|
|
run: pnpm build:docker build --platform linux/amd64,linux/arm64 --tries=3 --args '--load'
|
|
env:
|
|
LOG_LEVEL: debug
|
|
|
|
- name: Test docker
|
|
run: docker run -e LOG_LEVEL=debug --rm renovate/renovate --version
|
|
|
|
- name: dry-run
|
|
if: github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && env.DO_RELEASE != 'true')
|
|
run: docker run -e LOG_LEVEL=debug -e RENOVATE_TOKEN --rm renovate/renovate --dry-run=lookup ${{ github.repository }}
|
|
env:
|
|
RENOVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- run: df -h
|
|
if: ${{ !cancelled() }}
|
|
|
|
build-docs:
|
|
needs:
|
|
- setup-build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
if: github.event.pull_request.draft != true
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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 uv
|
|
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
with:
|
|
version: 0.12.18
|
|
enable-cache: true
|
|
cache-python: true
|
|
|
|
- name: Install uv dependencies
|
|
run: uv sync --locked
|
|
|
|
- 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' || github.event.repository.has_issues == false) && 'true' || '' }}
|
|
|
|
- name: Test docs
|
|
run: pnpm test:docs
|
|
|
|
- name: Upload
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: docs
|
|
path: tmp/docs/
|
|
|
|
- name: Build mkdocs
|
|
run: pnpm mkdocs build --no-build
|
|
|
|
test-e2e:
|
|
needs:
|
|
- setup-build
|
|
- build
|
|
runs-on: 'ubuntu-latest'
|
|
timeout-minutes: 7
|
|
|
|
if: github.event.pull_request.draft != true
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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 dist
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: renovate-dist
|
|
path: dist/
|
|
|
|
- name: Pack
|
|
run: pnpm test-e2e:pack
|
|
|
|
- name: Install dependencies
|
|
run: pnpm test-e2e:install
|
|
|
|
- name: E2E Test
|
|
run: pnpm test-e2e:run
|
|
|
|
release:
|
|
needs:
|
|
- setup-build
|
|
- build-docker
|
|
- lint-oxlint
|
|
- 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
|
|
concurrency:
|
|
group: ${{ github.workflow }}-release-${{ github.ref }}
|
|
# never cancel a release that has already started, as it may have started pushing artifacts
|
|
cancel-in-progress: false
|
|
permissions:
|
|
actions: write
|
|
contents: write
|
|
issues: write
|
|
pull-requests: write
|
|
id-token: write
|
|
packages: write
|
|
|
|
steps:
|
|
# right at the start of the job, make sure we're not seeing another commit that's landed
|
|
- name: Check for newer commits
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GH_REPO: renovatebot/renovate
|
|
REF_NAME: ${{ github.ref_name }}
|
|
EXPECTED_SHA: ${{ github.sha }}
|
|
RUN_ID: ${{ github.run_id }}
|
|
run: |
|
|
latest_sha=$(git ls-remote https://github.com/renovatebot/renovate "refs/heads/$REF_NAME" | cut -f1)
|
|
if [[ "$latest_sha" != "$EXPECTED_SHA" ]]; then
|
|
echo "Newer commit detected on $REF_NAME ($latest_sha), cancelling release run"
|
|
gh run cancel "$RUN_ID"
|
|
sleep 5
|
|
fi
|
|
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
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: Setup Docker
|
|
uses: ./.github/actions/setup-docker
|
|
|
|
- name: Setup Node.js
|
|
uses: ./.github/actions/setup-node
|
|
with:
|
|
node-version: ${{ needs.setup-build.outputs.node-version }}
|
|
os: ${{ runner.os }}
|
|
# ensure that the release job installs fresh, with installed pacakges verified against the lockfile's integrity hashes
|
|
use-cache: false
|
|
|
|
- name: Install newer npm if needed
|
|
run: 'dpkg --compare-versions "$(npm -v)" lt 11.5.1 && (npm update -g npm; echo "updated npm to: $(npm -v)") || echo "npm is new enough: $(npm -v)"'
|
|
|
|
- uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
|
|
|
- name: Docker registry login
|
|
env:
|
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
REPOSITORY_OWNER: ${{ github.repository_owner }}
|
|
run: |
|
|
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
|
|
echo "$GITHUB_TOKEN" | docker login ghcr.io -u "$REPOSITORY_OWNER" --password-stdin
|
|
|
|
- name: Setup uv
|
|
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
with:
|
|
version: 0.12.18
|
|
# ensure that the release job installs fresh, with installed pacakges verified against the lockfile's integrity hashes
|
|
enable-cache: false
|
|
cache-python: true
|
|
|
|
- name: Install uv dependencies
|
|
run: uv sync --locked
|
|
|
|
- name: Check dry run
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
INPUT_DRY_RUN: ${{ github.event.inputs.dryRun }}
|
|
run: |
|
|
if [[ "$EVENT_NAME" == "workflow_dispatch" && "$INPUT_DRY_RUN" != "true" ]]; then
|
|
echo "DRY_RUN=false" >> "$GITHUB_ENV"
|
|
elif [[ "$DO_RELEASE" == "true" ]]; then
|
|
echo "DRY_RUN=false" >> "$GITHUB_ENV"
|
|
fi
|
|
|
|
# and one final check, in case preparing the environment has taken long enough for new commits
|
|
- name: Check for newer commits
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
REF_NAME: ${{ github.ref_name }}
|
|
EXPECTED_SHA: ${{ github.sha }}
|
|
RUN_ID: ${{ github.run_id }}
|
|
run: |
|
|
latest_sha=$(git ls-remote https://github.com/renovatebot/renovate "refs/heads/$REF_NAME" | cut -f1)
|
|
if [[ "$latest_sha" != "$EXPECTED_SHA" ]]; then
|
|
echo "Newer commit detected on $REF_NAME ($latest_sha), cancelling release run"
|
|
gh run cancel "$RUN_ID"
|
|
sleep 5
|
|
fi
|
|
|
|
- name: semantic-release
|
|
run: |
|
|
pnpm semantic-release --dry-run "$DRY_RUN"
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
LOG_LEVEL: debug
|
|
|
|
- name: Build mkdocs site for deployment
|
|
if: github.ref_name == 'main'
|
|
run: |
|
|
# Always rebuild the docs site with the announcement bar for deployment to GitHub Pages, including the announcement bar (which isn't included when preparing a release's docs)
|
|
latest_tag=$(gh release view --json tagName -q .tagName)
|
|
pnpm mkdocs build --version "$latest_tag"
|
|
mkdir -p tmp
|
|
tar -czf tmp/mkdocs-site.tgz -C tools/mkdocs/site .
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
MKDOCS_INCLUDE_ANNOUNCEMENT: 'true'
|
|
|
|
- name: Upload docs artifact for deployment
|
|
if: github.ref_name == 'main'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: mkdocs-site
|
|
path: tmp/mkdocs-site.tgz
|
|
retention-days: 1
|
|
|
|
- run: df -h
|
|
if: ${{ !cancelled() }}
|
|
|
|
deploy-docs-site:
|
|
if: ${{ github.repository == 'renovatebot/renovate' && github.ref_name == 'main' && github.event_name == 'push' }}
|
|
needs:
|
|
- setup-build
|
|
- release
|
|
|
|
permissions:
|
|
pages: write
|
|
id-token: write
|
|
|
|
environment:
|
|
name: github-pages
|
|
url: ${{ steps.deployment.outputs.page_url }}
|
|
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Download mkdocs site from release
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: mkdocs-site
|
|
path: tmp
|
|
|
|
- name: Extract docs site
|
|
run: |
|
|
mkdir -p tools/mkdocs/site
|
|
tar -xzf tmp/mkdocs-site.tgz -C tools/mkdocs/site
|
|
|
|
# Per https://github.com/renovatebot/helm-charts/issues/3752, when we migrated the docs site from renovatebot/renovatebot.github.io to renovatebot/renovate, the `/helm-charts/` repository would no longer work as a subdomain, due to a known GitHub Pages limitation
|
|
- name: Mirror helm-charts/index.yaml from helm-charts' GitHub Pages site
|
|
run: |
|
|
mkdir tools/mkdocs/site/helm-charts
|
|
curl --retry 5 --silent https://renovatebot.github.io/helm-charts/index.yaml -o tools/mkdocs/site/helm-charts/index.yaml
|
|
|
|
- name: Upload GitHub Pages artifact
|
|
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
|
|
with:
|
|
path: tools/mkdocs/site
|
|
|
|
- name: Deploy to GitHub Pages
|
|
id: deployment
|
|
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
|
|
|
|
notify-release-failure:
|
|
runs-on: ubuntu-latest
|
|
if: ${{ always() && (github.repository == 'renovatebot/renovate' && github.ref_name == 'main' && github.event_name == 'push') && (needs.release.result == 'failure' || needs.release.result == 'timed_out') }}
|
|
needs:
|
|
- release
|
|
steps:
|
|
- name: Post to Slack
|
|
id: slack
|
|
uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0
|
|
with:
|
|
webhook: ${{ secrets.RENOVATEBOT_SLACK_WEBHOOK_MAIN_FAILURES }}
|
|
webhook-type: incoming-webhook
|
|
payload: |
|
|
text: "*Release from `main` failed*:\nAction Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\nCommit: ${{ github.event.head_commit.url }}"
|
|
blocks:
|
|
- type: "section"
|
|
text:
|
|
type: "mrkdwn"
|
|
text: "*Release from `main` failed*:\nAction Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\nCommit: ${{ github.event.head_commit.url }}"
|
|
|
|
notify-docs-failure:
|
|
runs-on: ubuntu-latest
|
|
if: ${{ always() && (github.repository == 'renovatebot/renovate' && github.ref_name == 'main' && github.event_name == 'push') && (needs.deploy-docs-site.result == 'failure' || needs.deploy-docs-site.result == 'timed_out') }}
|
|
needs:
|
|
- deploy-docs-site
|
|
steps:
|
|
- name: Post to Slack
|
|
id: slack
|
|
uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0
|
|
with:
|
|
webhook: ${{ secrets.RENOVATEBOT_SLACK_WEBHOOK_MAIN_FAILURES }}
|
|
webhook-type: incoming-webhook
|
|
payload: |
|
|
text: "*Docs build from `main` failed*:\nAction Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\nCommit: ${{ github.event.head_commit.url }}"
|
|
blocks:
|
|
- type: "section"
|
|
text:
|
|
type: "mrkdwn"
|
|
text: "*Docs build from `main` failed*:\nAction Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\nCommit: ${{ github.event.head_commit.url }}"
|