diff --git a/.github/workflows/update-remix-run-dev.yml b/.github/workflows/update-remix-run-dev.yml new file mode 100644 index 000000000..a8a698fee --- /dev/null +++ b/.github/workflows/update-remix-run-dev.yml @@ -0,0 +1,28 @@ +name: Update @remix-run/dev + +on: + workflow_dispatch: + inputs: + new-version: + type: string + description: "Optional version to update @remix-run/dev to inside of @vercel/remix" + +jobs: + update-remix-run-dev: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup node + uses: actions/setup-node@v3 + - name: Enable corepack + run: corepack enable pnpm + - name: Update @remix-run/dev + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GH_TOKEN_PULL_REQUESTS }} + script: | + const script = require('./utils/update-remix-run-dev.js') + await script({ github, context }, "${{ inputs.new-version }}") diff --git a/utils/update-remix-run-dev.js b/utils/update-remix-run-dev.js new file mode 100644 index 000000000..97cac49ea --- /dev/null +++ b/utils/update-remix-run-dev.js @@ -0,0 +1,73 @@ +const { execSync } = require('child_process'); +const path = require('path'); +const fs = require('fs'); + +module.exports = async ({ github, context }, newVersion) => { + execSync('git config --global user.email infra+release@vercel.com'); + execSync('git config --global user.name vercel-release-bot'); + execSync('git checkout main'); + + const packagePath = path.join(__dirname, '..', 'packages', 'remix'); + const oldVersion = JSON.parse( + fs.readFileSync(path.join(packagePath, 'package.json'), 'utf-8') + ).dependencies['@remix-run/dev']; + if (newVersion === '') { + newVersion = execSync('npm view @vercel/remix-run-dev dist-tags.latest', { + encoding: 'utf-8', + }); + } + const branch = `vercel-remix-run-dev-${newVersion.replaceAll('.', '-')}`; + + if (oldVersion === newVersion) { + // eslint-disable-next-line no-console + console.log( + `@vercel/remix-run-dev version ${newVersion} did not change, skipping update.` + ); + return; + } + + if ( + execSync(`git ls-remote --heads origin ${branch}`, { encoding: 'utf-8' }) + .toString() + .trim() + ) { + // eslint-disable-next-line no-console + console.log(`Branch ${branch} already exists, skipping update.`); + return; + } + + execSync( + `pnpm install @remix-run/dev@npm:@vercel/remix-run-dev@${newVersion} --save-exact --lockfile-only`, + { cwd: packagePath } + ); + + execSync(`git checkout -b ${branch}`); + execSync('git add -A'); + execSync(`git commit -m ${branch}`); + execSync(`git push origin ${branch}`); + + const { repo, owner } = context.repo; + + const pr = await github.rest.pulls.create({ + owner, + repo, + head: branch, + base: 'main', + title: `[remix] Upgrade @remix-run/dev to version ${newVersion}`, + body: `This auto-generated PR updates @remix-run/dev to version ${newVersion}`, + }); + + await github.rest.pulls.requestReviewers({ + owner, + repo, + pull_number: pr.data.number, + reviewers: ['Ethan-Arrowood', 'TooTallNate'], + }); + + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: pr.data.number, + labels: ['area: remix', 'semver: patch', 'pr: automerge'], + }); +};