diff --git a/.github/renovate-bot.js b/.github/renovate-bot.js deleted file mode 100644 index fdc8b7d5b..000000000 --- a/.github/renovate-bot.js +++ /dev/null @@ -1,24 +0,0 @@ -const repository = require("./renovate-repository.json") -delete repository.$schema - -// Mend-hosted Renovate reads renovate.json, which disables it. This process -// ignores that file and is the only Renovate run for the repository. -module.exports = { - platform: "github", - onboarding: false, - requireConfig: "ignored", - gitAuthor: "Renovate Bot <29139614+renovate[bot]@users.noreply.github.com>", - // Mend opened the existing pull requests as renovate[bot]. This job uses the - // access token's user, so it has to read those pull requests too. - ignorePrAuthor: true, - binarySource: "global", - executionTimeout: 45, - allowedCommands: ["^bash scripts/repair-renovate-lockfiles.sh$"], - repositories: [ - { - repository: "alienplatform/alien", - ...repository, - enabled: true, - }, - ], -} diff --git a/.github/renovate-repository.json b/.github/renovate-repository.json deleted file mode 100644 index 15f6fb077..000000000 --- a/.github/renovate-repository.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["config:recommended"], - "additionalBranchPrefix": "alien-370-", - "ignorePaths": [ - "**/node_modules/**", - "**/bower_components/**", - "**/vendor/**", - "**/examples/**", - "**/__tests__/**", - "**/test/**", - "**/tests/**", - "**/__fixtures__/**", - "docker/Dockerfile.alien-sandbox-agent", - "docker/Dockerfile.alien-sandbox-default", - "docker/Dockerfile.alien-sandbox-gcp" - ], - "postUpgradeTasks": { - "commands": ["bash scripts/repair-renovate-lockfiles.sh"], - "fileFilters": ["**/pnpm-lock.yaml"], - "executionMode": "branch" - }, - "packageRules": [ - { - "description": "scripts/repair-renovate-lockfiles.sh refreshes pnpm lockfiles before Renovate commits.", - "matchManagers": ["npm"], - "skipArtifactsUpdate": true - }, - { - "description": "Batch stable minor and patch updates into one pull request, same as group:allNonMajor, and automerge it after CI passes. GitHub Actions stay separate because one workflow edit would make GitHub reject the whole batch.", - "matchManagers": ["!github-actions"], - "matchPackageNames": ["*"], - "matchUpdateTypes": ["minor", "patch"], - "matchCurrentVersion": "!/^0/", - "groupName": "all non-major dependencies", - "groupSlug": "all-minor-patch", - "automerge": true, - "automergeType": "pr", - "automergeStrategy": "squash", - "platformAutomerge": false - }, - { - "description": "CI installs the pnpm version pinned in the workflow. This token cannot update that pin, so a packageManager bump fails every job.", - "matchPackageNames": ["pnpm"], - "enabled": false - }, - { - "description": "Do not treat potentially breaking 0.x minor releases as routine updates", - "matchUpdateTypes": ["minor"], - "matchCurrentVersion": "/^0\\./", - "enabled": false - }, - { - "description": "Require explicit dashboard approval for major updates", - "matchUpdateTypes": ["major"], - "dependencyDashboardApproval": true - }, - { - "description": "ts-proto updates require regenerated Worker runtime clients", - "matchPackageNames": ["ts-proto"], - "automerge": false - }, - { - "description": "Keep ts-proto minor and patch updates in their own pull request", - "matchPackageNames": ["ts-proto"], - "matchUpdateTypes": ["minor", "patch"], - "groupName": "ts-proto", - "groupSlug": "ts-proto" - } - ] -} diff --git a/.github/workflows/ci-fast.yml b/.github/workflows/ci-fast.yml index 006fd4118..d2545af75 100644 --- a/.github/workflows/ci-fast.yml +++ b/.github/workflows/ci-fast.yml @@ -25,9 +25,6 @@ jobs: startsWith(github.event.head_commit.message, 'chore: release ')) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 - - name: Check Renovate lockfile classification - run: bash scripts/repair-renovate-lockfiles.test.sh - name: Validate PR title and branch if: github.event_name == 'pull_request' env: @@ -40,10 +37,7 @@ jobs: echo " Example: feat: add Azure container deployment support" exit 1 fi - # Self-hosted Renovate opens renovate/alien-- as the token user. - # The slug may contain dots, which the human branch pattern rejects. if [[ "$PR_AUTHOR" != "dependabot[bot]" && "$PR_AUTHOR" != "renovate[bot]" ]] && - ! grep -qE '^renovate/alien-[0-9]+-[a-z0-9][a-z0-9._-]*$' <<< "$BRANCH" && ! grep -qE '^[a-z0-9][a-z0-9._-]*/alien-[0-9]+-[a-z0-9]+(-[a-z0-9]+)*$' <<< "$BRANCH"; then echo "::error::Branch must include its Linear issue, for example: alon/alien-123-azure-containers" exit 1 diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml deleted file mode 100644 index a7a55543f..000000000 --- a/.github/workflows/renovate.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Renovate - -on: - schedule: - - cron: "47 * * * *" - workflow_dispatch: - -permissions: - contents: read - -concurrency: - group: renovate - cancel-in-progress: false - -jobs: - renovate: - name: Renovate - runs-on: ubuntu-latest - timeout-minutes: 180 - steps: - - uses: actions/checkout@v7 - with: - persist-credentials: false - - - uses: pnpm/action-setup@v6 - - - uses: actions/setup-node@v7 - with: - node-version: 24 - - - uses: oven-sh/setup-bun@v2 - with: - bun-version: "1.4.2" - - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: "1.98.1" - - - name: Install Renovate - run: npm install --global renovate@44.61.1 - - - name: Run Renovate - env: - RENOVATE_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} - RENOVATE_CONFIG_FILE: ${{ github.workspace }}/.github/renovate-bot.js - run: renovate diff --git a/.github/workflows/repair-renovate-lockfiles.yml b/.github/workflows/repair-renovate-lockfiles.yml new file mode 100644 index 000000000..cdcda8349 --- /dev/null +++ b/.github/workflows/repair-renovate-lockfiles.yml @@ -0,0 +1,54 @@ +name: Repair Renovate lockfiles + +on: + pull_request: + types: [opened, reopened, synchronize] + paths: + - "**/package.json" + - "**/pnpm-lock.yaml" + - "**/pnpm-workspace.yaml" + +concurrency: + group: repair-renovate-lockfiles-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + repair: + # Keep dependency automation paused until explicitly re-enabled. + if: ${{ false }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ github.event.pull_request.head.ref }} + token: ${{ secrets.REPO_ACCESS_TOKEN }} + persist-credentials: false + + - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 + with: + node-version: 24 + + - name: Regenerate pnpm lockfiles + run: | + pnpm install --lockfile-only --no-frozen-lockfile --ignore-scripts + pnpm --dir examples install --lockfile-only --no-frozen-lockfile --ignore-scripts + pnpm --dir examples/github-agent/packages/dashboard install \ + --lockfile-only --no-frozen-lockfile --ignore-scripts + + - name: Commit repaired lockfiles + env: + BRANCH: ${{ github.event.pull_request.head.ref }} + PUSH_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} + run: | + git add pnpm-lock.yaml examples/pnpm-lock.yaml \ + examples/github-agent/packages/dashboard/pnpm-lock.yaml + if git diff --cached --quiet; then + exit 0 + fi + git config user.name "alien-platform[bot]" + git config user.email "3108015+alien-platform[bot]@users.noreply.github.com" + git commit -m "chore(deps): repair pnpm lockfiles" + git push "https://x-access-token:${PUSH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" \ + "HEAD:${BRANCH}" diff --git a/renovate.json b/renovate.json index 6132aecd0..fe72214d6 100644 --- a/renovate.json +++ b/renovate.json @@ -1,4 +1,45 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "enabled": false + "enabled": false, + "extends": ["config:recommended"], + "additionalBranchPrefix": "alien-370-", + "ignorePaths": [ + "**/node_modules/**", + "**/bower_components/**", + "**/vendor/**", + "**/examples/**", + "**/__tests__/**", + "**/test/**", + "**/tests/**", + "**/__fixtures__/**", + "docker/Dockerfile.alien-sandbox-agent", + "docker/Dockerfile.alien-sandbox-default", + "docker/Dockerfile.alien-sandbox-gcp" + ], + "packageRules": [ + { + "description": "Automerge stable non-major updates independently after CI passes", + "matchUpdateTypes": ["minor", "patch"], + "matchCurrentVersion": "!/^0/", + "automerge": true, + "automergeType": "pr", + "automergeStrategy": "squash" + }, + { + "description": "Do not treat potentially breaking 0.x minor releases as routine updates", + "matchUpdateTypes": ["minor"], + "matchCurrentVersion": "/^0\\./", + "enabled": false + }, + { + "description": "Require explicit dashboard approval for major updates", + "matchUpdateTypes": ["major"], + "dependencyDashboardApproval": true + }, + { + "description": "ts-proto updates require regenerated Worker runtime clients", + "matchPackageNames": ["ts-proto"], + "automerge": false + } + ] } diff --git a/scripts/repair-renovate-lockfiles.sh b/scripts/repair-renovate-lockfiles.sh deleted file mode 100755 index 865cbace5..000000000 --- a/scripts/repair-renovate-lockfiles.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -# Refresh pnpm lockfiles after Renovate edits package manifests. -# Renovate runs this before it commits. - -set -euo pipefail - -npm_files_changed() { - local changed=false - local path - while IFS= read -r path; do - if printf '%s\n' "$path" | grep -Eq '(^|/)(package\.json|pnpm-lock\.yaml|pnpm-workspace\.yaml)$'; then - changed=true - fi - done - printf '%s\n' "$changed" -} - -base_ref() { - if ! git rev-parse --verify --quiet origin/main >/dev/null; then - git fetch --no-tags --depth=1 origin main - fi - if git rev-parse --verify --quiet origin/main >/dev/null; then - printf '%s\n' origin/main - return - fi - if git rev-parse --verify --quiet refs/remotes/origin/HEAD >/dev/null; then - printf '%s\n' refs/remotes/origin/HEAD - return - fi - echo "Cannot find origin/main to classify dependency changes" >&2 - return 1 -} - -refresh_lockfiles() { - pnpm install --lockfile-only --no-frozen-lockfile --ignore-scripts - pnpm --dir examples install --lockfile-only --no-frozen-lockfile --ignore-scripts - pnpm --dir examples/github-agent/packages/dashboard install \ - --lockfile-only --no-frozen-lockfile --ignore-scripts -} - -main() { - local root base changed need - root="$(git rev-parse --show-toplevel)" - cd "$root" - - base="$(base_ref)" - changed="$( - git diff --name-only "$base" - git ls-files --others --exclude-standard - )" - need="$(printf '%s\n' "$changed" | npm_files_changed)" - if [[ "$need" != true ]]; then - echo "No npm files changed." - return 0 - fi - refresh_lockfiles -} - -if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then - main "$@" -fi diff --git a/scripts/repair-renovate-lockfiles.test.sh b/scripts/repair-renovate-lockfiles.test.sh deleted file mode 100755 index c8bafa05d..000000000 --- a/scripts/repair-renovate-lockfiles.test.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source-path=SCRIPTDIR -# shellcheck source=repair-renovate-lockfiles.sh -source "${script_dir}/repair-renovate-lockfiles.sh" - -expect_npm() { - local expected="$1" - shift - local actual - actual="$(printf '%s\n' "$@" | npm_files_changed)" - if [[ "$actual" != "$expected" ]]; then - printf 'classification mismatch for: %s\nexpected: %s\nactual: %s\n' "$*" "$expected" "$actual" >&2 - exit 1 - fi -} - -expect_npm true "package.json" -expect_npm true "examples/pnpm-lock.yaml" "README.md" -expect_npm true "examples/github-agent/packages/dashboard/pnpm-workspace.yaml" -expect_npm false "Cargo.toml" -expect_npm false "Cargo.lock" -expect_npm false "apps/api/package.json.bak" -expect_npm true "package.json" "crates/foo/Cargo.toml" - -calls="$(mktemp)" -( - pnpm() { - printf '%s\n' "$*" >>"$calls" - } - refresh_lockfiles -) -expected="$( - cat <<'EOF' -install --lockfile-only --no-frozen-lockfile --ignore-scripts ---dir examples install --lockfile-only --no-frozen-lockfile --ignore-scripts ---dir examples/github-agent/packages/dashboard install --lockfile-only --no-frozen-lockfile --ignore-scripts -EOF -)" -actual="$(cat "$calls")" -rm -f "$calls" -if [[ "$actual" != "$expected" ]]; then - printf 'lockfile refresh commands mismatch\nexpected:\n%s\nactual:\n%s\n' "$expected" "$actual" >&2 - exit 1 -fi - -noop="$(mktemp -d)" -git init -q -b main "$noop" -git -C "$noop" -c user.email=test@example.com -c user.name=test commit -q --allow-empty -m init -git -C "$noop" remote add origin "$noop" -git -C "$noop" update-ref refs/remotes/origin/main HEAD -noop_msg="$(cd "$noop" && main)" -rm -rf "$noop" -if [[ "$noop_msg" != "No npm files changed." ]]; then - echo "unchanged tree should skip lockfile repair" >&2 - exit 1 -fi - -echo "ok"