diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index cb2a696d1..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,91 +0,0 @@ -version: 2 -updates: - # npm dependencies (single root package.json, no workspaces) - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "weekly" - day: "monday" - open-pull-requests-limit: 15 - labels: - - "dependencies" - - "npm" - commit-message: - prefix: "chore" - prefix-development: "chore" - include: "scope" - groups: - dev-patch-updates: - dependency-type: "development" - update-types: - - "patch" - dev-minor-updates: - dependency-type: "development" - update-types: - - "minor" - prod-patch-updates: - dependency-type: "production" - update-types: - - "patch" - prod-minor-updates: - dependency-type: "production" - update-types: - - "minor" - # Major bumps grouped so they land as a single reviewable PR instead of - # one-per-package noise. These often need manual follow-up (Electron, - # React, Vite, Tailwind, Express 5, etc.). - major-updates: - update-types: - - "major" - ignore: - # typescript-eslint declares `typescript: >=4.8.4 <6.1.0`, and TypeScript 7 - # removed `ts.Extension`, which @typescript-eslint/typescript-estree reads - # at import time. Bumping to 7 makes `eslint .` fail to load its own config, - # so `npm run lint` cannot run at all. Drop this once typescript-eslint - # supports TypeScript 7. - - dependency-name: "typescript" - update-types: ["version-update:semver-major"] - - # Docker base images (docker/Dockerfile + docker-compose / compose-dev) - - package-ecosystem: "docker" - directory: "/docker" - schedule: - interval: "weekly" - day: "monday" - open-pull-requests-limit: 10 - labels: - - "dependencies" - - "docker" - commit-message: - prefix: "chore" - include: "scope" - groups: - docker-patch-updates: - update-types: - - "patch" - docker-minor-updates: - update-types: - - "minor" - docker-major-updates: - update-types: - - "major" - - # GitHub Actions used across the workflows in .github/workflows - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - day: "monday" - open-pull-requests-limit: 10 - labels: - - "dependencies" - - "github-actions" - commit-message: - prefix: "ci" - include: "scope" - groups: - github-actions: - update-types: - - "patch" - - "minor" - - "major" diff --git a/.github/workflows/dependabot-retarget.yml b/.github/workflows/dependabot-retarget.yml deleted file mode 100644 index 15f052275..000000000 --- a/.github/workflows/dependabot-retarget.yml +++ /dev/null @@ -1,157 +0,0 @@ -name: Retarget and Merge Dependabot PRs - -on: - schedule: - - cron: "0 6 * * *" - workflow_dispatch: - -permissions: - contents: write - pull-requests: write - -jobs: - retarget-and-merge: - runs-on: blacksmith-2vcpu-ubuntu-2404 - steps: - - name: Checkout repository - uses: actions/checkout@v7 - with: - fetch-depth: 1 - - - name: Resolve newest dev branch - id: dev - env: - GH_TOKEN: ${{ secrets.TERMIX_PAT }} - run: | - REFS=$(gh api "repos/${{ github.repository }}/branches" --paginate -q '.[].name') - # The helper exits non-zero when no dev-X.Y.Z branch exists; treat that - # as "nothing to do" rather than a workflow failure. - if DEV_BRANCH=$(printf '%s\n' "$REFS" | node scripts/latest-dev-branch.cjs 2>/dev/null); then - echo "Newest dev branch: $DEV_BRANCH" - echo "branch=$DEV_BRANCH" >> "$GITHUB_OUTPUT" - else - echo "No dev-X.Y.Z branch open; nothing to retarget." - echo "branch=" >> "$GITHUB_OUTPUT" - fi - - - name: Retarget and merge Dependabot PRs - if: ${{ steps.dev.outputs.branch != '' }} - env: - GH_TOKEN: ${{ secrets.TERMIX_PAT }} - DEV_BRANCH: ${{ steps.dev.outputs.branch }} - REPO: ${{ github.repository }} - run: | - set -uo pipefail - - CONFLICT_LABEL="dependabot-rebase-requested" - - # Ensure the bookkeeping label exists (no-op if it already does). - gh label create "$CONFLICT_LABEL" --repo "$REPO" \ - --color "D93F0B" --description "Retarget workflow asked Dependabot to rebase a conflicting PR" \ - 2>/dev/null || true - - # True if the PR already carries the conflict label. - has_conflict_label() { - gh pr view "$1" --repo "$REPO" --json labels \ - -q '.labels[].name' | grep -qx "$CONFLICT_LABEL" - } - - # Wait until GitHub has a definite mergeable verdict for a PR (it - # returns UNKNOWN while recomputing after a base change or a push). - # Echoes " ". - wait_for_verdict() { - local pr="$1" mergeable state - for _ in $(seq 1 30); do - read -r mergeable state < <(gh pr view "$pr" --repo "$REPO" \ - --json mergeable,mergeStateStatus \ - -q '.mergeable + " " + .mergeStateStatus') - if [ "$mergeable" != "UNKNOWN" ] && [ "$state" != "UNKNOWN" ]; then - echo "$mergeable $state" - return 0 - fi - sleep 20 - done - echo "$mergeable $state" - } - - # Phase 1: retarget every open Dependabot PR from main onto the dev - # branch. This kicks off a Dependabot rebase for each. - PR_NUMBERS=$(gh pr list --repo "$REPO" \ - --author "app/dependabot" \ - --base main \ - --state open \ - --json number -q '.[].number') - - # Pick up PRs already sitting on the dev branch from a previous run too. - PR_NUMBERS="$PR_NUMBERS $(gh pr list --repo "$REPO" \ - --author "app/dependabot" \ - --base "$DEV_BRANCH" \ - --state open \ - --json number -q '.[].number')" - - PR_NUMBERS=$(printf '%s\n' $PR_NUMBERS | sort -un) - - if [ -z "$PR_NUMBERS" ]; then - echo "No open Dependabot PRs to process." - exit 0 - fi - - for PR in $PR_NUMBERS; do - BASE=$(gh pr view "$PR" --repo "$REPO" --json baseRefName -q .baseRefName) - if [ "$BASE" != "$DEV_BRANCH" ]; then - echo "Retargeting PR #$PR ($BASE -> $DEV_BRANCH)" - gh pr edit "$PR" --repo "$REPO" --base "$DEV_BRANCH" - fi - done - - # Phase 2: merge one at a time. Each merge can make the remaining npm - # PRs stale, so re-check immediately before merging and rebase stragglers. - for PR in $PR_NUMBERS; do - echo "::group::PR #$PR" - - read -r MERGEABLE STATE < <(wait_for_verdict "$PR") - echo " mergeable=$MERGEABLE mergeStateStatus=$STATE" - - # BEHIND = clean but needs the latest base; ask Dependabot to rebase - # and skip for now (next run merges it once it is up to date). - if [ "$STATE" = "BEHIND" ]; then - echo " PR #$PR is behind $DEV_BRANCH; asking Dependabot to rebase." - gh pr comment "$PR" --repo "$REPO" --body "@dependabot rebase" - echo "::endgroup::" - continue - fi - - # DIRTY / CONFLICTING = a real conflict. Try a rebase once (label it so - # we can tell next time); if it is STILL conflicting on a later run - # despite already being labelled, the rebase failed for good - close it - # so Dependabot reopens a fresh PR against the current dev branch. - if [ "$MERGEABLE" = "CONFLICTING" ] || [ "$STATE" = "DIRTY" ]; then - if has_conflict_label "$PR"; then - echo " PR #$PR still conflicts after a prior rebase request; closing so Dependabot reopens it fresh." - gh pr close "$PR" --repo "$REPO" --delete-branch \ - --comment "Closing: this PR still conflicts with $DEV_BRANCH after a rebase attempt (its changes are likely already merged). Dependabot will reopen a fresh PR computed against the current $DEV_BRANCH." - else - echo " PR #$PR conflicts with $DEV_BRANCH; requesting a rebase and labelling it." - gh pr edit "$PR" --repo "$REPO" --add-label "$CONFLICT_LABEL" - gh pr comment "$PR" --repo "$REPO" --body "@dependabot rebase" - fi - echo "::endgroup::" - continue - fi - - # A clean PR that was previously flagged has recovered - drop the label. - if has_conflict_label "$PR"; then - gh pr edit "$PR" --repo "$REPO" --remove-label "$CONFLICT_LABEL" || true - fi - - echo " Squash-merging PR #$PR" - if gh pr merge "$PR" --repo "$REPO" --squash --admin; then - echo " Merged PR #$PR" - # Give GitHub a moment to mark the now-stale siblings BEHIND. - sleep 15 - else - echo " Could not merge PR #$PR now; it will be retried next run." - fi - - echo "::endgroup::" - done