name: renovate on: workflow_dispatch: schedule: - cron: "@hourly" push: jobs: discover-repos: name: Discover Repositories runs-on: ubuntu-latest container: ghcr.io/renovatebot/renovate:39.219.2 outputs: repo-batches: ${{ steps.create-batches.outputs.batches }} steps: - name: Checkout uses: actions/checkout@v4 - name: Cache Renovate dependencies uses: actions/cache@v4 with: path: /tmp/renovate-cache key: ${{ runner.os }}-renovate-discovery-${{ hashFiles('config.js') }}-${{ github.run_id }} restore-keys: | ${{ runner.os }}-renovate-discovery-${{ hashFiles('config.js') }}- ${{ runner.os }}-renovate-discovery- - name: Discover Repositories run: | renovate --write-discovered-repos=/tmp/renovate-repos.json env: RENOVATE_CONFIG_FILE: "config.js" RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} GITHUB_COM_TOKEN: ${{ secrets.GH_TOKEN }} LOG_LEVEL: "info" RENOVATE_CACHE_DIR: /tmp/renovate-cache RENOVATE_AUTODISCOVER: "true" - name: Create Repository Batches id: create-batches run: | # Check if repos file exists and is not empty if [ ! -f /tmp/renovate-repos.json ] || [ ! -s /tmp/renovate-repos.json ]; then echo "No repositories discovered or file not created/empty" echo "batches=[]" >> $GITHUB_OUTPUT exit 0 fi # Use node to process JSON instead of jq (Node.js is already installed in the container) node -e ' const fs = require("fs"); try { const data = fs.readFileSync("/tmp/renovate-repos.json", "utf8"); let repos = []; try { repos = JSON.parse(data); if (!Array.isArray(repos)) { repos = []; } } catch (e) { console.error("Invalid JSON:", e.message); } // Create batches of 5 repos const batches = []; for (let i = 0; i < repos.length; i += 5) { batches.push(repos.slice(i, i + 5)); } console.log(`Created ${batches.length} batches of repositories`); // Output for GitHub Actions fs.writeFileSync(process.env.GITHUB_OUTPUT, `batches=${JSON.stringify(batches)}\n`, {flag: "a"}); } catch (e) { console.error("Error processing repositories:", e.message); fs.writeFileSync(process.env.GITHUB_OUTPUT, "batches=[]\n", {flag: "a"}); } ' renovate: name: Run Renovate needs: discover-repos runs-on: ubuntu-latest container: ghcr.io/renovatebot/renovate:39.219.2 if: ${{ needs.discover-repos.outputs.repo-batches != '[]' }} strategy: matrix: batch: ${{ fromJson(needs.discover-repos.outputs.repo-batches) }} fail-fast: false max-parallel: 5 steps: - name: Checkout uses: actions/checkout@v4 - name: Cache Renovate dependencies uses: actions/cache@v4 with: path: /tmp/renovate-cache key: ${{ runner.os }}-renovate-batch-${{ github.run_id }} restore-keys: | ${{ runner.os }}-renovate- - name: Run Renovate on Batch run: | # Use node to process the batch and generate comma-separated repo list node -e ' const batch = JSON.parse(process.argv[1]); if (batch && batch.length > 0) { const repoList = batch.join(","); console.log(`Processing repositories: ${repoList}`); console.log(`::set-output name=repo_list::${repoList}`); } else { console.log("No repositories to process in this batch"); console.log("::set-output name=repo_list::"); } ' '${{ toJson(matrix.batch) }}' # Get the repo list from the node script output REPOS=$(node -e 'console.log(process.env.BATCH_JSON ? JSON.parse(process.env.BATCH_JSON).join(",") : "")' ) # Run Renovate on the specific repositories if any were found if [ -n "$REPOS" ]; then echo "Processing: $REPOS" renovate $REPOS else echo "No repositories to process in this batch" fi env: BATCH_JSON: ${{ toJson(matrix.batch) }} RENOVATE_CONFIG_FILE: "config.js" RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} GITHUB_COM_TOKEN: ${{ secrets.GH_TOKEN }} LOG_LEVEL: "info" RENOVATE_CACHE_DIR: /tmp/renovate-cache # Fallback job in case no repositories are found or for handling config repositories renovate-default: name: Run Renovate (Default) needs: discover-repos runs-on: ubuntu-latest container: ghcr.io/renovatebot/renovate:39.219.2 if: ${{ needs.discover-repos.outputs.repo-batches == '[]' }} steps: - name: Checkout uses: actions/checkout@v4 - name: Cache Renovate dependencies uses: actions/cache@v4 with: path: /tmp/renovate-cache key: ${{ runner.os }}-renovate-default-${{ hashFiles('config.js') }}-${{ github.run_id }} restore-keys: | ${{ runner.os }}-renovate-default-${{ hashFiles('config.js') }}- ${{ runner.os }}-renovate-default- - name: Run Renovate run: renovate env: RENOVATE_CONFIG_FILE: "config.js" RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} GITHUB_COM_TOKEN: ${{ secrets.GH_TOKEN }} LOG_LEVEL: "info" RENOVATE_CACHE_DIR: /tmp/renovate-cache