Renovate #4231
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: 'Renovate' | |
on: # yamllint disable-line rule:truthy | |
workflow_dispatch: | |
inputs: | |
repoCache: | |
description: 'Reset or disable the cache?' | |
type: 'choice' | |
default: 'enabled' | |
options: | |
- 'enabled' | |
- 'disabled' | |
- 'reset' | |
renovateLogLevel: | |
description: 'Renovate Log Level' | |
type: 'choice' | |
default: 'debug' | |
options: | |
- 'debug' | |
- 'info' | |
- 'warn' | |
- 'error' | |
- 'fatal' | |
schedule: | |
# run renovate once an hour | |
- cron: '0 * * * *' | |
# schedule to reset the cache once a week on Monday night | |
- cron: '30 0 * * 1' | |
push: | |
branches: | |
- 'main' | |
paths: | |
- '.github/workflows/renovate.yml' | |
- '.github/renovate.json5' | |
- '.github/renovate_global.js' | |
# Declare default permissions as read only | |
permissions: 'read-all' | |
concurrency: | |
group: 'ci-${{ github.workflow }}-${{ github.ref }}' | |
cancel-in-progress: false | |
# Adding these as env variables makes it easy to re-use them in different steps and in bash. | |
env: | |
# cache for the actual renovate run | |
cache_archive: 'renovate_cache.tar.gz' | |
# This is the dir renovate provides | |
# If we set our own directory via cacheDir, we can run into permissions issues. | |
# It is also possible to cache a higher level of the directory, but it has minimal benefit. While renovate execution | |
# time gets faster, it also takes longer to upload the cache as it grows bigger. | |
cache_dir: '/tmp/renovate/cache/renovate/repository' | |
# This can be manually changed to bust the cache if neccessary. | |
# cache for the actual renovate run | |
cache_key: 'renovate-cache' | |
# gitleaks image to use to check files prior to uploading them to prevent sensitive data being leaked | |
# yamllint disable rule:line-length | |
# renovate image dep: | |
gitleaks-image: 'ghcr.io/gitleaks/gitleaks:v8.22.0@sha256:9c008fc701d3a0a2a15b77a7677b940e2e5942e8af8cc2a0b6e078c4365c3c86' | |
# yamllint enable rule:line-length | |
jobs: | |
check-secrets: | |
name: 'Check if required secrets are available' | |
runs-on: 'ubuntu-24.04' | |
permissions: | |
contents: 'read' | |
outputs: | |
secrets-defined: '${{ steps.secret-check.outputs.secrets-defined }}' | |
steps: | |
- name: 'Harden Runner' | |
uses: 'step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f' # v2.10.2 | |
with: | |
disable-sudo: true | |
egress-policy: 'block' | |
- name: 'Check if all required secrets are defined' | |
id: 'secret-check' | |
shell: 'bash' | |
run: | | |
# fail if: | |
# - a variable is unbound | |
# - any command fails | |
# - a command in a pipe fails | |
# - a command in a sub-shell fails | |
set -Eeuo pipefail | |
( | |
[[ "${{ secrets.CRC_USERNAME }}" != '' ]] && | |
[[ "${{ secrets.CRC_PASSWORD }}" != '' ]] && | |
[[ "${{ secrets.RENOVATE_TOKEN }}" != '' ]] | |
) || { | |
echo "secrets-defined=false" >> "${GITHUB_OUTPUT}"; | |
exit 0; | |
}; | |
# secrets not empty, so assuming defined | |
echo "secrets-defined=true" >> "${GITHUB_OUTPUT}"; | |
call-renovate-configuration-workflow: | |
name: 'Include workflow to validate renovate configuration' | |
if: "needs.check-secrets.outputs.secrets-defined == 'true'" | |
needs: 'check-secrets' | |
permissions: | |
contents: 'write' | |
uses: './.github/workflows/renovate_configuration_check.yml' | |
check-user-permissions: | |
runs-on: 'ubuntu-24.04' | |
permissions: | |
contents: 'read' | |
needs: 'call-renovate-configuration-workflow' | |
outputs: | |
require-result: '${{ steps.check-access.outputs.require-result }}' | |
steps: | |
- name: 'Harden Runner' | |
uses: 'step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f' # v2.10.2 | |
with: | |
egress-policy: 'block' | |
allowed-endpoints: > | |
api.github.com:443 | |
github.com:443 | |
- name: 'Get User Permissions' | |
id: 'check-access' | |
uses: 'actions-cool/check-user-permission@956b2e73cdfe3bcb819bb7225e490cb3b18fd76e' # v2.2.1 | |
with: | |
require: 'write' | |
username: '${{ github.triggering_actor }}' | |
env: | |
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' | |
- name: 'Check User Permission' | |
if: "steps.check-access.outputs.require-result == 'false'" | |
shell: 'bash' | |
run: | | |
# fail if: | |
# - a variable is unbound | |
# - any command fails | |
# - a command in a pipe fails | |
# - a command in a sub-shell fails | |
set -Eeuo pipefail | |
# enable debug if runner runs in debug | |
[[ "${{ runner.debug }}" -ne 1 ]] || { | |
echo "INFO: Enabling bash trace"; | |
set -x; | |
}; | |
echo "${{ github.triggering_actor }} does not have permissions on this repo." | |
echo "Current permission level is ${{ steps.check-access.outputs.user-permission }}" | |
echo "Job originally triggered by ${{ github.actor }}" | |
renovate: | |
runs-on: 'ubuntu-24.04' | |
needs: 'check-user-permissions' | |
if: "needs.check-user-permissions.outputs.require-result == 'true'" | |
permissions: | |
contents: 'write' | |
pull-requests: 'write' | |
steps: | |
- name: 'Harden Runner' | |
uses: 'step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f' # v2.10.2 | |
with: | |
egress-policy: 'block' | |
allowed-endpoints: > | |
auth.docker.io:443 | |
api.github.com:443 | |
console.redhat.com:443 | |
cdn.quay.io:443 | |
cdn01.quay.io:443 | |
cdn02.quay.io:443 | |
cdn03.quay.io:443 | |
endoflife.date:443 | |
galaxy.ansible.com:443 | |
ghcr.io:443 | |
github.com:443 | |
hub.docker.com:443 | |
index.docker.io:443 | |
objects.githubusercontent.com:443 | |
pkg-containers.githubusercontent.com:443 | |
production.cloudflare.docker.com:443 | |
pypi.org:443 | |
registry.access.redhat.com:443 | |
registry.npmjs.org:443 | |
registry.redhat.io:443 | |
repology.org:443 | |
rubygems.org:443 | |
sso.redhat.com:443 | |
www.python.org:443 | |
- name: 'Checkout the repository' | |
uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # v4.2.2 | |
with: | |
# check out the pull request's HEAD | |
ref: '${{ github.event.pull_request.head.sha }}' | |
persist-credentials: false | |
- name: 'Download cache of the previous workflow run' | |
uses: 'dawidd6/action-download-artifact@80620a5d27ce0ae443b965134db88467fc607b43' # v7 | |
if: >- | |
github.event.inputs.repoCache != 'disabled' && | |
github.event.inputs.repoCache != 'reset' && | |
github.event.schedule != '30 0 * * 1' | |
id: 'artifact-download' | |
with: | |
name: '${{ env.cache_key }}' | |
path: 'cache-download' | |
if_no_artifact_found: 'ignore' | |
- name: 'Extract Renovate cache to improve performance' | |
if: >- | |
github.event.inputs.repoCache != 'disabled' && | |
github.event.inputs.repoCache != 'reset' && | |
github.event.schedule != '30 0 * * 1' && | |
steps.artifact-download.outputs.found_artifact == 'true' | |
shell: 'bash' | |
run: | | |
# fail if: | |
# - a variable is unbound | |
# - any command fails | |
# - a command in a pipe fails | |
# - a command in a sub-shell fails | |
set -Eeuo pipefail | |
# enable debug if runner runs in debug | |
[[ "${{ runner.debug }}" -ne 1 ]] || { | |
echo "INFO: Enabling bash trace"; | |
set -x; | |
}; | |
# Make sure the directory exists, and extract it there. Note that it's nested in the download directory. | |
mkdir -p "${{ env.cache_dir }}" | |
tar -xzf "cache-download/${{ env.cache_archive }}" -C "${{ env.cache_dir }}" | |
# Unfortunately, the permissions expected within renovate's docker container | |
# are different than the ones given after the cache is restored. We have to | |
# change ownership to solve this. We also need to have correct permissions in | |
# the entire /tmp/renovate tree, not just the section with the repo cache. | |
sudo chown -R "12021:root" "/tmp/renovate/" | |
# show directory contents if runner runs in debug | |
[[ "${{ runner.debug }}" -ne 1 ]] || { | |
ls -R "${{ env.cache_dir }}"; | |
}; | |
- name: 'Authenticate to console.redhat.com' | |
shell: 'bash' | |
run: | | |
# fail if: | |
# - a variable is unbound | |
# - any command fails | |
# - a command in a pipe fails | |
# - a command in a sub-shell fails | |
set -Eeuo pipefail | |
# set the parameters for curl | |
params=( | |
"https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token" | |
"-d" | |
"grant_type=refresh_token" | |
"-d" | |
"client_id=cloud-services" | |
"-d" | |
"refresh_token=${{ secrets.AUTOMATION_HUB_TOKEN }}" | |
"--silent" | |
"--show-error" | |
) | |
# authenticate and retrieve the bearer token # noqa: line-length | |
bearerToken="$(curl "${params[@]}" | jq --raw-output .access_token)" | |
# mask the bearer token to prevent leaking | |
echo "::add-mask::${bearerToken}" | |
# make the bearer token visible to other workflow steps | |
echo RENOVATE_AUTOMATION_HUB_AUTH_TOKEN="${bearerToken}" >> "${GITHUB_ENV}" | |
- name: 'Run Renovate' | |
uses: 'renovatebot/github-action@e3a862510f27d57a380efb11f0b52ad7e8dbf213' # v41.0.6 | |
with: | |
# yamllint disable-line rule:line-length | |
# renovate self-update: datasource=docker depName=renovatebot/renovate registryUrl=https://ghcr.io | |
renovate-version: '39.82.0' | |
configurationFile: '.github/renovate_global.js' | |
token: '${{ secrets.RENOVATE_TOKEN }}' | |
env: | |
RENOVATE_REPOSITORY_CACHE: "${{ github.event.inputs.repoCache || 'enabled' }}" | |
RENOVATE_REPOSITORIES: '${{ github.repository }}' | |
RENOVATE_CRC_USERNAME: '${{ secrets.CRC_USERNAME }}' | |
RENOVATE_CRC_PASSWORD: '${{ secrets.CRC_PASSWORD }}' | |
RENOVATE_GHCR_TOKEN: '${{ secrets.GITHUB_TOKEN }}' | |
RENOVATE_GHCR_USERNAME: '${{ github.actor }}' | |
LOG_LEVEL: "${{ github.event.inputs.renovateLogLevel || 'debug' }}" | |
- name: 'Scan renovate cache directory to ensure it contains no secrets prior to uploading' | |
if: "github.event.inputs.repoCache != 'disabled'" | |
shell: 'bash' | |
run: | | |
# fail if: | |
# - a variable is unbound | |
# - any command fails | |
# - a command in a pipe fails | |
# - a command in a sub-shell fails | |
set -Eeuo pipefail | |
# enable debug if runner runs in debug | |
[[ "${{ runner.debug }}" -ne 1 ]] || { | |
echo "INFO: Enabling bash trace"; | |
set -x; | |
}; | |
docker run -v "${{ env.cache_dir }}:/scan" "${{ env.gitleaks-image }}" detect --source "/scan" --no-git || { | |
echo "ERROR: Secret found, failing workflow"; | |
exit 1; | |
}; | |
- name: 'Compress Renovate cache to improve performance' | |
if: "github.event.inputs.repoCache != 'disabled'" | |
shell: 'bash' | |
run: | | |
# fail if: | |
# - a variable is unbound | |
# - any command fails | |
# - a command in a pipe fails | |
# - a command in a sub-shell fails | |
set -Eeuo pipefail | |
# enable debug if runner runs in debug | |
[[ "${{ runner.debug }}" -ne 1 ]] || { | |
echo "INFO: Enabling bash trace"; | |
set -x; | |
}; | |
# The -C is important, as otherwise we end up extracting the files with | |
# their full path, ultimately leading to a nested directory situation. | |
tar -czvf "${{ env.cache_archive }}" -C "${{ env.cache_dir }}" . | |
- name: 'Upload compressed cache' | |
uses: 'actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b' # v4.5.0 | |
if: "github.event.inputs.repoCache != 'disabled'" | |
with: | |
name: '${{ env.cache_key }}' | |
path: '${{ env.cache_archive }}' | |
# Since this is updated and restored on every run, we don't need to keep it | |
# for long. Just make sure this value is large enough that multiple renovate | |
# runs can happen before older cache archives are deleted. | |
retention-days: 1 | |
... |