From d1617120f329654cc3bbdedcb245b1f6e4bacbc5 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Tue, 24 Oct 2023 13:20:37 +0100 Subject: [PATCH] post diff to PR --- .github/workflows/build.yml | 76 ++++++++++++++++++ .projenrc.ts | 9 ++- projenrc/diff-db.ts | 153 ++++++++++++++++++++++++++++++++++++ projenrc/index.ts | 1 + 4 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 projenrc/diff-db.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 92bbc6c7a..71b234f4a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,6 +44,11 @@ jobs: echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch." cat .repo.patch exit 1 + - name: Upload head database + uses: actions/upload-artifact@v3 + with: + name: db.head.json.gz + path: packages/@aws-cdk/aws-service-spec/db.json.gz self-mutation: needs: build runs-on: awscdk-service-spec_ubuntu-latest_32-core @@ -76,3 +81,74 @@ jobs: git add . git commit -s -m "chore: self mutation" git push origin HEAD:$PULL_REQUEST_REF + base-database: + runs-on: awscdk-service-spec_ubuntu-latest_32-core + permissions: {} + env: + CI: "true" + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.base.ref }} + repository: ${{ github.event.pull_request.base.repo.full_name }} + lfs: true + - name: Install dependencies + run: yarn install --check-files + - name: Build base database + run: npx projen nx compile + working-directory: packages/@aws-cdk/aws-service-spec + - name: Upload base database + uses: actions/upload-artifact@v3 + with: + name: db.base.json.gz + path: packages/@aws-cdk/aws-service-spec/db.json.gz + diff-db: + needs: + - build + - base-database + runs-on: awscdk-service-spec_ubuntu-latest_32-core + permissions: + contents: write + env: + CI: "true" + if: "!(needs.build.outputs.self_mutation_happened)" + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + lfs: false + - name: Install dependencies + run: yarn install --check-files + - name: Build diff-db + run: npx projen nx compile + working-directory: packages/@aws-cdk/service-spec-importers + - name: Download base database + uses: actions/download-artifact@v3 + with: + name: db.base.json.gz + path: ${{ runner.temp }} + - name: Download head database + uses: actions/download-artifact@v3 + with: + name: db.head.json.gz + path: ${{ runner.temp }} + - name: Diff databases + run: ./bin/diff-db ${{ runner.temp }}/db.base.json.gz ${{ runner.temp }}/db.head.json.gz > ${{ runner.temp }}/DIFF + working-directory: packages/@aws-cdk/service-spec-importers + - id: diff-db + run: |- + echo "diff=$(cat ${{ runner.temp }}/DIFF)" >> $GITHUB_OUTPUT + echo "\`\`\`\n$(cat ${{ runner.temp }}/DIFF)\n\`\`\`\" >> $GITHUB_STEP_SUMMARY + - name: Comment diff + if: ${{ steps.diff-db.outputs.diff }} + uses: thollander/actions-comment-pull-request@v2 + with: + comment_tag: diff-db + message: | + Model database diff introduced between base and head branch: + ``` + ${{ steps.diff-db.outputs.diff }} + ``` diff --git a/.projenrc.ts b/.projenrc.ts index 27f4d0176..367ece908 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -1,5 +1,5 @@ import * as pj from 'projen'; -import { AwsCdkIntegrationTest, TypeScriptWorkspace, YarnMonorepo } from './projenrc'; +import { AwsCdkIntegrationTest, DiffDb, TypeScriptWorkspace, YarnMonorepo } from './projenrc'; import { RegionalSource, Role, SingleSource, SourceProcessing } from './projenrc/update-sources'; const workflowRunsOn = [ @@ -178,6 +178,13 @@ new AwsCdkIntegrationTest(repo, { serviceSpecTypes, }); +// Post diff of database +new DiffDb(repo, { + workflowRunsOn, + serviceSpec: awsServiceSpec, + serviceSpecImporters, +}); + // Update sources new SingleSource(repo, { name: 'documentation', diff --git a/projenrc/diff-db.ts b/projenrc/diff-db.ts new file mode 100644 index 000000000..4f2e3e7c0 --- /dev/null +++ b/projenrc/diff-db.ts @@ -0,0 +1,153 @@ +import * as pj from 'projen'; +import { yarn } from 'cdklabs-projen-project-types'; +import { relative } from 'node:path'; + +export interface DiffDbOptions { + readonly workflowRunsOn: string[]; + readonly serviceSpec: yarn.TypeScriptWorkspace; + readonly serviceSpecImporters: yarn.TypeScriptWorkspace; +} + +export class DiffDb extends pj.Component { + private readonly workflow: pj.github.GithubWorkflow; + private readonly serviceSpec: yarn.TypeScriptWorkspace; + private readonly importers: yarn.TypeScriptWorkspace; + private readonly workflowRunsOn: string[]; + + public constructor(root: yarn.Monorepo, options: DiffDbOptions) { + super(root); + + this.workflow = root.github?.tryFindWorkflow('build')!; + this.serviceSpec = options.serviceSpec; + this.importers = options.serviceSpecImporters; + this.workflowRunsOn = options.workflowRunsOn; + + this.uploadHeadDatabase(); + this.buildBaseDatabase(); + this.diffDatabase(); + } + + private path(path: string) { + return relative(this.project.outdir, path); + } + + private uploadHeadDatabase() { + this.workflow.file?.patch( + pj.JsonPatch.add('/jobs/build/steps/-', { + name: 'Upload head database', + uses: 'actions/upload-artifact@v3', + with: { + name: 'db.head.json.gz', + path: this.path(this.serviceSpec.outdir + '/db.json.gz'), + }, + }), + ); + } + + private buildBaseDatabase() { + this.workflow.addJob('base-database', { + runsOn: this.workflowRunsOn, + env: { CI: 'true' }, + permissions: {}, + steps: [ + { + name: 'Checkout', + uses: 'actions/checkout@v3', + with: { + ref: '${{ github.event.pull_request.base.ref }}', + repository: '${{ github.event.pull_request.base.repo.full_name }}', + lfs: true, + }, + }, + { + name: 'Install dependencies', + run: 'yarn install --check-files', + }, + { + name: 'Build base database', + workingDirectory: this.path(this.serviceSpec.outdir), + run: 'npx projen nx compile', + }, + { + name: 'Upload base database', + uses: 'actions/upload-artifact@v3', + with: { + name: 'db.base.json.gz', + path: this.path(this.serviceSpec.outdir + '/db.json.gz'), + }, + }, + ], + }); + } + + private diffDatabase() { + this.workflow.addJob('diff-db', { + needs: ['build', 'base-database'], + if: '!(needs.build.outputs.self_mutation_happened)', + runsOn: this.workflowRunsOn, + env: { CI: 'true' }, + permissions: { + contents: pj.github.workflows.JobPermission.WRITE, + }, + steps: [ + { + name: 'Checkout', + uses: 'actions/checkout@v3', + with: { + ref: '${{ github.event.pull_request.head.ref }}', + repository: '${{ github.event.pull_request.head.repo.full_name }}', + lfs: false, + }, + }, + { + name: 'Install dependencies', + run: 'yarn install --check-files', + }, + { + name: 'Build diff-db', + workingDirectory: this.path(this.importers.outdir), + run: 'npx projen nx compile', + }, + { + name: 'Download base database', + uses: 'actions/download-artifact@v3', + with: { + name: 'db.base.json.gz', + path: '${{ runner.temp }}', + }, + }, + { + name: 'Download head database', + uses: 'actions/download-artifact@v3', + with: { + name: 'db.head.json.gz', + path: '${{ runner.temp }}', + }, + }, + { + name: 'Diff databases', + workingDirectory: this.path(this.importers.outdir), + run: './bin/diff-db ${{ runner.temp }}/db.base.json.gz ${{ runner.temp }}/db.head.json.gz > ${{ runner.temp }}/DIFF', + }, + { + id: 'diff-db', + run: [ + 'echo "diff=$(cat ${{ runner.temp }}/DIFF)" >> $GITHUB_OUTPUT', + 'echo "\\`\\`\\`\\n$(cat ${{ runner.temp }}/DIFF)\\n\\`\\`\\`\\" >> $GITHUB_STEP_SUMMARY', + ].join('\n'), + }, + + { + name: 'Comment diff', + if: '${{ steps.diff-db.outputs.diff }}', + uses: 'thollander/actions-comment-pull-request@v2', + with: { + comment_tag: 'diff-db', + message: + 'Model database diff introduced between base and head branch:\n```\n${{ steps.diff-db.outputs.diff }}\n```\n', + }, + }, + ], + }); + } +} diff --git a/projenrc/index.ts b/projenrc/index.ts index 39812841b..4c3be1816 100644 --- a/projenrc/index.ts +++ b/projenrc/index.ts @@ -1,3 +1,4 @@ export * from './aws-cdk-integration-test'; +export * from './diff-db'; export * from './monorepo'; export * from './workspace';