From efd8251e7633214006c7d92c247079ee09c65b99 Mon Sep 17 00:00:00 2001 From: Joy Liu <34288846+joyliu-q@users.noreply.github.com> Date: Fri, 8 Apr 2022 16:54:55 -0400 Subject: [PATCH] [Kittyhawk] Configure version w Projen (#132) * :new: Configure version w Projen * :art: WIP: Address changes * chore(release): 1.2.0 * :art: It works now * :art: Clean-up * :art: Same thing w Kraken * :art: lint -_- * :art: Bump version & reconfig --- cdk/kittyhawk/.projenrc.js | 1 + cdk/kittyhawk/.versionrc.json | 18 --- cdk/kittyhawk/CHANGELOG.md | 5 + cdk/kittyhawk/version.json | 1 - cdk/kraken/.projenrc.js | 1 + cdk/kraken/CHANGELOG.md | 4 + cdk/kraken/package.json | 2 +- cdk/kraken/src/auto-approve.ts | 20 +-- cdk/kraken/src/cdk.ts | 127 +++++++++--------- cdk/kraken/src/deploy.ts | 34 ++--- cdk/kraken/src/django-project.ts | 29 ++-- cdk/kraken/src/django.ts | 54 ++++---- cdk/kraken/src/docker.ts | 74 +++++----- cdk/kraken/src/index.ts | 26 ++-- cdk/kraken/src/integration-tests.ts | 71 +++++----- cdk/kraken/src/labs-application.ts | 101 +++++++------- .../src/postintegrationimagepublishjob.ts | 41 +++--- cdk/kraken/src/pypi.ts | 72 +++++----- cdk/kraken/src/react-project.ts | 29 ++-- cdk/kraken/src/react.ts | 73 +++++----- cdk/kraken/src/utils.ts | 3 +- cdk/kraken/test/auto-approve.test.ts | 19 ++- cdk/kraken/test/cdk.test.ts | 21 ++- cdk/kraken/test/custom.test.ts | 74 +++++----- cdk/kraken/test/django-project.test.ts | 40 +++--- cdk/kraken/test/django.test.ts | 36 +++-- cdk/kraken/test/docker.test.ts | 31 +++-- cdk/kraken/test/integration-tests.test.ts | 33 +++-- cdk/kraken/test/labs-application.test.ts | 37 ++--- cdk/kraken/test/pypi.test.ts | 17 +-- cdk/kraken/test/react-project.test.ts | 36 +++-- cdk/kraken/test/react.test.ts | 14 +- cdk/kraken/test/utils.test.ts | 26 ++-- cdk/kraken/test/utils.ts | 18 ++- 34 files changed, 636 insertions(+), 552 deletions(-) delete mode 100644 cdk/kittyhawk/.versionrc.json delete mode 100644 cdk/kittyhawk/version.json diff --git a/cdk/kittyhawk/.projenrc.js b/cdk/kittyhawk/.projenrc.js index f48748ae..b3278da4 100644 --- a/cdk/kittyhawk/.projenrc.js +++ b/cdk/kittyhawk/.projenrc.js @@ -15,6 +15,7 @@ const project = new TypeScriptProject({ }, }); +project.addFields({['version']: '1.1.3'}); project.prettier?.ignoreFile?.addPatterns('src/imports'); project.testTask.steps.forEach(step => { if (step.exec) { diff --git a/cdk/kittyhawk/.versionrc.json b/cdk/kittyhawk/.versionrc.json deleted file mode 100644 index 41c43f8c..00000000 --- a/cdk/kittyhawk/.versionrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "packageFiles": [ - { - "filename": "version.json", - "type": "json" - } - ], - "bumpFiles": [ - { - "filename": "version.json", - "type": "json" - } - ], - "commitAll": true, - "scripts": { - "postbump": "npx projen && git add ." - } -} diff --git a/cdk/kittyhawk/CHANGELOG.md b/cdk/kittyhawk/CHANGELOG.md index 34e2ccef..e40476fe 100644 --- a/cdk/kittyhawk/CHANGELOG.md +++ b/cdk/kittyhawk/CHANGELOG.md @@ -1,4 +1,9 @@ # Changelog + +## 1.1.3 (2022-04-08) + +* Upgrade dependencies and fix projen version configuration + ## 1.1.2 (2022-04-03) * Dependency updates * Move cdk8s-cli from `devDependencies` to `dependencies` diff --git a/cdk/kittyhawk/version.json b/cdk/kittyhawk/version.json deleted file mode 100644 index 88f49c1a..00000000 --- a/cdk/kittyhawk/version.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"1.1.0"} diff --git a/cdk/kraken/.projenrc.js b/cdk/kraken/.projenrc.js index 8ed165e3..a8dd1404 100644 --- a/cdk/kraken/.projenrc.js +++ b/cdk/kraken/.projenrc.js @@ -12,6 +12,7 @@ const project = new TypeScriptProject({ ...common.options, }); +project.addFields({['version']: '0.8.6'}); project.prettier?.ignoreFile?.addPatterns('src/imports'); project.testTask.steps.forEach(step => { if (step.exec) { diff --git a/cdk/kraken/CHANGELOG.md b/cdk/kraken/CHANGELOG.md index 7d696afa..370c3704 100644 --- a/cdk/kraken/CHANGELOG.md +++ b/cdk/kraken/CHANGELOG.md @@ -2,6 +2,10 @@ ## X.Y.Z (UNRELEASED) +## 0.8.6 (2022-04-08) + +* Upgrade dependencies and fix projen version configuration + ## 0.8.5 (2022-04-05) * CDK publish: fix conditional publish check diff --git a/cdk/kraken/package.json b/cdk/kraken/package.json index f30423bd..4c67044c 100644 --- a/cdk/kraken/package.json +++ b/cdk/kraken/package.json @@ -63,7 +63,7 @@ "main": "lib/index.js", "license": "MIT", "homepage": "https://kraken.pennlabs.org", - "version": "0.0.0", + "version": "0.8.6", "jest": { "testMatch": [ "/src/**/__tests__/**/*.ts?(x)", diff --git a/cdk/kraken/src/auto-approve.ts b/cdk/kraken/src/auto-approve.ts index fedd2075..49fb35ec 100644 --- a/cdk/kraken/src/auto-approve.ts +++ b/cdk/kraken/src/auto-approve.ts @@ -1,5 +1,5 @@ -import { Workflow, Stack, WorkflowProps, Job } from 'cdkactions'; -import { Construct } from 'constructs'; +import { Workflow, Stack, WorkflowProps, Job } from "cdkactions"; +import { Construct } from "constructs"; /** * Auto-approve PRs opened by dependabot. Used to fulfil requirements @@ -12,21 +12,21 @@ export class AutoApproveStack extends Stack { * @param overrides Optional overrides for the stack. */ public constructor(scope: Construct, overrides?: Partial) { - super(scope, 'autoapprove'); - const workflow = new Workflow(this, 'autoapprove', { - name: 'Auto Approve dependabot PRs', - on: 'pullRequest', + super(scope, "autoapprove"); + const workflow = new Workflow(this, "autoapprove", { + name: "Auto Approve dependabot PRs", + on: "pullRequest", ...overrides, }); - new Job(workflow, 'approve', { - runsOn: 'ubuntu-latest', + new Job(workflow, "approve", { + runsOn: "ubuntu-latest", steps: [ { - uses: 'hmarr/auto-approve-action@v2.0.0', + uses: "hmarr/auto-approve-action@v2.0.0", if: "github.actor == 'dependabot[bot]'", with: { - 'github-token': '${{ secrets.BOT_GITHUB_PAT }}', + "github-token": "${{ secrets.BOT_GITHUB_PAT }}", }, }, ], diff --git a/cdk/kraken/src/cdk.ts b/cdk/kraken/src/cdk.ts index 606c811e..206dd63e 100644 --- a/cdk/kraken/src/cdk.ts +++ b/cdk/kraken/src/cdk.ts @@ -1,6 +1,6 @@ -import { CheckoutJob, Workflow, Stack, WorkflowProps } from 'cdkactions'; -import { Construct } from 'constructs'; -import dedent from 'ts-dedent'; +import { CheckoutJob, Workflow, Stack, WorkflowProps } from "cdkactions"; +import { Construct } from "constructs"; +import dedent from "ts-dedent"; /** * Optional props to configure the CDK publish stack. @@ -30,11 +30,16 @@ export class CDKPublishStack extends Stack { * @param config Optional configuration for the cdk publish stack. * @param overrides Optional overrides for the stack. */ - public constructor(scope: Construct, id: string, config?: CDKPublishStackProps, overrides?: Partial) { + public constructor( + scope: Construct, + id: string, + config?: CDKPublishStackProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - defaultBranch: 'master', - nodeVersion: '14', + defaultBranch: "master", + nodeVersion: "14", ...config, }; const path = `cdk/${id}`; @@ -48,78 +53,80 @@ export class CDKPublishStack extends Stack { }, ...overrides, }); - new CheckoutJob(workflow, 'publish', { - runsOn: 'ubuntu-latest', - steps: [{ - name: 'Cache', - uses: 'actions/cache@v2', - with: { - path: '**/node_modules', - key: `v0-\${{ hashFiles('${path}/yarn.lock') }}`, + new CheckoutJob(workflow, "publish", { + runsOn: "ubuntu-latest", + steps: [ + { + name: "Cache", + uses: "actions/cache@v2", + with: { + path: "**/node_modules", + key: `v0-\${{ hashFiles('${path}/yarn.lock') }}`, + }, }, - }, - { - name: 'Install Dependencies', - run: dedent`cd ${path} + { + name: "Install Dependencies", + run: dedent`cd ${path} yarn install --frozen-lockfile`, - }, - { - name: 'Test', - run: dedent`cd ${path} + }, + { + name: "Test", + run: dedent`cd ${path} yarn test`, - }, - { - name: 'Upload Code Coverage', - run: dedent`ROOT=$(pwd) + }, + { + name: "Upload Code Coverage", + run: dedent`ROOT=$(pwd) cd ${path} yarn run codecov -p $ROOT -F ${id}`, - }, - { - name: 'Install jq', - run: dedent` + }, + { + name: "Install jq", + run: dedent` curl -sSLo /usr/bin/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 chmod +x /usr/bin/jq`, - }, - { - name: 'Check if version is already published to npm', - id: 'version_check', - run: dedent`cd ${path} + }, + { + name: "Check if version is already published to npm", + id: "version_check", + run: dedent`cd ${path} PACKAGE=\$(node -p "require('./package.json').name") VERSION=\$(node -p "require('./package.json').version") NEW_VERSION=\$(yarn info $PACKAGE versions --json | jq ".data | any(. == \\"$VERSION\\") | not") echo "::set-output name=NEW_VERSION::$NEW_VERSION"`, - }, - { - name: 'Publish to npm', - run: dedent`cd ${path} + }, + { + name: "Publish to npm", + run: dedent`cd ${path} yarn compile yarn package mv dist/js/*.tgz dist/js/${id}.tgz yarn publish --non-interactive --access public dist/js/${id}.tgz`, - if: `github.ref == 'refs/heads/${fullConfig.defaultBranch}' && steps.version_check.outputs.NEW_VERSION == 'true'`, - env: { - NPM_AUTH_TOKEN: '${{ secrets.NPM_AUTH_TOKEN }}', + if: `github.ref == 'refs/heads/${fullConfig.defaultBranch}' && steps.version_check.outputs.NEW_VERSION == 'true'`, + env: { + NPM_AUTH_TOKEN: "${{ secrets.NPM_AUTH_TOKEN }}", + }, }, - }, - { - name: 'Build docs', - run: dedent`cd ${path} + { + name: "Build docs", + run: dedent`cd ${path} yarn docgen`, - }, - { - name: 'Publish docs', - if: `github.ref == 'refs/heads/${fullConfig.defaultBranch}'`, - uses: 'peaceiris/actions-gh-pages@v3', - with: { - personal_token: '${{ secrets.BOT_GITHUB_PAT }}', - external_repository: `pennlabs/${id}-docs`, - cname: `${id}.pennlabs.org`, - publish_branch: 'master', - publish_dir: `${path}/docs`, - user_name: 'github-actions', - user_email: 'github-actions[bot]@users.noreply.github.com', }, - }], + { + name: "Publish docs", + if: `github.ref == 'refs/heads/${fullConfig.defaultBranch}'`, + uses: "peaceiris/actions-gh-pages@v3", + with: { + personal_token: "${{ secrets.BOT_GITHUB_PAT }}", + external_repository: `pennlabs/${id}-docs`, + cname: `${id}.pennlabs.org`, + publish_branch: "master", + publish_dir: `${path}/docs`, + user_name: "github-actions", + user_email: "github-actions[bot]@users.noreply.github.com", + }, + }, + ], container: { image: `node:${fullConfig.nodeVersion}`, }, diff --git a/cdk/kraken/src/deploy.ts b/cdk/kraken/src/deploy.ts index 2b8de2c3..19957bf8 100644 --- a/cdk/kraken/src/deploy.ts +++ b/cdk/kraken/src/deploy.ts @@ -1,5 +1,5 @@ -import { CheckoutJob, Workflow, JobProps } from 'cdkactions'; -import dedent from 'ts-dedent'; +import { CheckoutJob, Workflow, JobProps } from "cdkactions"; +import dedent from "ts-dedent"; /** * Optional props to configure the deploy job. @@ -28,21 +28,25 @@ export class DeployJob extends CheckoutJob { * @param config Optional configuration for the deploy job. * @param overrides Optional overrides for the job. */ - public constructor(scope: Workflow, config?: DeployJobProps, overrides?: Partial) { + public constructor( + scope: Workflow, + config?: DeployJobProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - deployTag: '${{ github.sha }}', - defaultBranch: 'master', + deployTag: "${{ github.sha }}", + defaultBranch: "master", ...config, }; - super(scope, 'deploy', { - runsOn: 'ubuntu-latest', + super(scope, "deploy", { + runsOn: "ubuntu-latest", if: `github.ref == 'refs/heads/${fullConfig.defaultBranch}'`, steps: [ { - id: 'synth', - name: 'Synth cdk8s manifests', + id: "synth", + name: "Synth cdk8s manifests", run: dedent`cd k8s yarn install --frozen-lockfile @@ -55,12 +59,12 @@ export class DeployJob extends CheckoutJob { yarn build`, env: { GIT_SHA: fullConfig.deployTag, - REPOSITORY: '${{ github.repository }}', - AWS_ACCOUNT_ID: '${{ secrets.AWS_ACCOUNT_ID }}', + REPOSITORY: "${{ github.repository }}", + AWS_ACCOUNT_ID: "${{ secrets.AWS_ACCOUNT_ID }}", }, }, { - name: 'Deploy', + name: "Deploy", run: dedent`aws eks --region us-east-1 update-kubeconfig --name production --role-arn arn:aws:iam::\${AWS_ACCOUNT_ID}:role/kubectl # get repo name from synth step @@ -70,9 +74,9 @@ export class DeployJob extends CheckoutJob { kubectl apply -f k8s/dist/ -l app.kubernetes.io/component=certificate kubectl apply -f k8s/dist/ --prune -l app.kubernetes.io/part-of=$RELEASE_NAME`, env: { - AWS_ACCOUNT_ID: '${{ secrets.AWS_ACCOUNT_ID }}', - AWS_ACCESS_KEY_ID: '${{ secrets.GH_AWS_ACCESS_KEY_ID }}', - AWS_SECRET_ACCESS_KEY: '${{ secrets.GH_AWS_SECRET_ACCESS_KEY }}', + AWS_ACCOUNT_ID: "${{ secrets.AWS_ACCOUNT_ID }}", + AWS_ACCESS_KEY_ID: "${{ secrets.GH_AWS_ACCESS_KEY_ID }}", + AWS_SECRET_ACCESS_KEY: "${{ secrets.GH_AWS_SECRET_ACCESS_KEY }}", }, }, ], diff --git a/cdk/kraken/src/django-project.ts b/cdk/kraken/src/django-project.ts index 44112534..b7c50e46 100644 --- a/cdk/kraken/src/django-project.ts +++ b/cdk/kraken/src/django-project.ts @@ -1,8 +1,7 @@ -import { JobProps, Workflow } from 'cdkactions'; -import { DjangoCheckJob, DjangoCheckJobProps } from './django'; -import { DockerPublishJob, DockerPublishJobProps } from './docker'; -import { buildId } from './utils'; - +import { JobProps, Workflow } from "cdkactions"; +import { DjangoCheckJob, DjangoCheckJobProps } from "./django"; +import { DockerPublishJob, DockerPublishJobProps } from "./docker"; +import { buildId } from "./utils"; /** * Props to configure the DjangoProject. @@ -75,8 +74,8 @@ export class DjangoProject { public constructor(workflow: Workflow, config: DjangoProjectProps) { // Build config const fullConfig: Required = { - id: '', - path: '.', + id: "", + path: ".", checkProps: {}, checkOverrides: {}, publishProps: {}, @@ -85,26 +84,30 @@ export class DjangoProject { }; // Add jobs - const djangoCheckJob = new DjangoCheckJob(workflow, + const djangoCheckJob = new DjangoCheckJob( + workflow, { id: fullConfig.id, projectName: fullConfig.projectName, path: fullConfig.path, ...config.checkProps, }, - fullConfig.checkOverrides, + fullConfig.checkOverrides ); - const publishJob = new DockerPublishJob(workflow, buildId('backend', fullConfig.id), + const publishJob = new DockerPublishJob( + workflow, + buildId("backend", fullConfig.id), { imageName: fullConfig.imageName, path: fullConfig.path, ...fullConfig.publishProps, }, { - needs: djangoCheckJob.id - , ...fullConfig.publishOverrides, - }); + needs: djangoCheckJob.id, + ...fullConfig.publishOverrides, + } + ); // Set public fields this.publishJobId = publishJob.id; diff --git a/cdk/kraken/src/django.ts b/cdk/kraken/src/django.ts index 573da666..31240941 100644 --- a/cdk/kraken/src/django.ts +++ b/cdk/kraken/src/django.ts @@ -1,6 +1,6 @@ -import { CheckoutJob, Workflow, StepsProps, JobProps } from 'cdkactions'; -import dedent from 'ts-dedent'; -import { buildId, buildName } from './utils'; +import { CheckoutJob, Workflow, StepsProps, JobProps } from "cdkactions"; +import dedent from "ts-dedent"; +import { buildId, buildName } from "./utils"; /** * Props to configure the Django check job. @@ -55,12 +55,16 @@ export class DjangoCheckJob extends CheckoutJob { * @param config Configuration for the Django check job. * @param overrides Optional overrides for the job. */ - public constructor(scope: Workflow, config: DjangoCheckJobProps, overrides?: Partial) { + public constructor( + scope: Workflow, + config: DjangoCheckJobProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - id: '', - pythonVersion: '3.8-buster', - path: '.', + id: "", + pythonVersion: "3.8-buster", + path: ".", black: true, flake8: true, ...config, @@ -69,15 +73,15 @@ export class DjangoCheckJob extends CheckoutJob { // Define steps const steps: StepsProps[] = [ { - name: 'Cache', - uses: 'actions/cache@v2', + name: "Cache", + uses: "actions/cache@v2", with: { - path: '~/.local/share/virtualenvs', + path: "~/.local/share/virtualenvs", key: `v0-\${{ hashFiles('${fullConfig.path}/Pipfile.lock') }}`, }, }, { - name: 'Install Dependencies', + name: "Install Dependencies", run: dedent`cd ${fullConfig.path} pip install pipenv pipenv install --deploy --dev`, @@ -85,55 +89,55 @@ export class DjangoCheckJob extends CheckoutJob { ]; if (fullConfig.flake8) { steps.push({ - name: 'Lint (flake8)', + name: "Lint (flake8)", run: dedent`cd ${fullConfig.path} pipenv run flake8 .`, }); } if (fullConfig.black) { steps.push({ - name: 'Lint (black)', + name: "Lint (black)", run: dedent`cd ${fullConfig.path} pipenv run black --check .`, }); } steps.push({ - name: 'Test (run in parallel)', + name: "Test (run in parallel)", run: dedent`cd ${fullConfig.path} pipenv run coverage run --concurrency=multiprocessing manage.py test --settings=${fullConfig.projectName}.settings.ci --parallel pipenv run coverage combine`, }); steps.push({ - name: 'Upload Code Coverage', + name: "Upload Code Coverage", run: dedent`ROOT=$(pwd) cd ${fullConfig.path} pipenv run codecov --root $ROOT --flags backend`, }); // Create Job - super(scope, buildId('django-check', fullConfig.id), { - name: buildName('Django Check', fullConfig.id), - runsOn: 'ubuntu-latest', + super(scope, buildId("django-check", fullConfig.id), { + name: buildName("Django Check", fullConfig.id), + runsOn: "ubuntu-latest", steps, container: { image: `python:${fullConfig.pythonVersion}`, }, env: { - DATABASE_URL: 'postgres://postgres:postgres@postgres:5432/postgres', + DATABASE_URL: "postgres://postgres:postgres@postgres:5432/postgres", }, services: { postgres: { - image: 'postgres:12', + image: "postgres:12", env: { - POSTGRES_USER: 'postgres', - POSTGRES_DB: 'postgres', - POSTGRES_PASSWORD: 'postgres', + POSTGRES_USER: "postgres", + POSTGRES_DB: "postgres", + POSTGRES_PASSWORD: "postgres", }, - options: '--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5', + options: + "--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5", }, }, ...overrides, }); } } - diff --git a/cdk/kraken/src/docker.ts b/cdk/kraken/src/docker.ts index b6750751..0fc0bc88 100644 --- a/cdk/kraken/src/docker.ts +++ b/cdk/kraken/src/docker.ts @@ -1,6 +1,5 @@ -import { CheckoutJob, Workflow, JobProps, StepsProps } from 'cdkactions'; -import { buildId, buildName } from './utils'; - +import { CheckoutJob, Workflow, JobProps, StepsProps } from "cdkactions"; +import { buildId, buildName } from "./utils"; /** * Props to configure the Docker publish job. @@ -77,64 +76,79 @@ export class DockerPublishJob extends CheckoutJob { * @param config Configuration for the docker publish job. * @param overrides Optional overrides for the job. */ - public constructor(scope: Workflow, id: string, config: DockerPublishJobProps, overrides?: Partial) { + public constructor( + scope: Workflow, + id: string, + config: DockerPublishJobProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - path: '.', + path: ".", push: "${{ github.ref == 'refs/heads/master' }}", - tags: 'latest,${{ github.sha }}', - username: '${{ secrets.DOCKER_USERNAME }}', - password: '${{ secrets.DOCKER_PASSWORD }}', - dockerfile: 'Dockerfile', + tags: "latest,${{ github.sha }}", + username: "${{ secrets.DOCKER_USERNAME }}", + password: "${{ secrets.DOCKER_PASSWORD }}", + dockerfile: "Dockerfile", cache: true, noPublish: false, ...config, }; - const formattedName = fullConfig.noPublish ? buildName('Build', id) : buildName('Publish', id); - const formattedId = fullConfig.noPublish ? buildId('build', id) : buildId('publish', id); + const formattedName = fullConfig.noPublish + ? buildName("Build", id) + : buildName("Publish", id); + const formattedId = fullConfig.noPublish + ? buildId("build", id) + : buildId("publish", id); // Define docker action with const imageName = `pennlabs/${fullConfig.imageName}`; const dockerWith: any = { - 'context': fullConfig.path, - 'file': `${fullConfig.path}/${fullConfig.dockerfile}`, - 'push': fullConfig.push, - 'cache-from': 'type=local,src=/tmp/.buildx-cache', - 'cache-to': 'type=local,dest=/tmp/.buildx-cache', + context: fullConfig.path, + file: `${fullConfig.path}/${fullConfig.dockerfile}`, + push: fullConfig.push, + "cache-from": "type=local,src=/tmp/.buildx-cache", + "cache-to": "type=local,dest=/tmp/.buildx-cache", }; if (fullConfig.cache) { - dockerWith['cache-from'] = dockerWith['cache-from'].concat(`,type=registry,ref=${imageName}:latest`); + dockerWith["cache-from"] = dockerWith["cache-from"].concat( + `,type=registry,ref=${imageName}:latest` + ); } // Build tags string - const tagsString = (tags: string) => tags.split(',').map(tag => `${imageName}:${tag}`).join(); + const tagsString = (tags: string) => + tags + .split(",") + .map((tag) => `${imageName}:${tag}`) + .join(); dockerWith.tags = tagsString(fullConfig.tags); // Define steps const steps: StepsProps[] = [ { - uses: 'docker/setup-qemu-action@v1', + uses: "docker/setup-qemu-action@v1", }, { - uses: 'docker/setup-buildx-action@v1', + uses: "docker/setup-buildx-action@v1", }, { - name: 'Cache Docker layers', - uses: 'actions/cache@v2', + name: "Cache Docker layers", + uses: "actions/cache@v2", with: { - path: '/tmp/.buildx-cache', + path: "/tmp/.buildx-cache", key: `buildx-${formattedId}`, }, }, { - uses: 'docker/login-action@v1', + uses: "docker/login-action@v1", with: { username: fullConfig.username, password: fullConfig.password, }, }, { - name: 'Build/Publish', - uses: 'docker/build-push-action@v2', + name: "Build/Publish", + uses: "docker/build-push-action@v2", with: dockerWith, }, ]; @@ -142,12 +156,12 @@ export class DockerPublishJob extends CheckoutJob { // If publishing isn't wanted if (fullConfig.noPublish) { dockerWith.push = false; - dockerWith.outputs = 'type=docker,dest=/tmp/image.tar'; + dockerWith.outputs = "type=docker,dest=/tmp/image.tar"; steps.push({ - uses: 'actions/upload-artifact@v2', + uses: "actions/upload-artifact@v2", with: { name: formattedId, - path: '/tmp/image.tar', + path: "/tmp/image.tar", }, }); steps.splice(3, 1); @@ -156,7 +170,7 @@ export class DockerPublishJob extends CheckoutJob { // Create job super(scope, formattedId, { name: formattedName, - runsOn: 'ubuntu-latest', + runsOn: "ubuntu-latest", steps, ...overrides, }); diff --git a/cdk/kraken/src/index.ts b/cdk/kraken/src/index.ts index 854cb63e..2b192394 100644 --- a/cdk/kraken/src/index.ts +++ b/cdk/kraken/src/index.ts @@ -1,13 +1,13 @@ -export * from './auto-approve'; -export * from './cdk'; -export * from './deploy'; -export * from './django-project'; -export * from './django'; -export * from './docker'; -export * from './integration-tests'; -export * from './labs-application'; -export * from './postintegrationimagepublishjob'; -export * from './pypi'; -export * from './react-project'; -export * from './react'; -export * from './utils'; +export * from "./auto-approve"; +export * from "./cdk"; +export * from "./deploy"; +export * from "./django-project"; +export * from "./django"; +export * from "./docker"; +export * from "./integration-tests"; +export * from "./labs-application"; +export * from "./postintegrationimagepublishjob"; +export * from "./pypi"; +export * from "./react-project"; +export * from "./react"; +export * from "./utils"; diff --git a/cdk/kraken/src/integration-tests.ts b/cdk/kraken/src/integration-tests.ts index 1d3f5261..96ce6b3b 100644 --- a/cdk/kraken/src/integration-tests.ts +++ b/cdk/kraken/src/integration-tests.ts @@ -1,8 +1,7 @@ -import { Workflow, JobProps, CheckoutJob } from 'cdkactions'; -import dedent from 'ts-dedent'; -import { PostIntegrationPublishJob } from './postintegrationimagepublishjob'; -import { buildId, buildName } from './utils'; - +import { Workflow, JobProps, CheckoutJob } from "cdkactions"; +import dedent from "ts-dedent"; +import { PostIntegrationPublishJob } from "./postintegrationimagepublishjob"; +import { buildId, buildName } from "./utils"; /** * Optional props to configure the IntegrationTestsJob. @@ -56,71 +55,77 @@ export class IntegrationTestsJob extends CheckoutJob { * @param config Configuration for the integration tests. * @param overrides Optional Overrides for the job. */ - public constructor(scope: Workflow, config: IntegrationTestsJobProps, overrides?: Partial) { + public constructor( + scope: Workflow, + config: IntegrationTestsJobProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - id: '', + id: "", createPostIntegrationPublishJob: true, ...config, }; // Create Job - super(scope, buildId('integration-tests', fullConfig.id), { - name: buildName('Integration Tests', fullConfig.id), - runsOn: 'ubuntu-latest', + super(scope, buildId("integration-tests", fullConfig.id), { + name: buildName("Integration Tests", fullConfig.id), + runsOn: "ubuntu-latest", steps: [ { - uses: 'actions/download-artifact@v2', + uses: "actions/download-artifact@v2", }, { - name: 'Load docker images', - run: fullConfig.dockerBuildIds.map(id => `docker load --input ${id}/image.tar`).join('\n'), + name: "Load docker images", + run: fullConfig.dockerBuildIds + .map((id) => `docker load --input ${id}/image.tar`) + .join("\n"), }, { - name: 'Run docker compose', + name: "Run docker compose", run: dedent`mkdir -p /tmp/test-results docker-compose -f docker-compose.test.yaml up -d`, }, { - name: 'Wait for backend', + name: "Wait for backend", run: dedent`for try in {1..20}; do docker-compose -f docker-compose.test.yaml exec -T backend python manage.py migrate --check && break sleep 5 done`, }, { - name: 'Populate backend', - run: 'docker-compose -f docker-compose.test.yaml exec -T backend python manage.py populate', + name: "Populate backend", + run: "docker-compose -f docker-compose.test.yaml exec -T backend python manage.py populate", }, { - name: 'Run integration tests', + name: "Run integration tests", run: fullConfig.testCommand, }, { - name: 'Delete artifacts when no longer needed', + name: "Delete artifacts when no longer needed", if: "failure() || github.ref != 'refs/heads/master'", - uses: 'geekyeggo/delete-artifact@v1', + uses: "geekyeggo/delete-artifact@v1", with: { - name: fullConfig.dockerBuildIds.join('\n'), + name: fullConfig.dockerBuildIds.join("\n"), }, }, { - name: 'Print logs on failure', - if: 'failure()', - run: 'docker-compose -f docker-compose.test.yaml logs', + name: "Print logs on failure", + if: "failure()", + run: "docker-compose -f docker-compose.test.yaml logs", }, { - name: 'Upload artifacts on failure', - if: 'failure()', - uses: 'actions/upload-artifact@v2', + name: "Upload artifacts on failure", + if: "failure()", + uses: "actions/upload-artifact@v2", with: { - name: 'cypress-output', - path: '/tmp/test-results', + name: "cypress-output", + path: "/tmp/test-results", }, }, ], env: { - GIT_SHA: '${{ github.sha }}', + GIT_SHA: "${{ github.sha }}", }, ...overrides, }); @@ -130,14 +135,16 @@ export class IntegrationTestsJob extends CheckoutJob { // Optionally create post integration publish job function if (fullConfig.createPostIntegrationPublishJob) { - const postIntegrationPublishJob = new PostIntegrationPublishJob(scope, + const postIntegrationPublishJob = new PostIntegrationPublishJob( + scope, { dockerBuildIds: fullConfig.dockerBuildIds, dockerImages: fullConfig.dockerImages, }, { needs: this.id, - }); + } + ); this.finalJobId = postIntegrationPublishJob.id; } } diff --git a/cdk/kraken/src/labs-application.ts b/cdk/kraken/src/labs-application.ts index 1627b257..5cc49a0c 100644 --- a/cdk/kraken/src/labs-application.ts +++ b/cdk/kraken/src/labs-application.ts @@ -1,13 +1,15 @@ -import { Workflow, JobProps, WorkflowProps, Stack } from 'cdkactions'; -import { Construct } from 'constructs'; -import { DeployJob, DeployJobProps } from './deploy'; -import { DjangoCheckJobProps } from './django'; -import { DjangoProject } from './django-project'; -import { DockerPublishJobProps } from './docker'; -import { IntegrationTestsJob, IntegrationTestsJobProps } from './integration-tests'; -import { ReactCheckJobProps } from './react'; -import { ReactProject } from './react-project'; - +import { Workflow, JobProps, WorkflowProps, Stack } from "cdkactions"; +import { Construct } from "constructs"; +import { DeployJob, DeployJobProps } from "./deploy"; +import { DjangoCheckJobProps } from "./django"; +import { DjangoProject } from "./django-project"; +import { DockerPublishJobProps } from "./docker"; +import { + IntegrationTestsJob, + IntegrationTestsJobProps, +} from "./integration-tests"; +import { ReactCheckJobProps } from "./react"; +import { ReactProject } from "./react-project"; /** * Props to configure the LabsApplication stack @@ -118,11 +120,15 @@ export class LabsApplicationStack extends Stack { * @param config Configuration for the LabsApplication stack. * @param overrides Optional overrides for the workflow. */ - public constructor(scope: Construct, config: LabsApplicationStackProps, overrides?: Partial) { + public constructor( + scope: Construct, + config: LabsApplicationStackProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - backendPath: 'backend', - frontendPath: 'frontend', + backendPath: "backend", + frontendPath: "frontend", integrationTests: false, djangoCheckProps: {}, djangoCheckOverrides: {}, @@ -142,50 +148,54 @@ export class LabsApplicationStack extends Stack { fullConfig.reactDockerProps.noPublish = fullConfig.integrationTests; // Create stack - super(scope, 'application'); - const workflow = new Workflow(this, 'build-and-deploy', { - name: 'Build and Deploy', - on: 'push', + super(scope, "application"); + const workflow = new Workflow(this, "build-and-deploy", { + name: "Build and Deploy", + on: "push", ...overrides, }); // Django - const djangoProject = new DjangoProject(workflow, - { - projectName: fullConfig.djangoProjectName, - path: fullConfig.backendPath, - imageName: `${fullConfig.dockerImageBaseName}-backend`, - checkProps: fullConfig.djangoCheckProps, - checkOverrides: fullConfig.djangoCheckOverrides, - publishProps: fullConfig.djangoDockerProps, - publishOverrides: fullConfig.djangoDockerOverrides, - }); + const djangoProject = new DjangoProject(workflow, { + projectName: fullConfig.djangoProjectName, + path: fullConfig.backendPath, + imageName: `${fullConfig.dockerImageBaseName}-backend`, + checkProps: fullConfig.djangoCheckProps, + checkOverrides: fullConfig.djangoCheckOverrides, + publishProps: fullConfig.djangoDockerProps, + publishOverrides: fullConfig.djangoDockerOverrides, + }); // React - const reactProject = new ReactProject(workflow, - { - path: fullConfig.frontendPath, - imageName: `${fullConfig.dockerImageBaseName}-frontend`, - checkProps: fullConfig.reactCheckProps, - checkOverrides: fullConfig.reactCheckOverrides, - publishProps: fullConfig.reactDockerProps, - publishOverrides: fullConfig.reactDockerOverrides, - }, - ); + const reactProject = new ReactProject(workflow, { + path: fullConfig.frontendPath, + imageName: `${fullConfig.dockerImageBaseName}-frontend`, + checkProps: fullConfig.reactCheckProps, + checkOverrides: fullConfig.reactCheckOverrides, + publishProps: fullConfig.reactDockerProps, + publishOverrides: fullConfig.reactDockerOverrides, + }); let deployNeeds: string[]; if (fullConfig.integrationTests) { - const integrationTest = new IntegrationTestsJob(workflow, + const integrationTest = new IntegrationTestsJob( + workflow, { - dockerBuildIds: [djangoProject.publishJobId, reactProject.publishJobId], - dockerImages: [djangoProject.dockerImageName, reactProject.dockerImageName], + dockerBuildIds: [ + djangoProject.publishJobId, + reactProject.publishJobId, + ], + dockerImages: [ + djangoProject.dockerImageName, + reactProject.dockerImageName, + ], testCommand: 'echo "Add an integration test command" && exit 1', ...fullConfig.integrationProps, }, { ...fullConfig.integrationOverrides, needs: [djangoProject.publishJobId, reactProject.publishJobId], - }, + } ); deployNeeds = [integrationTest.finalJobId]; } else { @@ -193,10 +203,9 @@ export class LabsApplicationStack extends Stack { } // Deploy - new DeployJob(workflow, fullConfig.deployProps, - { - ...fullConfig.deployOverrides, - needs: deployNeeds, - }); + new DeployJob(workflow, fullConfig.deployProps, { + ...fullConfig.deployOverrides, + needs: deployNeeds, + }); } } diff --git a/cdk/kraken/src/postintegrationimagepublishjob.ts b/cdk/kraken/src/postintegrationimagepublishjob.ts index 0efe9b52..ce63ccf0 100644 --- a/cdk/kraken/src/postintegrationimagepublishjob.ts +++ b/cdk/kraken/src/postintegrationimagepublishjob.ts @@ -1,5 +1,4 @@ -import { CheckoutJob, Workflow, JobProps } from 'cdkactions'; - +import { CheckoutJob, Workflow, JobProps } from "cdkactions"; /** * Props to configure the post integration test docker image publish job. @@ -45,44 +44,52 @@ export class PostIntegrationPublishJob extends CheckoutJob { * @param config Configuration for the post integration tests publish job. * @param overrides Optional overrides for the job. */ - public constructor(scope: Workflow, config: PostIntegrationPublishJobProps, overrides?: Partial) { + public constructor( + scope: Workflow, + config: PostIntegrationPublishJobProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - defaultBranch: 'master', - dockerUsername: '${{ secrets.DOCKER_USERNAME }}', - dockerPassword: '${{ secrets.DOCKER_PASSWORD }}', + defaultBranch: "master", + dockerUsername: "${{ secrets.DOCKER_USERNAME }}", + dockerPassword: "${{ secrets.DOCKER_PASSWORD }}", ...config, }; // Create job - super(scope, 'post-integration-publish', { - name: 'Publish Images', - runsOn: 'ubuntu-latest', + super(scope, "post-integration-publish", { + name: "Publish Images", + runsOn: "ubuntu-latest", if: `github.ref == 'refs/heads/${fullConfig.defaultBranch}'`, steps: [ { - uses: 'actions/download-artifact@v2', + uses: "actions/download-artifact@v2", }, { - uses: 'geekyeggo/delete-artifact@v1', + uses: "geekyeggo/delete-artifact@v1", with: { - name: fullConfig.dockerBuildIds.join('\n'), + name: fullConfig.dockerBuildIds.join("\n"), }, }, { - name: 'Load docker images', - run: fullConfig.dockerBuildIds.map(id => `docker load --input ${id}/image.tar`).join('\n'), + name: "Load docker images", + run: fullConfig.dockerBuildIds + .map((id) => `docker load --input ${id}/image.tar`) + .join("\n"), }, { - uses: 'docker/login-action@v1', + uses: "docker/login-action@v1", with: { username: fullConfig.dockerUsername, password: fullConfig.dockerPassword, }, }, { - name: 'Push docker images', - run: fullConfig.dockerImages.map(image => `docker push -a ${image}`).join('\n'), + name: "Push docker images", + run: fullConfig.dockerImages + .map((image) => `docker push -a ${image}`) + .join("\n"), }, ], ...overrides, diff --git a/cdk/kraken/src/pypi.ts b/cdk/kraken/src/pypi.ts index cd4b9cc8..84b13902 100644 --- a/cdk/kraken/src/pypi.ts +++ b/cdk/kraken/src/pypi.ts @@ -1,6 +1,6 @@ -import { CheckoutJob, Workflow, Stack, WorkflowProps } from 'cdkactions'; -import { Construct } from 'constructs'; -import dedent from 'ts-dedent'; +import { CheckoutJob, Workflow, Stack, WorkflowProps } from "cdkactions"; +import { Construct } from "constructs"; +import dedent from "ts-dedent"; /** * Optional props to configure the PyPI publish stack. @@ -30,57 +30,61 @@ export class PyPIPublishStack extends Stack { * @param config Optional configuration for the stack. * @param overrides Optional overrides for the workflow. */ - public constructor(scope: Construct, config?: PyPIPublishStackProps, overrides?: Partial) { + public constructor( + scope: Construct, + config?: PyPIPublishStackProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - pythonVersion: '3.8', - pythonMatrixVersions: ['3.7', '3.8', '3.9', '3.10'], + pythonVersion: "3.8", + pythonMatrixVersions: ["3.7", "3.8", "3.9", "3.10"], ...config, }; - super(scope, 'pypi'); - const workflow = new Workflow(this, 'build-and-publish', { - name: 'Build and Publish', + super(scope, "pypi"); + const workflow = new Workflow(this, "build-and-publish", { + name: "Build and Publish", on: { push: { - branches: ['**'], - tags: ['[0-9]+.[0-9]+.[0-9]+'], + branches: ["**"], + tags: ["[0-9]+.[0-9]+.[0-9]+"], }, }, ...overrides, }); - const testJob = new CheckoutJob(workflow, 'test', { - runsOn: 'ubuntu-latest', + const testJob = new CheckoutJob(workflow, "test", { + runsOn: "ubuntu-latest", strategy: { matrix: { - 'python-version': fullConfig.pythonMatrixVersions, + "python-version": fullConfig.pythonMatrixVersions, }, }, steps: [ { - name: 'Set up Python ${{ matrix.python-version }}', - uses: 'actions/setup-python@v2', + name: "Set up Python ${{ matrix.python-version }}", + uses: "actions/setup-python@v2", with: { - 'python-version': '${{ matrix.python-version }}', + "python-version": "${{ matrix.python-version }}", }, }, { - name: 'Install dependencies', - run: 'pip install poetry tox tox-gh-actions codecov', + name: "Install dependencies", + run: "pip install poetry tox tox-gh-actions codecov", }, { - name: 'Test', - run: 'tox', + name: "Test", + run: "tox", }, { - name: 'Upload Code Coverage', - run: 'codecov', + name: "Upload Code Coverage", + run: "codecov", }, ], }); - new CheckoutJob(workflow, 'publish', { - runsOn: 'ubuntu-latest', + new CheckoutJob(workflow, "publish", { + runsOn: "ubuntu-latest", container: { image: `python:${fullConfig.pythonVersion}`, }, @@ -88,25 +92,25 @@ export class PyPIPublishStack extends Stack { if: "startsWith(github.ref, 'refs/tags')", steps: [ { - name: 'Install dependencies', - run: 'pip install poetry', + name: "Install dependencies", + run: "pip install poetry", }, { - name: 'Verify tag', - shell: 'bash', + name: "Verify tag", + shell: "bash", run: dedent`GIT_TAG=\${GITHUB_REF/refs\\/tags\\//} LIBRARY_VERSION=$(poetry version -s) if [[ "$GIT_TAG" != "$LIBRARY_VERSION" ]]; then echo "Tag ($GIT_TAG) does not match poetry version ($LIBRARY_VERSION)"; exit 1; fi`, }, { - name: 'Build', - run: 'poetry build', + name: "Build", + run: "poetry build", }, { - name: 'Publish', - run: 'poetry publish', + name: "Publish", + run: "poetry publish", env: { - POETRY_PYPI_TOKEN_PYPI: '${{ secrets.PYPI_PASSWORD }}', + POETRY_PYPI_TOKEN_PYPI: "${{ secrets.PYPI_PASSWORD }}", }, }, ], diff --git a/cdk/kraken/src/react-project.ts b/cdk/kraken/src/react-project.ts index c4e3b3b1..22e4e6fb 100644 --- a/cdk/kraken/src/react-project.ts +++ b/cdk/kraken/src/react-project.ts @@ -1,8 +1,7 @@ -import { JobProps, Workflow } from 'cdkactions'; -import { DockerPublishJob, DockerPublishJobProps } from './docker'; -import { ReactCheckJob, ReactCheckJobProps } from './react'; -import { buildId } from './utils'; - +import { JobProps, Workflow } from "cdkactions"; +import { DockerPublishJob, DockerPublishJobProps } from "./docker"; +import { ReactCheckJob, ReactCheckJobProps } from "./react"; +import { buildId } from "./utils"; /** * Props to configure the ReactProject. @@ -70,8 +69,8 @@ export class ReactProject { public constructor(workflow: Workflow, config: ReactProjectProps) { // Build config const fullConfig: Required = { - id: '', - path: '.', + id: "", + path: ".", checkProps: {}, checkOverrides: {}, publishProps: {}, @@ -80,25 +79,29 @@ export class ReactProject { }; // Add jobs - const reactCheckJob = new ReactCheckJob(workflow, + const reactCheckJob = new ReactCheckJob( + workflow, { id: fullConfig.id, path: fullConfig.path, ...config.checkProps, }, - fullConfig.checkOverrides, + fullConfig.checkOverrides ); - const publishJob = new DockerPublishJob(workflow, buildId('frontend', fullConfig.id), + const publishJob = new DockerPublishJob( + workflow, + buildId("frontend", fullConfig.id), { imageName: fullConfig.imageName, path: fullConfig.path, ...fullConfig.publishProps, }, { - needs: reactCheckJob.id - , ...fullConfig.publishOverrides, - }); + needs: reactCheckJob.id, + ...fullConfig.publishOverrides, + } + ); // Set public fields this.publishJobId = publishJob.id; diff --git a/cdk/kraken/src/react.ts b/cdk/kraken/src/react.ts index fc5328b1..2500e5f5 100644 --- a/cdk/kraken/src/react.ts +++ b/cdk/kraken/src/react.ts @@ -1,6 +1,6 @@ -import { Workflow, JobProps, CheckoutJob } from 'cdkactions'; -import dedent from 'ts-dedent'; -import { buildId, buildName } from './utils'; +import { Workflow, JobProps, CheckoutJob } from "cdkactions"; +import dedent from "ts-dedent"; +import { buildId, buildName } from "./utils"; /** * Optional props to configure the React check job. @@ -36,49 +36,54 @@ export class ReactCheckJob extends CheckoutJob { * @param config Optional configuration for the React check job. * @param overrides Optional overrides for the job. */ - public constructor(scope: Workflow, config?: ReactCheckJobProps, overrides?: Partial) { + public constructor( + scope: Workflow, + config?: ReactCheckJobProps, + overrides?: Partial + ) { // Build config const fullConfig: Required = { - id: '', - nodeVersion: '14', - path: '.', + id: "", + nodeVersion: "14", + path: ".", ...config, }; - // Create Job - super(scope, buildId('react-check', fullConfig.id), { - name: buildName('React Check', fullConfig.id), - runsOn: 'ubuntu-latest', - steps: [{ - name: 'Cache', - uses: 'actions/cache@v2', - with: { - path: '**/node_modules', - key: `v0-\${{ hashFiles('${fullConfig.path}/yarn.lock') }}`, + super(scope, buildId("react-check", fullConfig.id), { + name: buildName("React Check", fullConfig.id), + runsOn: "ubuntu-latest", + steps: [ + { + name: "Cache", + uses: "actions/cache@v2", + with: { + path: "**/node_modules", + key: `v0-\${{ hashFiles('${fullConfig.path}/yarn.lock') }}`, + }, }, - }, - { - name: 'Install Dependencies', - run: dedent`cd ${fullConfig.path} + { + name: "Install Dependencies", + run: dedent`cd ${fullConfig.path} yarn install --frozen-lockfile`, - }, - { - name: 'Lint', - run: dedent`cd ${fullConfig.path} + }, + { + name: "Lint", + run: dedent`cd ${fullConfig.path} yarn lint`, - }, - { - name: 'Test', - run: dedent`cd ${fullConfig.path} + }, + { + name: "Test", + run: dedent`cd ${fullConfig.path} yarn test`, - }, - { - name: 'Upload Code Coverage', - run: dedent`ROOT=$(pwd) + }, + { + name: "Upload Code Coverage", + run: dedent`ROOT=$(pwd) cd ${fullConfig.path} yarn run codecov -p $ROOT -F frontend`, - }], + }, + ], container: { image: `node:${fullConfig.nodeVersion}`, }, diff --git a/cdk/kraken/src/utils.ts b/cdk/kraken/src/utils.ts index d1736b91..dd82b355 100644 --- a/cdk/kraken/src/utils.ts +++ b/cdk/kraken/src/utils.ts @@ -1,2 +1,3 @@ -export const buildId = (id: string, suffix: string) => suffix ? `${id}-${suffix}` : id; +export const buildId = (id: string, suffix: string) => + suffix ? `${id}-${suffix}` : id; export const buildName = (name: string, id: string) => `${name} ${id}`.trim(); diff --git a/cdk/kraken/test/auto-approve.test.ts b/cdk/kraken/test/auto-approve.test.ts index 11fa52fc..8fd7c6cd 100644 --- a/cdk/kraken/test/auto-approve.test.ts +++ b/cdk/kraken/test/auto-approve.test.ts @@ -1,14 +1,13 @@ -import * as fs from 'fs'; -import { AutoApproveStack } from '../src'; -import { TestingApp } from './utils'; +import * as fs from "fs"; +import { AutoApproveStack } from "../src"; +import { TestingApp } from "./utils"; -test('default', () => { +test("default", () => { const app = TestingApp({ createValidateWorkflow: false }); new AutoApproveStack(app); app.synth(); - expect(fs.readdirSync(app.outdir)).toEqual([ - 'cdkactions_autoapprove.yaml', - ]); - expect(fs.readFileSync(`${app.outdir}/cdkactions_autoapprove.yaml`, 'utf-8')).toMatchSnapshot(); -}, -); + expect(fs.readdirSync(app.outdir)).toEqual(["cdkactions_autoapprove.yaml"]); + expect( + fs.readFileSync(`${app.outdir}/cdkactions_autoapprove.yaml`, "utf-8") + ).toMatchSnapshot(); +}); diff --git a/cdk/kraken/test/cdk.test.ts b/cdk/kraken/test/cdk.test.ts index cd184a56..eae4979a 100644 --- a/cdk/kraken/test/cdk.test.ts +++ b/cdk/kraken/test/cdk.test.ts @@ -1,14 +1,13 @@ -import * as fs from 'fs'; -import { CDKPublishStack } from '../src'; -import { TestingApp } from './utils'; +import * as fs from "fs"; +import { CDKPublishStack } from "../src"; +import { TestingApp } from "./utils"; -test('default', () => { +test("default", () => { const app = TestingApp({ createValidateWorkflow: false }); - new CDKPublishStack(app, 'example'); + new CDKPublishStack(app, "example"); app.synth(); - expect(fs.readdirSync(app.outdir)).toEqual([ - 'cdkactions_example.yaml', - ]); - expect(fs.readFileSync(`${app.outdir}/cdkactions_example.yaml`, 'utf-8')).toMatchSnapshot(); -}, -); + expect(fs.readdirSync(app.outdir)).toEqual(["cdkactions_example.yaml"]); + expect( + fs.readFileSync(`${app.outdir}/cdkactions_example.yaml`, "utf-8") + ).toMatchSnapshot(); +}); diff --git a/cdk/kraken/test/custom.test.ts b/cdk/kraken/test/custom.test.ts index 244c74cf..2e9567c1 100644 --- a/cdk/kraken/test/custom.test.ts +++ b/cdk/kraken/test/custom.test.ts @@ -1,43 +1,47 @@ -import { Workflow } from 'cdkactions'; -import { DeployJob, DjangoProject, ReactProject } from '../src'; +import { Workflow } from "cdkactions"; +import { DeployJob, DjangoProject, ReactProject } from "../src"; -test('workflow with 2 django+react projects', () => { - const workflow = new Workflow(undefined as any, 'workflow', { - name: 'Workflow', - on: 'push', +test("workflow with 2 django+react projects", () => { + const workflow = new Workflow(undefined as any, "workflow", { + name: "Workflow", + on: "push", }); - const djangoOne = new DjangoProject(workflow, - { - id: 'one', - projectName: 'projectOne', - path: 'backendOne', - imageName: 'imageOne-backend', - }); - const djangoTwo = new DjangoProject(workflow, - { - id: 'two', - projectName: 'projectTwo', - path: 'backendTwo', - imageName: 'imageTwo-backend', - }); + const djangoOne = new DjangoProject(workflow, { + id: "one", + projectName: "projectOne", + path: "backendOne", + imageName: "imageOne-backend", + }); + const djangoTwo = new DjangoProject(workflow, { + id: "two", + projectName: "projectTwo", + path: "backendTwo", + imageName: "imageTwo-backend", + }); - const reactOne = new ReactProject(workflow, - { - id: 'one', - path: 'frontendOne', - imageName: 'imageOne-frontend', - }); - const reactTwo = new ReactProject(workflow, - { - id: 'two', - path: 'frontendTwo', - imageName: 'imageTwo-frontend', - }); - new DeployJob(workflow, {}, + const reactOne = new ReactProject(workflow, { + id: "one", + path: "frontendOne", + imageName: "imageOne-frontend", + }); + const reactTwo = new ReactProject(workflow, { + id: "two", + path: "frontendTwo", + imageName: "imageTwo-frontend", + }); + new DeployJob( + workflow, + {}, { - needs: [djangoOne.publishJobId, djangoTwo.publishJobId, reactOne.publishJobId, reactTwo.publishJobId], - }); + needs: [ + djangoOne.publishJobId, + djangoTwo.publishJobId, + reactOne.publishJobId, + reactTwo.publishJobId, + ], + } + ); expect(workflow.toGHAction()).toMatchSnapshot(); }); diff --git a/cdk/kraken/test/django-project.test.ts b/cdk/kraken/test/django-project.test.ts index e689810e..ad7c7f36 100644 --- a/cdk/kraken/test/django-project.test.ts +++ b/cdk/kraken/test/django-project.test.ts @@ -1,29 +1,27 @@ -import { Workflow } from 'cdkactions'; -import { DjangoProject } from '../src'; +import { Workflow } from "cdkactions"; +import { DjangoProject } from "../src"; -test('default', () => { - const workflow = new Workflow(undefined as any, 'workflow', { - name: 'Workflow', - on: 'push', +test("default", () => { + const workflow = new Workflow(undefined as any, "workflow", { + name: "Workflow", + on: "push", + }); + new DjangoProject(workflow, { + projectName: "example", + imageName: "example", }); - new DjangoProject(workflow, - { - projectName: 'example', - imageName: 'example', - }); expect(workflow.toGHAction()).toMatchSnapshot(); }); -test('custom id', () => { - const workflow = new Workflow(undefined as any, 'workflow', { - name: 'Workflow', - on: 'push', +test("custom id", () => { + const workflow = new Workflow(undefined as any, "workflow", { + name: "Workflow", + on: "push", + }); + new DjangoProject(workflow, { + projectName: "example", + imageName: "example", + id: "custom", }); - new DjangoProject(workflow, - { - projectName: 'example', - imageName: 'example', - id: 'custom', - }); expect(workflow.toGHAction()).toMatchSnapshot(); }); diff --git a/cdk/kraken/test/django.test.ts b/cdk/kraken/test/django.test.ts index 79961051..f9a7c56a 100644 --- a/cdk/kraken/test/django.test.ts +++ b/cdk/kraken/test/django.test.ts @@ -1,26 +1,40 @@ -import { DjangoCheckJob } from '../src'; +import { DjangoCheckJob } from "../src"; -test('default', () => { - const dc = new DjangoCheckJob(undefined as any, { projectName: 'example' }); +test("default", () => { + const dc = new DjangoCheckJob(undefined as any, { projectName: "example" }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('different python version', () => { - const dc = new DjangoCheckJob(undefined as any, { pythonVersion: '2.7', projectName: 'example' }); +test("different python version", () => { + const dc = new DjangoCheckJob(undefined as any, { + pythonVersion: "2.7", + projectName: "example", + }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('different directory', () => { - const dc = new DjangoCheckJob(undefined as any, { path: 'backend', projectName: 'example' }); +test("different directory", () => { + const dc = new DjangoCheckJob(undefined as any, { + path: "backend", + projectName: "example", + }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('no lint', () => { - const dc = new DjangoCheckJob(undefined as any, { projectName: 'example', black: false, flake8: false }); +test("no lint", () => { + const dc = new DjangoCheckJob(undefined as any, { + projectName: "example", + black: false, + flake8: false, + }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('with overrides', () => { - const dc = new DjangoCheckJob(undefined as any, { projectName: 'example' }, { continueOnError: true }); +test("with overrides", () => { + const dc = new DjangoCheckJob( + undefined as any, + { projectName: "example" }, + { continueOnError: true } + ); expect(dc.toGHAction()).toMatchSnapshot(); }); diff --git a/cdk/kraken/test/docker.test.ts b/cdk/kraken/test/docker.test.ts index f536dd4c..a5178c25 100644 --- a/cdk/kraken/test/docker.test.ts +++ b/cdk/kraken/test/docker.test.ts @@ -1,22 +1,35 @@ -import { DockerPublishJob } from '../src'; +import { DockerPublishJob } from "../src"; // DockerPublish -test('default', () => { - const dc = new DockerPublishJob(undefined as any, 'publish', { imageName: 'example' }); +test("default", () => { + const dc = new DockerPublishJob(undefined as any, "publish", { + imageName: "example", + }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('disable cache', () => { - const dc = new DockerPublishJob(undefined as any, 'publish', { imageName: 'example', cache: false }); +test("disable cache", () => { + const dc = new DockerPublishJob(undefined as any, "publish", { + imageName: "example", + cache: false, + }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('no publish', () => { - const dc = new DockerPublishJob(undefined as any, 'publish', { imageName: 'example', noPublish: true }); +test("no publish", () => { + const dc = new DockerPublishJob(undefined as any, "publish", { + imageName: "example", + noPublish: true, + }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('with overrides', () => { - const dc = new DockerPublishJob(undefined as any, 'publish', { imageName: 'example' }, { continueOnError: true }); +test("with overrides", () => { + const dc = new DockerPublishJob( + undefined as any, + "publish", + { imageName: "example" }, + { continueOnError: true } + ); expect(dc.toGHAction()).toMatchSnapshot(); }); diff --git a/cdk/kraken/test/integration-tests.test.ts b/cdk/kraken/test/integration-tests.test.ts index c10ec9f2..aa19a494 100644 --- a/cdk/kraken/test/integration-tests.test.ts +++ b/cdk/kraken/test/integration-tests.test.ts @@ -1,29 +1,28 @@ -import { Workflow } from 'cdkactions'; -import { IntegrationTestsJob } from '../src'; +import { Workflow } from "cdkactions"; +import { IntegrationTestsJob } from "../src"; - -test('default', () => { - const workflow = new Workflow(undefined as any, 'workflow', { - name: 'Workflow', - on: 'push', +test("default", () => { + const workflow = new Workflow(undefined as any, "workflow", { + name: "Workflow", + on: "push", }); new IntegrationTestsJob(workflow, { - testCommand: 'exit 0', - dockerBuildIds: ['id'], - dockerImages: ['image'], + testCommand: "exit 0", + dockerBuildIds: ["id"], + dockerImages: ["image"], }); expect(workflow.toGHAction()).toMatchSnapshot(); }); -test('no post image publish', () => { - const workflow = new Workflow(undefined as any, 'workflow', { - name: 'Workflow', - on: 'push', +test("no post image publish", () => { + const workflow = new Workflow(undefined as any, "workflow", { + name: "Workflow", + on: "push", }); new IntegrationTestsJob(workflow, { - testCommand: 'exit 0', - dockerBuildIds: ['id'], - dockerImages: ['image'], + testCommand: "exit 0", + dockerBuildIds: ["id"], + dockerImages: ["image"], createPostIntegrationPublishJob: false, }); expect(workflow.toGHAction()).toMatchSnapshot(); diff --git a/cdk/kraken/test/labs-application.test.ts b/cdk/kraken/test/labs-application.test.ts index 1b739284..3fb5c7a4 100644 --- a/cdk/kraken/test/labs-application.test.ts +++ b/cdk/kraken/test/labs-application.test.ts @@ -1,33 +1,34 @@ -import * as fs from 'fs'; -import { LabsApplicationStack } from '../src'; -import { TestingApp } from './utils'; +import * as fs from "fs"; +import { LabsApplicationStack } from "../src"; +import { TestingApp } from "./utils"; - -test('default', () => { +test("default", () => { const app = TestingApp({ createValidateWorkflow: false }); new LabsApplicationStack(app, { - djangoProjectName: 'example', - dockerImageBaseName: 'example', + djangoProjectName: "example", + dockerImageBaseName: "example", }); app.synth(); expect(fs.readdirSync(app.outdir)).toEqual([ - 'cdkactions_build-and-deploy.yaml', + "cdkactions_build-and-deploy.yaml", ]); - expect(fs.readFileSync(`${app.outdir}/cdkactions_build-and-deploy.yaml`, 'utf-8')).toMatchSnapshot(); -}, -); + expect( + fs.readFileSync(`${app.outdir}/cdkactions_build-and-deploy.yaml`, "utf-8") + ).toMatchSnapshot(); +}); -test('integration tests', () => { +test("integration tests", () => { const app = TestingApp({ createValidateWorkflow: false }); new LabsApplicationStack(app, { - djangoProjectName: 'example', - dockerImageBaseName: 'example', + djangoProjectName: "example", + dockerImageBaseName: "example", integrationTests: true, }); app.synth(); expect(fs.readdirSync(app.outdir)).toEqual([ - 'cdkactions_build-and-deploy.yaml', + "cdkactions_build-and-deploy.yaml", ]); - expect(fs.readFileSync(`${app.outdir}/cdkactions_build-and-deploy.yaml`, 'utf-8')).toMatchSnapshot(); -}, -); + expect( + fs.readFileSync(`${app.outdir}/cdkactions_build-and-deploy.yaml`, "utf-8") + ).toMatchSnapshot(); +}); diff --git a/cdk/kraken/test/pypi.test.ts b/cdk/kraken/test/pypi.test.ts index 8dcb0ea2..d73a3173 100644 --- a/cdk/kraken/test/pypi.test.ts +++ b/cdk/kraken/test/pypi.test.ts @@ -1,14 +1,15 @@ -import * as fs from 'fs'; -import { PyPIPublishStack } from '../src'; -import { TestingApp } from './utils'; +import * as fs from "fs"; +import { PyPIPublishStack } from "../src"; +import { TestingApp } from "./utils"; -test('default', () => { +test("default", () => { const app = TestingApp({ createValidateWorkflow: false }); new PyPIPublishStack(app); app.synth(); expect(fs.readdirSync(app.outdir)).toEqual([ - 'cdkactions_build-and-publish.yaml', + "cdkactions_build-and-publish.yaml", ]); - expect(fs.readFileSync(`${app.outdir}/cdkactions_build-and-publish.yaml`, 'utf-8')).toMatchSnapshot(); -}, -); + expect( + fs.readFileSync(`${app.outdir}/cdkactions_build-and-publish.yaml`, "utf-8") + ).toMatchSnapshot(); +}); diff --git a/cdk/kraken/test/react-project.test.ts b/cdk/kraken/test/react-project.test.ts index df5a48f2..86d71611 100644 --- a/cdk/kraken/test/react-project.test.ts +++ b/cdk/kraken/test/react-project.test.ts @@ -1,27 +1,25 @@ -import { Workflow } from 'cdkactions'; -import { ReactProject } from '../src'; +import { Workflow } from "cdkactions"; +import { ReactProject } from "../src"; -test('default', () => { - const workflow = new Workflow(undefined as any, 'workflow', { - name: 'Workflow', - on: 'push', +test("default", () => { + const workflow = new Workflow(undefined as any, "workflow", { + name: "Workflow", + on: "push", + }); + new ReactProject(workflow, { + imageName: "example", }); - new ReactProject(workflow, - { - imageName: 'example', - }); expect(workflow.toGHAction()).toMatchSnapshot(); }); -test('custom id', () => { - const workflow = new Workflow(undefined as any, 'workflow', { - name: 'Workflow', - on: 'push', +test("custom id", () => { + const workflow = new Workflow(undefined as any, "workflow", { + name: "Workflow", + on: "push", + }); + new ReactProject(workflow, { + imageName: "example", + id: "custom", }); - new ReactProject(workflow, - { - imageName: 'example', - id: 'custom', - }); expect(workflow.toGHAction()).toMatchSnapshot(); }); diff --git a/cdk/kraken/test/react.test.ts b/cdk/kraken/test/react.test.ts index 6e150c23..5d9efc7a 100644 --- a/cdk/kraken/test/react.test.ts +++ b/cdk/kraken/test/react.test.ts @@ -1,21 +1,21 @@ -import { ReactCheckJob } from '../src'; +import { ReactCheckJob } from "../src"; -test('default', () => { +test("default", () => { const dc = new ReactCheckJob(undefined as any, {}); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('different node version', () => { - const dc = new ReactCheckJob(undefined as any, { nodeVersion: '12' }); +test("different node version", () => { + const dc = new ReactCheckJob(undefined as any, { nodeVersion: "12" }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('different directory', () => { - const dc = new ReactCheckJob(undefined as any, { path: 'frontend' }); +test("different directory", () => { + const dc = new ReactCheckJob(undefined as any, { path: "frontend" }); expect(dc.toGHAction()).toMatchSnapshot(); }); -test('with overrides', () => { +test("with overrides", () => { const dc = new ReactCheckJob(undefined as any, {}, { continueOnError: true }); expect(dc.toGHAction()).toMatchSnapshot(); }); diff --git a/cdk/kraken/test/utils.test.ts b/cdk/kraken/test/utils.test.ts index 9599828a..407bbd7e 100644 --- a/cdk/kraken/test/utils.test.ts +++ b/cdk/kraken/test/utils.test.ts @@ -1,25 +1,25 @@ -import { buildId, buildName } from '../src'; +import { buildId, buildName } from "../src"; -test('buildId no suffix', () => { - const id = 'id'; - const suffix = ''; +test("buildId no suffix", () => { + const id = "id"; + const suffix = ""; expect(buildId(id, suffix)).toBe(id); }); -test('buildId with suffix', () => { - const id = 'id'; - const suffix = 'abc'; +test("buildId with suffix", () => { + const id = "id"; + const suffix = "abc"; expect(buildId(id, suffix)).toBe(`${id}-${suffix}`); }); -test('buildName no suffix', () => { - const name = 'name'; - const id = ''; +test("buildName no suffix", () => { + const name = "name"; + const id = ""; expect(buildName(name, id)).toBe(name); }); -test('buildName woth suffix', () => { - const name = 'name'; - const id = 'id'; +test("buildName woth suffix", () => { + const name = "name"; + const id = "id"; expect(buildName(name, id)).toBe(`${name} ${id}`); }); diff --git a/cdk/kraken/test/utils.ts b/cdk/kraken/test/utils.ts index 4f6e777d..27ea73d8 100644 --- a/cdk/kraken/test/utils.ts +++ b/cdk/kraken/test/utils.ts @@ -1,16 +1,14 @@ -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import { App, AppProps } from 'cdkactions'; +import * as fs from "fs"; +import * as os from "os"; +import * as path from "path"; +import { App, AppProps } from "cdkactions"; /** * A util function returning an instance of App with a outdir set to a temp directory * @param options AppProps to provide to the new App */ -export const TestingApp = (options: Partial) => new App( - { +export const TestingApp = (options: Partial) => + new App({ ...options, - outdir: fs.mkdtempSync(path.join(os.tmpdir(), 'kraken')), - }, -); - + outdir: fs.mkdtempSync(path.join(os.tmpdir(), "kraken")), + });