diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..2620c59 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,135 @@ +# Renovate +## What is Renovate +Renovate is an open-source tool (by Mend) that **automates dependency updates** across basically any language or ecosystem. It supports npm, pip, Terraform, Docker, Maven, Go modules, and a bunch more. + +At a high level, Renovate: +- Scans your repo for dependencies. +- Checks if newer versions are available. +- Creates pull requests with the updates. + +## How to use Renovate Action +### **Create your own ``renovate.json``:** +You can use this as a template and adapt it to your needs later on. Add it to your repo's root level: +```json +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + ":dependencyDashboard", + ":semanticCommits", + ":automergeBranch" + ], + "timezone": "Europe/London", + "schedule": [ + "at any time" + ], + "labels": [ + "renovate", + "terraform" + ], + "assignees": [], + "reviewers": [], + "prConcurrentLimit": 0, + "prHourlyLimit": 0, + "rebaseWhen": "conflicted", + "lockFileMaintenance": { + "enabled": false + }, + "digest": { + "automerge": true + }, + + "packageRules": [ + { + "description": "Terraform providers and modules", + "matchManagers": [ + "terraform" + ], + "commitMessageTopic": "Terraform {{depName}}", + "pinDigests": false + },{ + "matchManagers": ["nvm", "node-version", "asdf"], + "groupName": "Node.js version", + "groupSlug": "node-version", + "semanticCommitType": "chore", + "semanticCommitScope": "node", + "commitMessageTopic": "Node.js version", + "commitMessageExtra": "update Node.js runtime version" + }, + { + "matchManagers": ["npm"], + "groupName": "npm dependencies", + "semanticCommitType": "chore", + "semanticCommitScope": "deps" + } + ], + + "npm": { + "enabled": true + }, + + "nvm": { + "enabled": true + }, + + "asdf": { + "enabled": true + } + +} +``` + +### **Invoke our reusable workflow from your repo:** You can use our reusable workflow from our [GitHub Actions repo](https://github.com/resizes/github-actions/blob/main/.github/workflows/renovate.yml): +```yaml +name: Renovate + +on: + schedule: + # Run every Monday at 5:00 AM UTC + - cron: '0 5 * * 1' + workflow_dispatch: + inputs: + log_level: + description: 'Log level' + required: false + default: 'info' + type: choice + options: + - info + - debug + - trace + dry_run: + description: 'Dry run (no PRs will be created)' + required: false + default: false + type: boolean + force_refresh: + description: 'Force refresh all dependencies' + required: false + default: false + type: boolean + +permissions: + contents: write # To create branches and commits + pull-requests: write # To create and update pull requests + issues: write # For dependency dashboard (if enabled) + checks: read # To read check status + statuses: read # To read commit statuses + actions: read # To read workflow runs + security-events: read # To read security events + +jobs: + renovate: + uses: resizes/github-actions/.github/workflows/renovate.yml@v1 + with: + log_level: ${{ inputs.log_level }} + dry_run: ${{ inputs.dry_run }} + force_refresh: ${{ inputs.force_refresh }} + runner: 'ubuntu-latest' + github_app_id: ${{ secrets.RENOVATE_APP_ID }} + owner: 'Resizes' + repositories: | + + secrets: + github_app_private_key: ${{ secrets.RENOVATE_APP_PRIVATE_KEY }} +``` \ No newline at end of file diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml new file mode 100644 index 0000000..59529d3 --- /dev/null +++ b/.github/workflows/renovate.yml @@ -0,0 +1,124 @@ +name: Renovate + +on: + workflow_call: + inputs: + log_level: + description: 'Log level for Renovate' + required: false + type: string + default: 'info' + dry_run: + description: 'Dry run (no PRs will be created)' + required: false + type: boolean + default: false + force_refresh: + description: 'Force refresh all dependencies' + required: false + type: boolean + default: false + renovate_config_file: + description: 'Path to Renovate configuration file' + required: false + type: string + default: 'renovate.json' + runner: + description: 'GitHub Actions runner to use' + required: false + type: string + default: 'actions-runners' + github_app_id: + description: 'GitHub App ID' + required: true + type: string + owner: + description: 'Owner of the repository' + required: true + type: string + repositories: + description: 'Repositories to be applied the changes to' + required: true + type: string + secrets: + github_app_private_key: + description: 'GitHub App private key (in .pem format)' + required: true + +env: + LOG_LEVEL: ${{ inputs.log_level }} + RENOVATE_DRY_RUN: ${{ inputs.dry_run }} + +jobs: + renovate: + runs-on: ${{ inputs.runner }} + name: Renovate Dependencies + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Install GitHub CLI + run: | + sudo apt update + sudo apt install gh -y + + - name: Create GitHub App Token + id: create-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ inputs.github_app_id }} + private-key: ${{ secrets.github_app_private_key }} + owner: ${{ inputs.owner }} + repositories: ${{ inputs.repositories }} + + - name: Self-hosted Renovate + uses: renovatebot/github-action@v43.0.18 + with: + configurationFile: ${{ inputs.renovate_config_file }} + token: ${{ steps.create-token.outputs.token }} + env: + LOG_LEVEL: ${{ env.LOG_LEVEL }} + RENOVATE_DRY_RUN: ${{ env.RENOVATE_DRY_RUN }} + RENOVATE_FORCE: ${{ inputs.force_refresh }} + # Enable autodiscover to find the current repository + RENOVATE_AUTODISCOVER: true + RENOVATE_AUTODISCOVER_FILTER: ${{ github.repository }} + RENOVATE_GIT_AUTHOR: 'Renovate Bot ' + + - name: Get Renovate PRs + id: get-prs + if: always() + run: | + # Get PRs created by Renovate Bot in the last 7 days + PRS=$(gh pr list \ + --author "app/github-actions" \ + --limit 20 \ + --json number,title,url,createdAt,state \ + --jq 'map(select(.createdAt >= (now - 604800 | strftime("%Y-%m-%dT%H:%M:%SZ")))) | .[] | "• <\(.url)|\(.title)> (#\(.number)) - \(.state)"' \ + | sed 's/OPEN/🟢 Open/g; s/MERGED/🟣 Merged/g; s/CLOSED/⚫ Closed/g') + + # Count PRs - ensure we always get a valid number + if [ -z "$PRS" ]; then + PR_COUNT="0" + else + PR_COUNT=$(echo "$PRS" | grep -c .) + if [ -z "$PR_COUNT" ]; then + PR_COUNT="0" + fi + fi + + # Format the PR list (escape newlines for JSON) + if [ -n "$PRS" ]; then + PR_LIST=$(echo "$PRS" | sed ':a;N;$!ba;s/\n/\\n/g') + else + PR_LIST="No PRs found in the last 7 days." + fi + + # Set outputs + echo "pr_list<> $GITHUB_OUTPUT + echo "$PR_LIST" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + echo "pr_count=$PR_COUNT" >> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ inputs.github_token }}