├── src
├── index.ts
├── _shell.ts
└── image.ts
├── .github
├── pull_request_template.md
└── workflows
│ ├── auto-approve.yml
│ ├── pull-request-lint.yml
│ ├── stale.yml
│ ├── upgrade-main.yml
│ ├── release.yml
│ └── build.yml
├── git-hooks
├── setup.sh
├── README.md
└── prepare-commit-msg
├── .npmignore
├── .projen
├── files.json
├── deps.json
└── tasks.json
├── .mergify.yml
├── README.md
├── .gitattributes
├── tsconfig.dev.json
├── .projenrc.js
├── .gitignore
├── DCO
├── API.md
├── test
└── image.test.ts
├── CONTRIBUTING.md
├── package.json
├── .eslintrc.json
└── LICENSE
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './image';
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Fixes #
--------------------------------------------------------------------------------
/git-hooks/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ##############################################
4 | # Setup shared .git hooks for this project.
5 | #
6 |
7 | hooksdir="$(cd $(dirname $0) && pwd)"
8 |
9 | git config core.hooksPath ${hooksdir}
10 | echo "Configured core.hooksPath to ${hooksdir}"
--------------------------------------------------------------------------------
/git-hooks/README.md:
--------------------------------------------------------------------------------
1 | # Git Hooks
2 |
3 | This directory contains git hooks that the core team uses for various tasks.
4 |
5 | - Commit signoff for automatic compliance of the [DCO](../CONTRIBUTING.md#developer-certificate-of-origin-dco).
6 |
7 | ## Setup
8 |
9 | To setup these git hooks, run `./git-hooks/setup.sh` from the root directory of the project.
--------------------------------------------------------------------------------
/git-hooks/prepare-commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | NAME=$(git config user.name)
4 | EMAIL=$(git config user.email)
5 |
6 | if [ -z "$NAME" ]; then
7 | echo "empty git config user.name"
8 | exit 1
9 | fi
10 |
11 | if [ -z "$EMAIL" ]; then
12 | echo "empty git config user.email"
13 | exit 1
14 | fi
15 |
16 | git interpret-trailers --if-exists doNothing --trailer \
17 | "Signed-off-by: $NAME <$EMAIL>" \
18 | --in-place "$1"
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | /.projen/
3 | /test-reports/
4 | junit.xml
5 | /coverage/
6 | /dist/changelog.md
7 | /dist/version.txt
8 | /.mergify.yml
9 | /test/
10 | /tsconfig.dev.json
11 | /src/
12 | !/lib/
13 | !/lib/**/*.js
14 | !/lib/**/*.d.ts
15 | dist
16 | /tsconfig.json
17 | /.github/
18 | /.vscode/
19 | /.idea/
20 | /.projenrc.js
21 | tsconfig.tsbuildinfo
22 | /.eslintrc.json
23 | !.jsii
24 |
--------------------------------------------------------------------------------
/src/_shell.ts:
--------------------------------------------------------------------------------
1 | import { spawnSync } from 'child_process';
2 |
3 | const MAX_BUFFER_SIZE = 10 * 1024 * 1024;
4 |
5 | export function shell(command: string, ...args: string[]): string {
6 | const proc = spawnSync(command, args, { maxBuffer: MAX_BUFFER_SIZE, encoding: 'utf-8' });
7 |
8 | if (proc.error) {
9 | throw new Error(proc.error.message);
10 | }
11 |
12 | if (proc.status !== 0) {
13 | throw new Error(`non-zero exist code ${proc.status}: ${proc.stdout} ${proc.stderr}`);
14 | }
15 |
16 | return proc.stdout;
17 | }
--------------------------------------------------------------------------------
/.projen/files.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | ".eslintrc.json",
4 | ".gitattributes",
5 | ".github/pull_request_template.md",
6 | ".github/workflows/auto-approve.yml",
7 | ".github/workflows/build.yml",
8 | ".github/workflows/pull-request-lint.yml",
9 | ".github/workflows/release.yml",
10 | ".github/workflows/stale.yml",
11 | ".github/workflows/upgrade-main.yml",
12 | ".gitignore",
13 | ".mergify.yml",
14 | ".projen/deps.json",
15 | ".projen/files.json",
16 | ".projen/tasks.json",
17 | "LICENSE",
18 | "tsconfig.dev.json"
19 | ],
20 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
21 | }
22 |
--------------------------------------------------------------------------------
/.github/workflows/auto-approve.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: auto-approve
4 | on:
5 | pull_request_target:
6 | types:
7 | - labeled
8 | - opened
9 | - synchronize
10 | - reopened
11 | - ready_for_review
12 | jobs:
13 | approve:
14 | runs-on: ubuntu-latest
15 | permissions:
16 | pull-requests: write
17 | if: contains(github.event.pull_request.labels.*.name, 'auto-approve') && (github.event.pull_request.user.login == 'cdk8s-automation')
18 | steps:
19 | - uses: hmarr/auto-approve-action@v2.1.0
20 | with:
21 | github-token: ${{ secrets.GITHUB_TOKEN }}
22 |
--------------------------------------------------------------------------------
/.github/workflows/pull-request-lint.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: pull-request-lint
4 | on:
5 | pull_request_target:
6 | types:
7 | - labeled
8 | - opened
9 | - synchronize
10 | - reopened
11 | - ready_for_review
12 | - edited
13 | jobs:
14 | validate:
15 | name: Validate PR title
16 | runs-on: ubuntu-latest
17 | permissions:
18 | pull-requests: write
19 | steps:
20 | - uses: amannn/action-semantic-pull-request@v3.4.6
21 | env:
22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 | with:
24 | types: |-
25 | feat
26 | fix
27 | chore
28 | requireScope: false
29 |
--------------------------------------------------------------------------------
/.mergify.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | queue_rules:
4 | - name: default
5 | conditions:
6 | - "#approved-reviews-by>=1"
7 | - -label~=(do-not-merge)
8 | - status-success=build
9 | - status-success=package-python
10 | pull_request_rules:
11 | - name: Automatic merge on approval and successful build
12 | actions:
13 | delete_head_branch: {}
14 | queue:
15 | method: squash
16 | name: default
17 | commit_message_template: |-
18 | {{ title }} (#{{ number }})
19 |
20 | {{ body }}
21 | conditions:
22 | - "#approved-reviews-by>=1"
23 | - -label~=(do-not-merge)
24 | - status-success=build
25 | - status-success=package-python
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cdk8s-image
2 |
3 | An `Image` construct which takes care of building & pushing docker images that
4 | can be used in [CDK8s](https://github.com/awslabs/cdk8s) apps.
5 |
6 | The following example will build the docker image from `Dockerfile` under the
7 | `my-app` directory, push it to a local registry and then define a Kubernetes
8 | deployment that deploys containers that run this image.
9 |
10 | ```ts
11 | const image = new Image(this, 'image', {
12 | dir: `${__dirname}/my-app`,
13 | registry: 'localhost:5000'
14 | });
15 |
16 | new Deployment(this, 'deployment', {
17 | containers: [ new Container({ image: image.url }) ],
18 | });
19 | ```
20 |
21 | ## Contributions
22 |
23 | All contributions are celebrated.
24 |
25 | ## License
26 |
27 | Licensed under [Apache 2.0](./LICENSE).
28 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | *.snap linguist-generated
4 | /.eslintrc.json linguist-generated
5 | /.gitattributes linguist-generated
6 | /.github/pull_request_template.md linguist-generated
7 | /.github/workflows/auto-approve.yml linguist-generated
8 | /.github/workflows/build.yml linguist-generated
9 | /.github/workflows/pull-request-lint.yml linguist-generated
10 | /.github/workflows/release.yml linguist-generated
11 | /.github/workflows/stale.yml linguist-generated
12 | /.github/workflows/upgrade-main.yml linguist-generated
13 | /.gitignore linguist-generated
14 | /.mergify.yml linguist-generated
15 | /.npmignore linguist-generated
16 | /.projen/** linguist-generated
17 | /.projen/deps.json linguist-generated
18 | /.projen/files.json linguist-generated
19 | /.projen/tasks.json linguist-generated
20 | /LICENSE linguist-generated
21 | /package.json linguist-generated
22 | /tsconfig.dev.json linguist-generated
23 | /yarn.lock linguist-generated
--------------------------------------------------------------------------------
/tsconfig.dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "alwaysStrict": true,
4 | "declaration": true,
5 | "esModuleInterop": true,
6 | "experimentalDecorators": true,
7 | "inlineSourceMap": true,
8 | "inlineSources": true,
9 | "lib": [
10 | "es2019"
11 | ],
12 | "module": "CommonJS",
13 | "noEmitOnError": false,
14 | "noFallthroughCasesInSwitch": true,
15 | "noImplicitAny": true,
16 | "noImplicitReturns": true,
17 | "noImplicitThis": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "resolveJsonModule": true,
21 | "strict": true,
22 | "strictNullChecks": true,
23 | "strictPropertyInitialization": true,
24 | "stripInternal": true,
25 | "target": "ES2019"
26 | },
27 | "include": [
28 | ".projenrc.js",
29 | "src/**/*.ts",
30 | "test/**/*.ts"
31 | ],
32 | "exclude": [
33 | "node_modules"
34 | ],
35 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
36 | }
37 |
--------------------------------------------------------------------------------
/.projenrc.js:
--------------------------------------------------------------------------------
1 | const { cdk } = require('projen');
2 |
3 | const project = new cdk.JsiiProject({
4 | authorUrl: 'https://aws.amazon.com',
5 | authorName: 'Amazon Web Services',
6 | keywords: [
7 | 'cdk8s',
8 | 'docker',
9 | 'containers',
10 | 'kubernetes',
11 | ],
12 | peerDeps: [
13 | 'constructs',
14 | 'cdk8s',
15 | ],
16 | name: 'udp-cdk8s-image',
17 | minNodeVersion: '14.17.0',
18 | description: 'Build & Push local docker images inside CDK8s applications',
19 | repository: 'https://github.com/cdk8s-team/cdk8s-image',
20 | defaultReleaseBranch: 'main',
21 | projenUpgradeSecret: 'PROJEN_GITHUB_TOKEN',
22 | autoApproveOptions: {
23 | allowedUsernames: ['cdk8s-automation'],
24 | secret: 'GITHUB_TOKEN',
25 | },
26 | autoApproveUpgrades: true,
27 | publishToPypi: {
28 | distName: 'udp-cdk8s-image',
29 | module: 'udp_cdk8s_image',
30 | twineRegistryUrl: 'https://fso.jfrog.io/artifactory/api/pypi/fso-pypi',
31 | twineUsernameSecret: 'ARTIFACTORY_USERNAME',
32 | twinePasswordSecret: 'ARTIFACTORY_TOKEN',
33 | },
34 | releaseToNpm: false,
35 | });
36 |
37 | project.synth();
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 | !/.gitattributes
3 | !/.projen/tasks.json
4 | !/.projen/deps.json
5 | !/.projen/files.json
6 | !/.github/workflows/pull-request-lint.yml
7 | !/.github/workflows/auto-approve.yml
8 | !/.github/workflows/stale.yml
9 | !/package.json
10 | !/LICENSE
11 | !/.npmignore
12 | logs
13 | *.log
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 | lerna-debug.log*
18 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
19 | pids
20 | *.pid
21 | *.seed
22 | *.pid.lock
23 | lib-cov
24 | coverage
25 | *.lcov
26 | .nyc_output
27 | build/Release
28 | node_modules/
29 | jspm_packages/
30 | *.tsbuildinfo
31 | .eslintcache
32 | *.tgz
33 | .yarn-integrity
34 | .cache
35 | !/.projenrc.js
36 | /test-reports/
37 | junit.xml
38 | /coverage/
39 | !/.github/workflows/build.yml
40 | /dist/changelog.md
41 | /dist/version.txt
42 | !/.github/workflows/release.yml
43 | !/.mergify.yml
44 | !/.github/pull_request_template.md
45 | !/test/
46 | !/tsconfig.dev.json
47 | !/src/
48 | /lib
49 | /dist/
50 | !/.eslintrc.json
51 | .jsii
52 | tsconfig.json
53 | !/API.md
54 | !/.github/workflows/upgrade-main.yml
55 |
--------------------------------------------------------------------------------
/DCO:
--------------------------------------------------------------------------------
1 | Developer Certificate of Origin
2 | Version 1.1
3 |
4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
5 |
6 | Everyone is permitted to copy and distribute verbatim copies of this
7 | license document, but changing it is not allowed.
8 |
9 |
10 | Developer's Certificate of Origin 1.1
11 |
12 | By making a contribution to this project, I certify that:
13 |
14 | (a) The contribution was created in whole or in part by me and I
15 | have the right to submit it under the open source license
16 | indicated in the file; or
17 |
18 | (b) The contribution is based upon previous work that, to the best
19 | of my knowledge, is covered under an appropriate open source
20 | license and I have the right under that license to submit that
21 | work with modifications, whether created in whole or in part
22 | by me, under the same open source license (unless I am
23 | permitted to submit under a different license), as indicated
24 | in the file; or
25 |
26 | (c) The contribution was provided directly to me by some other
27 | person who certified (a), (b) or (c) and I have not modified
28 | it.
29 |
30 | (d) I understand and agree that this project and the contribution
31 | are public and that a record of the contribution (including all
32 | personal information I submit with it, including my sign-off) is
33 | maintained indefinitely and may be redistributed consistent with
34 | this project or the open source license(s) involved.
35 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: stale
4 | on:
5 | schedule:
6 | - cron: 0 1 * * *
7 | workflow_dispatch: {}
8 | jobs:
9 | stale:
10 | runs-on: ubuntu-latest
11 | permissions:
12 | issues: write
13 | pull-requests: write
14 | steps:
15 | - uses: actions/stale@v4
16 | with:
17 | days-before-stale: -1
18 | days-before-close: -1
19 | days-before-pr-stale: 14
20 | days-before-pr-close: 2
21 | stale-pr-message: This pull request is now marked as stale because it hasn't seen activity for a while. Add a comment or it will be closed soon. If you wish to exclude this issue from being marked as stale, add the "backlog" label.
22 | close-pr-message: Closing this pull request as it hasn't seen activity for a while. Please add a comment @mentioning a maintainer to reopen. If you wish to exclude this issue from being marked as stale, add the "backlog" label.
23 | stale-pr-label: stale
24 | exempt-pr-labels: backlog
25 | days-before-issue-stale: 60
26 | days-before-issue-close: 7
27 | stale-issue-message: This issue is now marked as stale because it hasn't seen activity for a while. Add a comment or it will be closed soon. If you wish to exclude this issue from being marked as stale, add the "backlog" label.
28 | close-issue-message: Closing this issue as it hasn't seen activity for a while. Please add a comment @mentioning a maintainer to reopen. If you wish to exclude this issue from being marked as stale, add the "backlog" label.
29 | stale-issue-label: stale
30 | exempt-issue-labels: backlog
31 |
--------------------------------------------------------------------------------
/.projen/deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "name": "@types/jest",
5 | "type": "build"
6 | },
7 | {
8 | "name": "@types/node",
9 | "version": "^14",
10 | "type": "build"
11 | },
12 | {
13 | "name": "@typescript-eslint/eslint-plugin",
14 | "version": "^5",
15 | "type": "build"
16 | },
17 | {
18 | "name": "@typescript-eslint/parser",
19 | "version": "^5",
20 | "type": "build"
21 | },
22 | {
23 | "name": "cdk8s",
24 | "type": "build"
25 | },
26 | {
27 | "name": "constructs",
28 | "type": "build"
29 | },
30 | {
31 | "name": "eslint-import-resolver-node",
32 | "type": "build"
33 | },
34 | {
35 | "name": "eslint-import-resolver-typescript",
36 | "type": "build"
37 | },
38 | {
39 | "name": "eslint-plugin-import",
40 | "type": "build"
41 | },
42 | {
43 | "name": "eslint",
44 | "version": "^8",
45 | "type": "build"
46 | },
47 | {
48 | "name": "jest",
49 | "type": "build"
50 | },
51 | {
52 | "name": "jest-junit",
53 | "version": "^13",
54 | "type": "build"
55 | },
56 | {
57 | "name": "jsii",
58 | "type": "build"
59 | },
60 | {
61 | "name": "jsii-diff",
62 | "type": "build"
63 | },
64 | {
65 | "name": "jsii-docgen",
66 | "type": "build"
67 | },
68 | {
69 | "name": "json-schema",
70 | "type": "build"
71 | },
72 | {
73 | "name": "npm-check-updates",
74 | "version": "^12",
75 | "type": "build"
76 | },
77 | {
78 | "name": "projen",
79 | "type": "build"
80 | },
81 | {
82 | "name": "standard-version",
83 | "version": "^9",
84 | "type": "build"
85 | },
86 | {
87 | "name": "ts-jest",
88 | "type": "build"
89 | },
90 | {
91 | "name": "typescript",
92 | "type": "build"
93 | },
94 | {
95 | "name": "cdk8s",
96 | "type": "peer"
97 | },
98 | {
99 | "name": "constructs",
100 | "type": "peer"
101 | }
102 | ],
103 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
104 | }
105 |
--------------------------------------------------------------------------------
/src/image.ts:
--------------------------------------------------------------------------------
1 | import { Names } from 'cdk8s';
2 | import { Construct } from 'constructs';
3 | import { shell } from './_shell';
4 |
5 | const PARSE_DIGEST = /digest:\ (sha256:[0-9a-f]+)/;
6 |
7 | /**
8 | * Build arg to pass to the docker build
9 | */
10 | export interface BuildArg {
11 | /**
12 | * the name of the build arg
13 | */
14 | readonly name: string;
15 |
16 | /**
17 | * the value of the build arg
18 | */
19 | readonly value: string;
20 | }
21 |
22 | /**
23 | * Props for `Image`.
24 | */
25 | export interface ImageProps {
26 | /**
27 | * The docker build context directory (where `Dockerfile` is).
28 | */
29 | readonly dir: string;
30 |
31 | /**
32 | * The registry URL to use.
33 | *
34 | * This will be used as the prefix for the image name.
35 | *
36 | * For example, if you have a local registry listening on port 500, you can set this to `localhost:5000`.
37 | *
38 | * @default "docker.io/library"
39 | */
40 | readonly registry?: string;
41 |
42 | /**
43 | * List of build args to pass to the build action
44 | */
45 | readonly buildArgs?: BuildArg[];
46 | }
47 |
48 | /**
49 | * Represents a docker image built during synthesis from a context directory
50 | * (`dir`) with a `Dockerfile`.
51 | *
52 | * The image will be built using `docker build` and then pushed through `docker
53 | * push`. The URL of the pushed image can be accessed through `image.url`.
54 | *
55 | * If you push to a registry other then docker hub, you can specify the registry
56 | * URL through the `registry` option.
57 | */
58 | export class Image extends Construct {
59 | /**
60 | * The image URL to use in order to pull this instance of the image.
61 | */
62 | public readonly url: string;
63 |
64 | constructor(scope: Construct, id: string, props: ImageProps) {
65 | super(scope, id);
66 | const registry = props.registry ?? 'docker.io/library';
67 | const tag = `${registry}/${Names.toDnsLabel(this)}`;
68 | const buildArgs =
69 | props.buildArgs?.flatMap((arg) => [
70 | '--build-arg',
71 | `${arg.name}=${arg.value}`,
72 | ]) ?? [];
73 |
74 | console.error(`building docker image "${tag}"...`);
75 | shell('docker', 'build', '-t', tag, props.dir, ...buildArgs);
76 | console.error(`pushing docker image "${tag}"...`);
77 | const push = shell('docker', 'push', tag);
78 |
79 | const result = PARSE_DIGEST.exec(push);
80 | if (!result) {
81 | throw new Error(`unable to read image digest after push: ${push}`);
82 | }
83 |
84 | this.url = `${tag}@${result[1]}`;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/API.md:
--------------------------------------------------------------------------------
1 | # API Reference
2 |
3 | **Classes**
4 |
5 | Name|Description
6 | ----|-----------
7 | [Image](#udp-cdk8s-image-image)|Represents a docker image built during synthesis from a context directory (`dir`) with a `Dockerfile`.
8 |
9 |
10 | **Structs**
11 |
12 | Name|Description
13 | ----|-----------
14 | [BuildArg](#udp-cdk8s-image-buildarg)|Build arg to pass to the docker build.
15 | [ImageProps](#udp-cdk8s-image-imageprops)|Props for `Image`.
16 |
17 |
18 |
19 | ## class Image
20 |
21 | Represents a docker image built during synthesis from a context directory (`dir`) with a `Dockerfile`.
22 |
23 | The image will be built using `docker build` and then pushed through `docker
24 | push`. The URL of the pushed image can be accessed through `image.url`.
25 |
26 | If you push to a registry other then docker hub, you can specify the registry
27 | URL through the `registry` option.
28 |
29 | __Implements__: [IConstruct](#constructs-iconstruct), [IDependable](#constructs-idependable)
30 | __Extends__: [Construct](#constructs-construct)
31 |
32 | ### Initializer
33 |
34 |
35 |
36 |
37 | ```ts
38 | new Image(scope: Construct, id: string, props: ImageProps)
39 | ```
40 |
41 | * **scope** ([Construct](#constructs-construct)) *No description*
42 | * **id** (string) *No description*
43 | * **props** ([ImageProps](#udp-cdk8s-image-imageprops)) *No description*
44 | * **dir** (string) The docker build context directory (where `Dockerfile` is).
45 | * **buildArgs** (Array<[BuildArg](#udp-cdk8s-image-buildarg)>) List of build args to pass to the build action. __*Optional*__
46 | * **registry** (string) The registry URL to use. __*Default*__: "docker.io/library"
47 |
48 |
49 |
50 | ### Properties
51 |
52 |
53 | Name | Type | Description
54 | -----|------|-------------
55 | **url** | string | The image URL to use in order to pull this instance of the image.
56 |
57 |
58 |
59 | ## struct BuildArg
60 |
61 |
62 | Build arg to pass to the docker build.
63 |
64 |
65 |
66 | Name | Type | Description
67 | -----|------|-------------
68 | **name** | string | the name of the build arg.
69 | **value** | string | the value of the build arg.
70 |
71 |
72 |
73 | ## struct ImageProps
74 |
75 |
76 | Props for `Image`.
77 |
78 |
79 |
80 | Name | Type | Description
81 | -----|------|-------------
82 | **dir** | string | The docker build context directory (where `Dockerfile` is).
83 | **buildArgs**? | Array<[BuildArg](#udp-cdk8s-image-buildarg)> | List of build args to pass to the build action.
__*Optional*__
84 | **registry**? | string | The registry URL to use.
__*Default*__: "docker.io/library"
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/test/image.test.ts:
--------------------------------------------------------------------------------
1 | import { Testing } from 'cdk8s';
2 | import { Image } from '../src';
3 | import * as shell from '../src/_shell';
4 |
5 | beforeAll(() => {
6 | // disable logs
7 | jest.spyOn(console, 'error').mockReturnValue();
8 | });
9 |
10 | afterAll(() => {
11 | jest.resetAllMocks();
12 | });
13 |
14 | test('minimal usage', () => {
15 | // GIVEN
16 | const mock = jest.spyOn(shell, 'shell').mockReturnValue('text\ntext\n\ndigest: sha256:a1b2c3\n');
17 | const chart = Testing.chart();
18 |
19 | // WHEN
20 | const image = new Image(chart, 'my-image', {
21 | dir: 'foobar',
22 | });
23 |
24 | // THEN
25 | expect(image.url).toEqual('docker.io/library/test-my-image-c80f3600@sha256:a1b2c3');
26 | expect(mock).toBeCalledTimes(2);
27 | expect(mock).toBeCalledWith('docker', 'build', '-t', 'docker.io/library/test-my-image-c80f3600', 'foobar');
28 | expect(mock).toBeCalledWith('docker', 'push', 'docker.io/library/test-my-image-c80f3600');
29 | });
30 |
31 | test('custom registry', () => {
32 | // GIVEN
33 | const mock = jest.spyOn(shell, 'shell').mockReturnValue('text\ntext\n\ndigest: sha256:a1b2c3\n');
34 | const chart = Testing.chart();
35 |
36 | // WHEN
37 | const image = new Image(chart, 'my-image', {
38 | dir: 'foobar',
39 | registry: 'localhost:5000',
40 | });
41 |
42 | // THEN
43 | expect(image.url).toEqual('localhost:5000/test-my-image-c80f3600@sha256:a1b2c3');
44 | expect(mock).toBeCalledTimes(2);
45 | expect(mock).toBeCalledWith('docker', 'build', '-t', 'localhost:5000/test-my-image-c80f3600', 'foobar');
46 | expect(mock).toBeCalledWith('docker', 'push', 'localhost:5000/test-my-image-c80f3600');
47 | });
48 |
49 | test('single build arg', () => {
50 | // GIVEN
51 | const mock = jest.spyOn(shell, 'shell').mockReturnValue('text\ntext\n\ndigest: sha256:a1b2c3\n');
52 | const chart = Testing.chart();
53 |
54 | // WHEN
55 | const image = new Image(chart, 'my-image', {
56 | dir: 'foobar',
57 | buildArgs: [{ name: 'FOO', value: 'bar' }],
58 | });
59 |
60 | // THEN
61 | expect(image.url).toEqual('docker.io/library/test-my-image-c80f3600@sha256:a1b2c3');
62 | expect(mock).toBeCalledTimes(2);
63 | expect(mock).toBeCalledWith('docker', 'build', '-t', 'docker.io/library/test-my-image-c80f3600', 'foobar', '--build-arg', 'FOO=bar');
64 | expect(mock).toBeCalledWith('docker', 'push', 'docker.io/library/test-my-image-c80f3600');
65 | });
66 |
67 | test('multiple build args', () => {
68 | // GIVEN
69 | const mock = jest.spyOn(shell, 'shell').mockReturnValue('text\ntext\n\ndigest: sha256:a1b2c3\n');
70 | const chart = Testing.chart();
71 |
72 | // WHEN
73 | const image = new Image(chart, 'my-image', {
74 | dir: 'foobar',
75 | buildArgs: [
76 | { name: 'FOO', value: 'bar' },
77 | { name: 'BAR', value: 'baz' },
78 | ],
79 | });
80 |
81 | // THEN
82 | expect(image.url).toEqual('docker.io/library/test-my-image-c80f3600@sha256:a1b2c3');
83 | expect(mock).toBeCalledTimes(2);
84 | expect(mock).toBeCalledWith('docker', 'build', '-t', 'docker.io/library/test-my-image-c80f3600', 'foobar', '--build-arg', 'FOO=bar', '--build-arg', 'BAR=baz');
85 | expect(mock).toBeCalledWith('docker', 'push', 'docker.io/library/test-my-image-c80f3600');
86 | });
87 |
--------------------------------------------------------------------------------
/.github/workflows/upgrade-main.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: upgrade-main
4 | on:
5 | workflow_dispatch: {}
6 | schedule:
7 | - cron: 0 0 * * *
8 | jobs:
9 | upgrade:
10 | name: Upgrade
11 | runs-on: ubuntu-latest
12 | permissions:
13 | contents: read
14 | outputs:
15 | patch_created: ${{ steps.create_patch.outputs.patch_created }}
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v2
19 | with:
20 | ref: main
21 | - name: Setup Node.js
22 | uses: actions/setup-node@v2.2.0
23 | with:
24 | node-version: 14.17.0
25 | - name: Install dependencies
26 | run: yarn install --check-files --frozen-lockfile
27 | - name: Upgrade dependencies
28 | run: npx projen upgrade
29 | - id: create_patch
30 | name: Find mutations
31 | run: |-
32 | git add .
33 | git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=patch_created::true"
34 | - if: steps.create_patch.outputs.patch_created
35 | name: Upload patch
36 | uses: actions/upload-artifact@v2
37 | with:
38 | name: .repo.patch
39 | path: .repo.patch
40 | pr:
41 | name: Create Pull Request
42 | needs: upgrade
43 | runs-on: ubuntu-latest
44 | permissions:
45 | contents: write
46 | pull-requests: write
47 | if: ${{ needs.upgrade.outputs.patch_created }}
48 | steps:
49 | - name: Checkout
50 | uses: actions/checkout@v2
51 | with:
52 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
53 | ref: main
54 | - name: Download patch
55 | uses: actions/download-artifact@v2
56 | with:
57 | name: .repo.patch
58 | path: ${{ runner.temp }}
59 | - name: Apply patch
60 | run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."'
61 | - name: Set git identity
62 | run: |-
63 | git config user.name "github-actions"
64 | git config user.email "github-actions@github.com"
65 | - name: Create Pull Request
66 | id: create-pr
67 | uses: peter-evans/create-pull-request@v3
68 | with:
69 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
70 | commit-message: |-
71 | chore(deps): upgrade dependencies
72 |
73 | Upgrades project dependencies. See details in [workflow run].
74 |
75 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
76 |
77 | ------
78 |
79 | *Automatically created by projen via the "upgrade-main" workflow*
80 | branch: github-actions/upgrade-main
81 | title: "chore(deps): upgrade dependencies"
82 | labels: auto-approve
83 | body: |-
84 | Upgrades project dependencies. See details in [workflow run].
85 |
86 | [Workflow Run]: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
87 |
88 | ------
89 |
90 | *Automatically created by projen via the "upgrade-main" workflow*
91 | author: github-actions
92 | committer: github-actions
93 | signoff: true
94 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *main* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 | ### Developer Certificate Of Origin (DCO)
43 |
44 | Every commit should be signed-off in compliance with the [Developer Certificate Of Origin](./DCO).
45 | You can sign your commits by using the `git commit -s` command.
46 |
47 | > To configure automatic signoff, see [git-hooks](./git-hooks/README.md).
48 |
49 | ## Finding contributions to work on
50 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
51 |
52 |
53 | ## Code of Conduct
54 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
55 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
56 | opensource-codeofconduct@amazon.com with any additional questions or comments.
57 |
58 |
59 | ## Security issue notifications
60 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
61 |
62 |
63 | ## Licensing
64 |
65 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
66 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: release
4 | on:
5 | push:
6 | branches:
7 | - main
8 | workflow_dispatch: {}
9 | jobs:
10 | release:
11 | runs-on: ubuntu-latest
12 | permissions:
13 | contents: write
14 | outputs:
15 | latest_commit: ${{ steps.git_remote.outputs.latest_commit }}
16 | env:
17 | CI: "true"
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v2
21 | with:
22 | fetch-depth: 0
23 | - name: Set git identity
24 | run: |-
25 | git config user.name "github-actions"
26 | git config user.email "github-actions@github.com"
27 | - name: Setup Node.js
28 | uses: actions/setup-node@v2.2.0
29 | with:
30 | node-version: 14.17.0
31 | - name: Install dependencies
32 | run: yarn install --check-files --frozen-lockfile
33 | - name: release
34 | run: npx projen release
35 | - name: Check for new commits
36 | id: git_remote
37 | run: echo ::set-output name=latest_commit::"$(git ls-remote origin -h ${{ github.ref }} | cut -f1)"
38 | - name: Upload artifact
39 | if: ${{ steps.git_remote.outputs.latest_commit == github.sha }}
40 | uses: actions/upload-artifact@v2.1.1
41 | with:
42 | name: build-artifact
43 | path: dist
44 | release_github:
45 | name: Publish to GitHub Releases
46 | needs: release
47 | runs-on: ubuntu-latest
48 | permissions:
49 | contents: write
50 | if: needs.release.outputs.latest_commit == github.sha
51 | steps:
52 | - uses: actions/setup-node@v2
53 | with:
54 | node-version: 14.x
55 | - name: Download build artifacts
56 | uses: actions/download-artifact@v2
57 | with:
58 | name: build-artifact
59 | path: dist
60 | - name: Prepare Repository
61 | run: mv dist .repo
62 | - name: Collect GitHub Metadata
63 | run: mv .repo/dist dist
64 | - name: Release
65 | run: errout=$(mktemp); gh release create $(cat dist/releasetag.txt) -R $GITHUB_REPOSITORY -F dist/changelog.md -t $(cat dist/releasetag.txt) --target $GITHUB_REF 2> $errout && true; exitcode=$?; if [ $exitcode -ne 0 ] && ! grep -q "Release.tag_name already exists" $errout; then cat $errout; exit $exitcode; fi
66 | env:
67 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68 | GITHUB_REPOSITORY: ${{ github.repository }}
69 | GITHUB_REF: ${{ github.ref }}
70 | release_pypi:
71 | name: Publish to PyPI
72 | needs: release
73 | runs-on: ubuntu-latest
74 | permissions:
75 | contents: read
76 | if: needs.release.outputs.latest_commit == github.sha
77 | steps:
78 | - uses: actions/setup-node@v2
79 | with:
80 | node-version: 14.x
81 | - uses: actions/setup-python@v2
82 | with:
83 | python-version: 3.x
84 | - name: Download build artifacts
85 | uses: actions/download-artifact@v2
86 | with:
87 | name: build-artifact
88 | path: dist
89 | - name: Prepare Repository
90 | run: mv dist .repo
91 | - name: Install Dependencies
92 | run: cd .repo && yarn install --check-files --frozen-lockfile
93 | - name: Create python artifact
94 | run: cd .repo && npx projen package:python
95 | - name: Collect python Artifact
96 | run: mv .repo/dist dist
97 | - name: Release
98 | run: npx -p publib@latest publib-pypi
99 | env:
100 | TWINE_REPOSITORY_URL: https://fso.jfrog.io/artifactory/api/pypi/fso-pypi
101 | TWINE_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
102 | TWINE_PASSWORD: ${{ secrets.ARTIFACTORY_TOKEN }}
103 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "udp-cdk8s-image",
3 | "description": "Build & Push local docker images inside CDK8s applications",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/cdk8s-team/cdk8s-image"
7 | },
8 | "scripts": {
9 | "build": "npx projen build",
10 | "bump": "npx projen bump",
11 | "clobber": "npx projen clobber",
12 | "compat": "npx projen compat",
13 | "compile": "npx projen compile",
14 | "default": "npx projen default",
15 | "docgen": "npx projen docgen",
16 | "eject": "npx projen eject",
17 | "eslint": "npx projen eslint",
18 | "package": "npx projen package",
19 | "package-all": "npx projen package-all",
20 | "package:python": "npx projen package:python",
21 | "post-compile": "npx projen post-compile",
22 | "post-upgrade": "npx projen post-upgrade",
23 | "pre-compile": "npx projen pre-compile",
24 | "release": "npx projen release",
25 | "test": "npx projen test",
26 | "test:update": "npx projen test:update",
27 | "test:watch": "npx projen test:watch",
28 | "unbump": "npx projen unbump",
29 | "upgrade": "npx projen upgrade",
30 | "watch": "npx projen watch",
31 | "projen": "npx projen"
32 | },
33 | "author": {
34 | "name": "Amazon Web Services",
35 | "url": "https://aws.amazon.com",
36 | "organization": false
37 | },
38 | "devDependencies": {
39 | "@types/jest": "^26.0.24",
40 | "@types/node": "^14",
41 | "@typescript-eslint/eslint-plugin": "^5",
42 | "@typescript-eslint/parser": "^5",
43 | "cdk8s": "2.2.78",
44 | "constructs": "10.0.0",
45 | "eslint": "^8",
46 | "eslint-import-resolver-node": "^0.3.6",
47 | "eslint-import-resolver-typescript": "^2.5.0",
48 | "eslint-plugin-import": "^2.25.4",
49 | "jest": "^26.6.3",
50 | "jest-junit": "^13",
51 | "jsii": "^1.54.0",
52 | "jsii-diff": "^1.54.0",
53 | "jsii-docgen": "^1.8.110",
54 | "json-schema": "^0.4.0",
55 | "npm-check-updates": "^12",
56 | "projen": "^0.52.58",
57 | "standard-version": "^9",
58 | "ts-jest": "^26.5.6",
59 | "typescript": "^3.9.10"
60 | },
61 | "peerDependencies": {
62 | "cdk8s": "^2.2.78",
63 | "constructs": "^10.0.0"
64 | },
65 | "keywords": [
66 | "cdk8s",
67 | "containers",
68 | "docker",
69 | "kubernetes"
70 | ],
71 | "engines": {
72 | "node": ">= 14.17.0"
73 | },
74 | "main": "lib/index.js",
75 | "license": "Apache-2.0",
76 | "version": "0.0.0",
77 | "jest": {
78 | "testMatch": [
79 | "/src/**/__tests__/**/*.ts?(x)",
80 | "/(test|src)/**/?(*.)+(spec|test).ts?(x)"
81 | ],
82 | "clearMocks": true,
83 | "collectCoverage": true,
84 | "coverageReporters": [
85 | "json",
86 | "lcov",
87 | "clover",
88 | "cobertura",
89 | "text"
90 | ],
91 | "coverageDirectory": "coverage",
92 | "coveragePathIgnorePatterns": [
93 | "/node_modules/"
94 | ],
95 | "testPathIgnorePatterns": [
96 | "/node_modules/"
97 | ],
98 | "watchPathIgnorePatterns": [
99 | "/node_modules/"
100 | ],
101 | "reporters": [
102 | "default",
103 | [
104 | "jest-junit",
105 | {
106 | "outputDirectory": "test-reports"
107 | }
108 | ]
109 | ],
110 | "preset": "ts-jest",
111 | "globals": {
112 | "ts-jest": {
113 | "tsconfig": "tsconfig.dev.json"
114 | }
115 | }
116 | },
117 | "types": "lib/index.d.ts",
118 | "stability": "stable",
119 | "jsii": {
120 | "outdir": "dist",
121 | "targets": {
122 | "python": {
123 | "distName": "udp-cdk8s-image",
124 | "module": "udp_cdk8s_image"
125 | }
126 | },
127 | "tsc": {
128 | "outDir": "lib",
129 | "rootDir": "src"
130 | }
131 | },
132 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
133 | }
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | # ~~ Generated by projen. To modify, edit .projenrc.js and run "npx projen".
2 |
3 | name: build
4 | on:
5 | pull_request: {}
6 | workflow_dispatch: {}
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | permissions:
11 | contents: write
12 | outputs:
13 | self_mutation_happened: ${{ steps.self_mutation.outputs.self_mutation_happened }}
14 | env:
15 | CI: "true"
16 | steps:
17 | - name: Checkout
18 | uses: actions/checkout@v2
19 | with:
20 | ref: ${{ github.event.pull_request.head.ref }}
21 | repository: ${{ github.event.pull_request.head.repo.full_name }}
22 | - name: Setup Node.js
23 | uses: actions/setup-node@v2.2.0
24 | with:
25 | node-version: 14.17.0
26 | - name: Install dependencies
27 | run: yarn install --check-files
28 | - name: build
29 | run: npx projen build
30 | - id: self_mutation
31 | name: Find mutations
32 | run: |-
33 | git add .
34 | git diff --staged --patch --exit-code > .repo.patch || echo "::set-output name=self_mutation_happened::true"
35 | - if: steps.self_mutation.outputs.self_mutation_happened
36 | name: Upload patch
37 | uses: actions/upload-artifact@v2
38 | with:
39 | name: .repo.patch
40 | path: .repo.patch
41 | - name: Fail build on mutation
42 | if: steps.self_mutation.outputs.self_mutation_happened
43 | run: |-
44 | echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch."
45 | cat .repo.patch
46 | exit 1
47 | - name: Upload artifact
48 | uses: actions/upload-artifact@v2.1.1
49 | with:
50 | name: build-artifact
51 | path: dist
52 | self-mutation:
53 | needs: build
54 | runs-on: ubuntu-latest
55 | permissions:
56 | contents: write
57 | if: always() && needs.build.outputs.self_mutation_happened && !(github.event.pull_request.head.repo.full_name != github.repository)
58 | steps:
59 | - name: Checkout
60 | uses: actions/checkout@v2
61 | with:
62 | token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
63 | ref: ${{ github.event.pull_request.head.ref }}
64 | repository: ${{ github.event.pull_request.head.repo.full_name }}
65 | - name: Download patch
66 | uses: actions/download-artifact@v2
67 | with:
68 | name: .repo.patch
69 | path: ${{ runner.temp }}
70 | - name: Apply patch
71 | run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."'
72 | - name: Set git identity
73 | run: |-
74 | git config user.name "github-actions"
75 | git config user.email "github-actions@github.com"
76 | - name: Push changes
77 | run: |2-
78 | git add .
79 | git commit -s -m "chore: self mutation"
80 | git push origin HEAD:${{ github.event.pull_request.head.ref }}
81 | package-python:
82 | needs: build
83 | runs-on: ubuntu-latest
84 | permissions: {}
85 | if: "! needs.build.outputs.self_mutation_happened"
86 | steps:
87 | - uses: actions/setup-node@v2
88 | with:
89 | node-version: 14.x
90 | - uses: actions/setup-python@v2
91 | with:
92 | python-version: 3.x
93 | - name: Download build artifacts
94 | uses: actions/download-artifact@v2
95 | with:
96 | name: build-artifact
97 | path: dist
98 | - name: Prepare Repository
99 | run: mv dist .repo
100 | - name: Install Dependencies
101 | run: cd .repo && yarn install --check-files --frozen-lockfile
102 | - name: Create python artifact
103 | run: cd .repo && npx projen package:python
104 | - name: Collect python Artifact
105 | run: mv .repo/dist dist
106 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jest": true,
4 | "node": true
5 | },
6 | "root": true,
7 | "plugins": [
8 | "@typescript-eslint",
9 | "import"
10 | ],
11 | "parser": "@typescript-eslint/parser",
12 | "parserOptions": {
13 | "ecmaVersion": 2018,
14 | "sourceType": "module",
15 | "project": "./tsconfig.dev.json"
16 | },
17 | "extends": [
18 | "plugin:import/typescript"
19 | ],
20 | "settings": {
21 | "import/parsers": {
22 | "@typescript-eslint/parser": [
23 | ".ts",
24 | ".tsx"
25 | ]
26 | },
27 | "import/resolver": {
28 | "node": {},
29 | "typescript": {
30 | "project": "./tsconfig.dev.json",
31 | "alwaysTryTypes": true
32 | }
33 | }
34 | },
35 | "ignorePatterns": [
36 | "*.js",
37 | "!.projenrc.js",
38 | "*.d.ts",
39 | "node_modules/",
40 | "*.generated.ts",
41 | "coverage"
42 | ],
43 | "rules": {
44 | "indent": [
45 | "off"
46 | ],
47 | "@typescript-eslint/indent": [
48 | "error",
49 | 2
50 | ],
51 | "quotes": [
52 | "error",
53 | "single",
54 | {
55 | "avoidEscape": true
56 | }
57 | ],
58 | "comma-dangle": [
59 | "error",
60 | "always-multiline"
61 | ],
62 | "comma-spacing": [
63 | "error",
64 | {
65 | "before": false,
66 | "after": true
67 | }
68 | ],
69 | "no-multi-spaces": [
70 | "error",
71 | {
72 | "ignoreEOLComments": false
73 | }
74 | ],
75 | "array-bracket-spacing": [
76 | "error",
77 | "never"
78 | ],
79 | "array-bracket-newline": [
80 | "error",
81 | "consistent"
82 | ],
83 | "object-curly-spacing": [
84 | "error",
85 | "always"
86 | ],
87 | "object-curly-newline": [
88 | "error",
89 | {
90 | "multiline": true,
91 | "consistent": true
92 | }
93 | ],
94 | "object-property-newline": [
95 | "error",
96 | {
97 | "allowAllPropertiesOnSameLine": true
98 | }
99 | ],
100 | "keyword-spacing": [
101 | "error"
102 | ],
103 | "brace-style": [
104 | "error",
105 | "1tbs",
106 | {
107 | "allowSingleLine": true
108 | }
109 | ],
110 | "space-before-blocks": [
111 | "error"
112 | ],
113 | "curly": [
114 | "error",
115 | "multi-line",
116 | "consistent"
117 | ],
118 | "@typescript-eslint/member-delimiter-style": [
119 | "error"
120 | ],
121 | "semi": [
122 | "error",
123 | "always"
124 | ],
125 | "max-len": [
126 | "error",
127 | {
128 | "code": 150,
129 | "ignoreUrls": true,
130 | "ignoreStrings": true,
131 | "ignoreTemplateLiterals": true,
132 | "ignoreComments": true,
133 | "ignoreRegExpLiterals": true
134 | }
135 | ],
136 | "quote-props": [
137 | "error",
138 | "consistent-as-needed"
139 | ],
140 | "@typescript-eslint/no-require-imports": [
141 | "error"
142 | ],
143 | "import/no-extraneous-dependencies": [
144 | "error",
145 | {
146 | "devDependencies": [
147 | "**/test/**",
148 | "**/build-tools/**"
149 | ],
150 | "optionalDependencies": false,
151 | "peerDependencies": true
152 | }
153 | ],
154 | "import/no-unresolved": [
155 | "error"
156 | ],
157 | "import/order": [
158 | "warn",
159 | {
160 | "groups": [
161 | "builtin",
162 | "external"
163 | ],
164 | "alphabetize": {
165 | "order": "asc",
166 | "caseInsensitive": true
167 | }
168 | }
169 | ],
170 | "no-duplicate-imports": [
171 | "error"
172 | ],
173 | "no-shadow": [
174 | "off"
175 | ],
176 | "@typescript-eslint/no-shadow": [
177 | "error"
178 | ],
179 | "key-spacing": [
180 | "error"
181 | ],
182 | "no-multiple-empty-lines": [
183 | "error"
184 | ],
185 | "@typescript-eslint/no-floating-promises": [
186 | "error"
187 | ],
188 | "no-return-await": [
189 | "off"
190 | ],
191 | "@typescript-eslint/return-await": [
192 | "error"
193 | ],
194 | "no-trailing-spaces": [
195 | "error"
196 | ],
197 | "dot-notation": [
198 | "error"
199 | ],
200 | "no-bitwise": [
201 | "error"
202 | ],
203 | "@typescript-eslint/member-ordering": [
204 | "error",
205 | {
206 | "default": [
207 | "public-static-field",
208 | "public-static-method",
209 | "protected-static-field",
210 | "protected-static-method",
211 | "private-static-field",
212 | "private-static-method",
213 | "field",
214 | "constructor",
215 | "method"
216 | ]
217 | }
218 | ]
219 | },
220 | "overrides": [
221 | {
222 | "files": [
223 | ".projenrc.js"
224 | ],
225 | "rules": {
226 | "@typescript-eslint/no-require-imports": "off",
227 | "import/no-extraneous-dependencies": "off"
228 | }
229 | }
230 | ]
231 | }
232 |
--------------------------------------------------------------------------------
/.projen/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": {
3 | "build": {
4 | "name": "build",
5 | "description": "Full release build",
6 | "steps": [
7 | {
8 | "spawn": "default"
9 | },
10 | {
11 | "spawn": "pre-compile"
12 | },
13 | {
14 | "spawn": "compile"
15 | },
16 | {
17 | "spawn": "post-compile"
18 | },
19 | {
20 | "spawn": "test"
21 | },
22 | {
23 | "spawn": "package"
24 | }
25 | ]
26 | },
27 | "bump": {
28 | "name": "bump",
29 | "description": "Bumps version based on latest git tag and generates a changelog entry",
30 | "env": {
31 | "OUTFILE": "package.json",
32 | "CHANGELOG": "dist/changelog.md",
33 | "BUMPFILE": "dist/version.txt",
34 | "RELEASETAG": "dist/releasetag.txt"
35 | },
36 | "steps": [
37 | {
38 | "builtin": "release/bump-version"
39 | }
40 | ],
41 | "condition": "! git log --oneline -1 | grep -q \"chore(release):\""
42 | },
43 | "clobber": {
44 | "name": "clobber",
45 | "description": "hard resets to HEAD of origin and cleans the local repo",
46 | "env": {
47 | "BRANCH": "$(git branch --show-current)"
48 | },
49 | "steps": [
50 | {
51 | "exec": "git checkout -b scratch",
52 | "name": "save current HEAD in \"scratch\" branch"
53 | },
54 | {
55 | "exec": "git checkout $BRANCH"
56 | },
57 | {
58 | "exec": "git fetch origin",
59 | "name": "fetch latest changes from origin"
60 | },
61 | {
62 | "exec": "git reset --hard origin/$BRANCH",
63 | "name": "hard reset to origin commit"
64 | },
65 | {
66 | "exec": "git clean -fdx",
67 | "name": "clean all untracked files"
68 | },
69 | {
70 | "say": "ready to rock! (unpushed commits are under the \"scratch\" branch)"
71 | }
72 | ],
73 | "condition": "git diff --exit-code > /dev/null"
74 | },
75 | "compat": {
76 | "name": "compat",
77 | "description": "Perform API compatibility check against latest version",
78 | "steps": [
79 | {
80 | "exec": "jsii-diff npm:$(node -p \"require('./package.json').name\") -k --ignore-file .compatignore || (echo \"\nUNEXPECTED BREAKING CHANGES: add keys such as 'removed:constructs.Node.of' to .compatignore to skip.\n\" && exit 1)"
81 | }
82 | ]
83 | },
84 | "compile": {
85 | "name": "compile",
86 | "description": "Only compile",
87 | "steps": [
88 | {
89 | "exec": "jsii --silence-warnings=reserved-word --no-fix-peer-dependencies"
90 | }
91 | ]
92 | },
93 | "default": {
94 | "name": "default",
95 | "description": "Synthesize project files",
96 | "steps": [
97 | {
98 | "exec": "node .projenrc.js"
99 | }
100 | ]
101 | },
102 | "docgen": {
103 | "name": "docgen",
104 | "description": "Generate API.md from .jsii manifest",
105 | "steps": [
106 | {
107 | "exec": "jsii-docgen -o API.md"
108 | }
109 | ]
110 | },
111 | "eject": {
112 | "name": "eject",
113 | "description": "Remove projen from the project",
114 | "env": {
115 | "PROJEN_EJECTING": "true"
116 | },
117 | "steps": [
118 | {
119 | "spawn": "default"
120 | }
121 | ]
122 | },
123 | "eslint": {
124 | "name": "eslint",
125 | "description": "Runs eslint against the codebase",
126 | "steps": [
127 | {
128 | "exec": "eslint --ext .ts,.tsx --fix --no-error-on-unmatched-pattern src test build-tools .projenrc.js"
129 | }
130 | ]
131 | },
132 | "package": {
133 | "name": "package",
134 | "description": "Creates the distribution package",
135 | "steps": [
136 | {
137 | "exec": "if [ ! -z ${CI} ]; then mkdir -p dist && rsync -a . dist --exclude .git --exclude node_modules; else npx projen package-all; fi"
138 | }
139 | ]
140 | },
141 | "package-all": {
142 | "name": "package-all",
143 | "description": "Packages artifacts for all target languages",
144 | "steps": [
145 | {
146 | "spawn": "package:python"
147 | }
148 | ]
149 | },
150 | "package:python": {
151 | "name": "package:python",
152 | "description": "Create python language bindings",
153 | "steps": [
154 | {
155 | "exec": "jsii_version=$(node -p \"JSON.parse(fs.readFileSync('.jsii')).jsiiVersion.split(' ')[0]\")"
156 | },
157 | {
158 | "exec": "npx jsii-pacmak@$jsii_version -v --target python"
159 | }
160 | ]
161 | },
162 | "post-compile": {
163 | "name": "post-compile",
164 | "description": "Runs after successful compilation",
165 | "steps": [
166 | {
167 | "spawn": "docgen"
168 | }
169 | ]
170 | },
171 | "post-upgrade": {
172 | "name": "post-upgrade",
173 | "description": "Runs after upgrading dependencies"
174 | },
175 | "pre-compile": {
176 | "name": "pre-compile",
177 | "description": "Prepare the project for compilation"
178 | },
179 | "release": {
180 | "name": "release",
181 | "description": "Prepare a release from \"main\" branch",
182 | "env": {
183 | "RELEASE": "true"
184 | },
185 | "steps": [
186 | {
187 | "exec": "rm -fr dist"
188 | },
189 | {
190 | "spawn": "bump"
191 | },
192 | {
193 | "spawn": "build"
194 | },
195 | {
196 | "spawn": "unbump"
197 | },
198 | {
199 | "exec": "git diff --ignore-space-at-eol --exit-code"
200 | }
201 | ]
202 | },
203 | "test": {
204 | "name": "test",
205 | "description": "Run tests",
206 | "steps": [
207 | {
208 | "exec": "jest --passWithNoTests --all --updateSnapshot --coverageProvider=v8"
209 | },
210 | {
211 | "spawn": "eslint"
212 | }
213 | ]
214 | },
215 | "test:update": {
216 | "name": "test:update",
217 | "description": "Update jest snapshots",
218 | "steps": [
219 | {
220 | "exec": "jest --updateSnapshot"
221 | }
222 | ]
223 | },
224 | "test:watch": {
225 | "name": "test:watch",
226 | "description": "Run jest in watch mode",
227 | "steps": [
228 | {
229 | "exec": "jest --watch"
230 | }
231 | ]
232 | },
233 | "unbump": {
234 | "name": "unbump",
235 | "description": "Restores version to 0.0.0",
236 | "env": {
237 | "OUTFILE": "package.json",
238 | "CHANGELOG": "dist/changelog.md",
239 | "BUMPFILE": "dist/version.txt",
240 | "RELEASETAG": "dist/releasetag.txt"
241 | },
242 | "steps": [
243 | {
244 | "builtin": "release/reset-version"
245 | }
246 | ]
247 | },
248 | "upgrade": {
249 | "name": "upgrade",
250 | "description": "upgrade dependencies",
251 | "env": {
252 | "CI": "0"
253 | },
254 | "steps": [
255 | {
256 | "exec": "npm-check-updates --dep dev --upgrade --target=minor"
257 | },
258 | {
259 | "exec": "npm-check-updates --dep optional --upgrade --target=minor"
260 | },
261 | {
262 | "exec": "npm-check-updates --dep peer --upgrade --target=minor"
263 | },
264 | {
265 | "exec": "npm-check-updates --dep prod --upgrade --target=minor"
266 | },
267 | {
268 | "exec": "npm-check-updates --dep bundle --upgrade --target=minor"
269 | },
270 | {
271 | "exec": "yarn install --check-files"
272 | },
273 | {
274 | "exec": "yarn upgrade"
275 | },
276 | {
277 | "exec": "npx projen"
278 | },
279 | {
280 | "spawn": "post-upgrade"
281 | }
282 | ]
283 | },
284 | "watch": {
285 | "name": "watch",
286 | "description": "Watch & compile in the background",
287 | "steps": [
288 | {
289 | "exec": "jsii -w --silence-warnings=reserved-word --no-fix-peer-dependencies"
290 | }
291 | ]
292 | }
293 | },
294 | "env": {
295 | "PATH": "$(npx -c \"node -e \\\"console.log(process.env.PATH)\\\"\")"
296 | },
297 | "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
298 | }
299 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------