From 9bc557951ad6b3a65ebe4453cb8d034d90cb18ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=A7=91=F0=9F=8F=BB=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier?= Date: Fri, 2 Jun 2023 11:15:22 +0200 Subject: [PATCH] chore: automate maintenance of older releases Now that TypeScript 5.1 is out, and `jsii@v5.1` is about to be released, automation needs to automatically keep the `maintenance/v5.0` branch updated for at least 6 months. --- .gitattributes | 5 +- .github/workflows/auto-tag-dev-v5.0.yml | 59 ++++++++++++ .github/workflows/auto-tag-releases-v5.0.yml | 59 ++++++++++++ .github/workflows/build.yml | 1 + .../{upgrade.yml => upgrade-main.yml} | 13 ++- .../workflows/upgrade-maintenance-v5.0.yml | 91 +++++++++++++++++++ .gitignore | 5 +- .projen/files.json | 5 +- .projenrc.ts | 52 +++++++++-- projenrc/build-workflow.ts | 2 +- projenrc/release.ts | 15 ++- projenrc/support.ts | 12 ++- releases.json | 6 +- 13 files changed, 298 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/auto-tag-dev-v5.0.yml create mode 100644 .github/workflows/auto-tag-releases-v5.0.yml rename .github/workflows/{upgrade.yml => upgrade-main.yml} (90%) create mode 100644 .github/workflows/upgrade-maintenance-v5.0.yml diff --git a/.gitattributes b/.gitattributes index 4a60c0d0..f7644b0f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,12 +6,15 @@ /.github/pull_request_template.md linguist-generated /.github/workflows/auto-approve.yml linguist-generated /.github/workflows/auto-merge.yml linguist-generated +/.github/workflows/auto-tag-dev-v5.0.yml linguist-generated /.github/workflows/auto-tag-dev.yml linguist-generated +/.github/workflows/auto-tag-releases-v5.0.yml linguist-generated /.github/workflows/auto-tag-releases.yml linguist-generated /.github/workflows/build.yml linguist-generated /.github/workflows/pull-request-lint.yml linguist-generated /.github/workflows/release.yml linguist-generated -/.github/workflows/upgrade.yml linguist-generated +/.github/workflows/upgrade-main.yml linguist-generated +/.github/workflows/upgrade-maintenance-v5.0.yml linguist-generated /.gitignore linguist-generated /.npmignore linguist-generated /.npmrc linguist-generated diff --git a/.github/workflows/auto-tag-dev-v5.0.yml b/.github/workflows/auto-tag-dev-v5.0.yml new file mode 100644 index 00000000..5c0dfa03 --- /dev/null +++ b/.github/workflows/auto-tag-dev-v5.0.yml @@ -0,0 +1,59 @@ +# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". + +name: auto-tag-dev-v5.0 +run-name: Auto-Tag Prerelease (v5.0) +on: + schedule: + - cron: 0 5 * * 0,2-6 + workflow_dispatch: {} +jobs: + pre-flight: + name: Pre-Flight Checks + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + sha: ${{ steps.git.outputs.sha }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + repository: ${{ github.repository }} + ref: maintenance/v5.0 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version: 14.18.0 + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Build + run: yarn build + - name: Identify git SHA + id: git + run: echo sha=$(git rev-parse HEAD) >> $GITHUB_OUTPUT + auto-tag: + name: Auto-Tag Release + needs: pre-flight + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + repository: ${{ github.repository }} + token: ${{ secrets.PROJEN_GITHUB_TOKEN }} + ref: ${{ needs.pre-flight.outputs.sha }} + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version: 14.18.0 + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Set git identity + run: |- + git config user.name "github-actions" + git config user.email "github-actions@github.com" + - name: Tag PreRelease + run: yarn tag-release --idempotent --no-sign --push --prerelease=dev diff --git a/.github/workflows/auto-tag-releases-v5.0.yml b/.github/workflows/auto-tag-releases-v5.0.yml new file mode 100644 index 00000000..57170505 --- /dev/null +++ b/.github/workflows/auto-tag-releases-v5.0.yml @@ -0,0 +1,59 @@ +# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". + +name: auto-tag-releases-v5.0 +run-name: Auto-Tag Release (v5.0) +on: + schedule: + - cron: 0 5 * * 1 + workflow_dispatch: {} +jobs: + pre-flight: + name: Pre-Flight Checks + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + sha: ${{ steps.git.outputs.sha }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + repository: ${{ github.repository }} + ref: maintenance/v5.0 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version: 14.18.0 + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Build + run: yarn build + - name: Identify git SHA + id: git + run: echo sha=$(git rev-parse HEAD) >> $GITHUB_OUTPUT + auto-tag: + name: Auto-Tag Release + needs: pre-flight + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + repository: ${{ github.repository }} + token: ${{ secrets.PROJEN_GITHUB_TOKEN }} + ref: ${{ needs.pre-flight.outputs.sha }} + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version: 14.18.0 + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Set git identity + run: |- + git config user.name "github-actions" + git config user.email "github-actions@github.com" + - name: Tag Release + run: "yarn tag-release --idempotent --no-sign --push " diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a12d9f55..edffa7ba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,6 +7,7 @@ on: push: branches: - main + - maintenance/* jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/upgrade.yml b/.github/workflows/upgrade-main.yml similarity index 90% rename from .github/workflows/upgrade.yml rename to .github/workflows/upgrade-main.yml index 8f4ec608..d45e041e 100644 --- a/.github/workflows/upgrade.yml +++ b/.github/workflows/upgrade-main.yml @@ -1,6 +1,6 @@ # ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". -name: upgrade +name: upgrade-main on: workflow_dispatch: {} schedule: @@ -16,6 +16,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + with: + ref: main - name: Setup Node.js uses: actions/setup-node@v3 with: @@ -45,7 +47,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - with: {} + with: + ref: main - name: Download patch uses: actions/download-artifact@v3 with: @@ -71,8 +74,8 @@ jobs: ------ - *Automatically created by projen via the "upgrade" workflow* - branch: github-actions/upgrade + *Automatically created by projen via the "upgrade-main" workflow* + branch: github-actions/upgrade-main title: "chore(deps): upgrade dependencies" labels: auto-approve body: |- @@ -82,7 +85,7 @@ jobs: ------ - *Automatically created by projen via the "upgrade" workflow* + *Automatically created by projen via the "upgrade-main" workflow* author: github-actions committer: github-actions signoff: true diff --git a/.github/workflows/upgrade-maintenance-v5.0.yml b/.github/workflows/upgrade-maintenance-v5.0.yml new file mode 100644 index 00000000..4c0d39b2 --- /dev/null +++ b/.github/workflows/upgrade-maintenance-v5.0.yml @@ -0,0 +1,91 @@ +# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". + +name: upgrade-maintenance-v5.0 +on: + workflow_dispatch: {} + schedule: + - cron: 0 0 * * * +jobs: + upgrade: + name: Upgrade + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + patch_created: ${{ steps.create_patch.outputs.patch_created }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: maintenance/v5.0 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 14.18.0 + - name: Install dependencies + run: yarn install --check-files --frozen-lockfile + - name: Upgrade dependencies + run: npx projen upgrade + - name: Find mutations + id: create_patch + run: |- + git add . + git diff --staged --patch --exit-code > .repo.patch || echo "patch_created=true" >> $GITHUB_OUTPUT + - name: Upload patch + if: steps.create_patch.outputs.patch_created + uses: actions/upload-artifact@v3 + with: + name: .repo.patch + path: .repo.patch + pr: + name: Create Pull Request + needs: upgrade + runs-on: ubuntu-latest + permissions: + contents: read + if: ${{ needs.upgrade.outputs.patch_created }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: maintenance/v5.0 + - name: Download patch + uses: actions/download-artifact@v3 + with: + name: .repo.patch + path: ${{ runner.temp }} + - name: Apply patch + run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."' + - name: Set git identity + run: |- + git config user.name "github-actions" + git config user.email "github-actions@github.com" + - name: Create Pull Request + id: create-pr + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.PROJEN_GITHUB_TOKEN }} + commit-message: |- + chore(deps): upgrade dependencies + + Upgrades project dependencies. See details in [workflow run]. + + [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + + ------ + + *Automatically created by projen via the "upgrade-maintenance-v5.0" workflow* + branch: github-actions/upgrade-maintenance-v5.0 + title: "chore(deps): upgrade dependencies" + labels: auto-approve + body: |- + Upgrades project dependencies. See details in [workflow run]. + + [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + + ------ + + *Automatically created by projen via the "upgrade-maintenance-v5.0" workflow* + author: github-actions + committer: github-actions + signoff: true diff --git a/.gitignore b/.gitignore index 2156e79a..bb51dd7f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,8 @@ jspm_packages/ !/.projenrc.js !/jest.config.json /coverage/ -!/.github/workflows/upgrade.yml +!/.github/workflows/upgrade-main.yml +!/.github/workflows/upgrade-maintenance-v5.0.yml !/.github/pull_request_template.md !/.prettierrc.json !/.npmrc @@ -58,3 +59,5 @@ jspm_packages/ !/.github/workflows/release.yml !/.github/workflows/auto-tag-dev.yml !/.github/workflows/auto-tag-releases.yml +!/.github/workflows/auto-tag-dev-v5.0.yml +!/.github/workflows/auto-tag-releases-v5.0.yml diff --git a/.projen/files.json b/.projen/files.json index a0943a6d..2340c662 100644 --- a/.projen/files.json +++ b/.projen/files.json @@ -5,12 +5,15 @@ ".github/pull_request_template.md", ".github/workflows/auto-approve.yml", ".github/workflows/auto-merge.yml", + ".github/workflows/auto-tag-dev-v5.0.yml", ".github/workflows/auto-tag-dev.yml", + ".github/workflows/auto-tag-releases-v5.0.yml", ".github/workflows/auto-tag-releases.yml", ".github/workflows/build.yml", ".github/workflows/pull-request-lint.yml", ".github/workflows/release.yml", - ".github/workflows/upgrade.yml", + ".github/workflows/upgrade-main.yml", + ".github/workflows/upgrade-maintenance-v5.0.yml", ".gitignore", ".npmignore", ".npmrc", diff --git a/.projenrc.ts b/.projenrc.ts index 54ab2e81..58366442 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -2,7 +2,7 @@ import { javascript, JsonFile, JsonPatch, typescript } from 'projen'; import { BuildWorkflow } from './projenrc/build-workflow'; import { JsiiCalcFixtures } from './projenrc/fixtures'; import { ReleaseWorkflow } from './projenrc/release'; -import { SupportPolicy } from './projenrc/support'; +import { SUPPORT_POLICY, SupportPolicy } from './projenrc/support'; import { UpdateIntegPackage } from './projenrc/update-integ-package'; const project = new typescript.TypeScriptProject({ @@ -78,13 +78,27 @@ const project = new typescript.TypeScriptProject({ buildWorkflow: false, // We have our own build workflow (need matrix test) release: false, // We have our own release workflow - defaultReleaseBranch: 'release', + defaultReleaseBranch: 'main', autoApproveUpgrades: true, autoApproveOptions: { allowedUsernames: ['aws-cdk-automation', 'github-bot'], }, + depsUpgradeOptions: { + workflowOptions: { + branches: [ + 'main', + ...Object.entries(SUPPORT_POLICY.maintenance).flatMap(([version, until]) => { + if (Date.now() > until.getTime()) { + return []; + } + return [`maintenance/v${version}`]; + }), + ], + }, + }, + vscode: true, }); @@ -109,9 +123,6 @@ project.tsconfig?.file?.patch( JsonPatch.add('/compilerOptions/declarationMap', true), ); -// Add support policy documents -new SupportPolicy(project); - // Don't show .gitignore'd files in the VSCode explorer project.vscode!.settings.addSetting('explorer.excludeGitIgnore', true); // Use the TypeScript SDK from the project dependencies @@ -214,8 +225,9 @@ new JsiiCalcFixtures(project); // Add Node.js version matrix test new BuildWorkflow(project); -// Add the custom release workflow -new ReleaseWorkflow(project) +// Add support policy documents & release workflows +new SupportPolicy(project); +const releases = new ReleaseWorkflow(project) .autoTag({ preReleaseId: 'dev', runName: 'Auto-Tag Prerelease (default branch)', @@ -226,6 +238,32 @@ new ReleaseWorkflow(project) schedule: '0 0 * * 1', // Mondays at midnight }); +// We'll stagger release schedules so as to avoid everything going out at once. +let hour = 0; +for (const [version, until] of Object.entries(SUPPORT_POLICY.maintenance)) { + if (Date.now() <= until.getTime()) { + // Stagger schedules every 5 hours, rolling. 5 was selected because it's co-prime to 24. + hour = (hour + 5) % 24; + + const branch = `v${version}`; + + releases + .autoTag({ + preReleaseId: 'dev', + runName: `Auto-Tag Prerelease (${branch})`, + schedule: `0 ${hour} * * 0,2-6`, // Tuesday though sundays + branch: `maintenance/${branch}`, + nameSuffix: branch, + }) + .autoTag({ + runName: `Auto-Tag Release (${branch})`, + schedule: `0 ${hour} * * 1`, // Mondays + branch: `maintenance/${branch}`, + nameSuffix: branch, + }); + } +} + new UpdateIntegPackage(project); project.synth(); diff --git a/projenrc/build-workflow.ts b/projenrc/build-workflow.ts index 5b62f73c..ad2c39e9 100644 --- a/projenrc/build-workflow.ts +++ b/projenrc/build-workflow.ts @@ -35,7 +35,7 @@ export class BuildWorkflow { if (opts.defaultBranch !== null) { wf.on({ push: { - branches: [opts.defaultBranch ?? 'main'], + branches: [opts.defaultBranch ?? 'main', 'maintenance/*'], }, }); } diff --git a/projenrc/release.ts b/projenrc/release.ts index 72d5f78c..eddfb6a4 100644 --- a/projenrc/release.ts +++ b/projenrc/release.ts @@ -244,11 +244,8 @@ export class ReleaseWorkflow { } public autoTag(opts: AutoTagWorkflowProps): this { - new AutoTagWorkflow( - this.project, - `auto-tag-${opts.preReleaseId ?? 'releases'}${opts.branch ? `-${opts.branch}` : ''}`, - opts, - ); + const suffix = opts.nameSuffix ? `-${opts.nameSuffix}` : opts.branch ? `-${opts.branch}` : ''; + new AutoTagWorkflow(this.project, `auto-tag-${opts.preReleaseId ?? 'releases'}${suffix}`, opts); return this; } } @@ -321,6 +318,14 @@ interface AutoTagWorkflowProps { * @default - a regular release will be tagged. */ readonly preReleaseId?: string; + + /** + * The workflow name suffix. A single `-` will be prepended to this value if + * present, which is then appended at the end of the workflow name. + * + * @default - derived from the branch name (if present). + */ + readonly nameSuffix?: string; } class AutoTagWorkflow { diff --git a/projenrc/support.ts b/projenrc/support.ts index 437984f9..ea3873d1 100644 --- a/projenrc/support.ts +++ b/projenrc/support.ts @@ -1,15 +1,19 @@ import { JsonFile, Project } from 'projen'; import type { ReleasesDocument } from '../src/support'; +export const SUPPORT_POLICY: ReleasesDocument = { + current: '5.1', + maintenance: { + '5.0': new Date('2024-01-31'), + }, +}; + export class SupportPolicy { public constructor(project: Project) { new JsonFile(project, 'releases.json', { allowComments: false, editGitignore: false, - obj: { - current: '5.0', - maintenance: {}, - } satisfies ReleasesDocument, + obj: SUPPORT_POLICY, readonly: true, }); } diff --git a/releases.json b/releases.json index 165b805c..bcb034f2 100644 --- a/releases.json +++ b/releases.json @@ -1,5 +1,7 @@ { - "current": "5.0", - "maintenance": {}, + "current": "5.1", + "maintenance": { + "5.0": "2024-01-31T00:00:00.000Z" + }, "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." }