skuba 7.3.1 → 7.4.0-horrible-hacks-20240206023615

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/README.md +3 -3
  2. package/jest/transform.test.ts +3 -1
  3. package/lib/api/jest/index.d.ts +1 -1
  4. package/lib/api/jest/index.js.map +2 -2
  5. package/lib/cli/adapter/prettier.d.ts +1 -1
  6. package/lib/cli/adapter/prettier.js +11 -10
  7. package/lib/cli/adapter/prettier.js.map +2 -2
  8. package/lib/cli/build/index.js +0 -2
  9. package/lib/cli/build/index.js.map +2 -2
  10. package/lib/cli/buildPackage.js +0 -2
  11. package/lib/cli/buildPackage.js.map +2 -2
  12. package/lib/cli/configure/analyseConfiguration.d.ts +2 -0
  13. package/lib/cli/configure/analyseConfiguration.js.map +2 -2
  14. package/lib/cli/configure/getEntryPoint.js +1 -1
  15. package/lib/cli/configure/getEntryPoint.js.map +2 -2
  16. package/lib/cli/configure/getProjectType.js +1 -1
  17. package/lib/cli/configure/getProjectType.js.map +2 -2
  18. package/lib/cli/configure/index.js +11 -8
  19. package/lib/cli/configure/index.js.map +2 -2
  20. package/lib/cli/configure/modules/index.js +0 -2
  21. package/lib/cli/configure/modules/index.js.map +2 -2
  22. package/lib/cli/configure/modules/package.d.ts +1 -1
  23. package/lib/cli/configure/modules/package.js +2 -1
  24. package/lib/cli/configure/modules/package.js.map +2 -2
  25. package/lib/cli/configure/patchRenovateConfig.d.ts +2 -1
  26. package/lib/cli/configure/patchRenovateConfig.js +23 -10
  27. package/lib/cli/configure/patchRenovateConfig.js.map +2 -2
  28. package/lib/cli/configure/types.d.ts +2 -0
  29. package/lib/cli/configure/types.js.map +1 -1
  30. package/lib/cli/configure/upgrade/index.d.ts +15 -0
  31. package/lib/cli/configure/upgrade/index.js +130 -0
  32. package/lib/cli/configure/upgrade/index.js.map +7 -0
  33. package/lib/cli/configure/{addEmptyExports.d.ts → upgrade/patches/7.3.1/addEmptyExports.d.ts} +2 -2
  34. package/lib/cli/configure/{addEmptyExports.js → upgrade/patches/7.3.1/addEmptyExports.js} +15 -11
  35. package/lib/cli/configure/upgrade/patches/7.3.1/addEmptyExports.js.map +7 -0
  36. package/lib/cli/configure/upgrade/patches/7.3.1/index.d.ts +2 -0
  37. package/lib/cli/configure/upgrade/patches/7.3.1/index.js +55 -0
  38. package/lib/cli/configure/upgrade/patches/7.3.1/index.js.map +7 -0
  39. package/lib/cli/configure/upgrade/patches/7.3.1/moveNpmrcOutOfGitignoreManagedSection.d.ts +2 -0
  40. package/lib/cli/configure/upgrade/patches/7.3.1/moveNpmrcOutOfGitignoreManagedSection.js +94 -0
  41. package/lib/cli/configure/upgrade/patches/7.3.1/moveNpmrcOutOfGitignoreManagedSection.js.map +7 -0
  42. package/lib/cli/configure/upgrade/patches/7.3.1/patchDockerfile.d.ts +2 -0
  43. package/lib/cli/configure/{patchDockerfile.js → upgrade/patches/7.3.1/patchDockerfile.js} +18 -12
  44. package/lib/cli/configure/upgrade/patches/7.3.1/patchDockerfile.js.map +7 -0
  45. package/lib/cli/configure/upgrade/patches/7.3.1/patchServerListener.d.ts +2 -0
  46. package/lib/cli/configure/{patchServerListener.js → upgrade/patches/7.3.1/patchServerListener.js} +18 -14
  47. package/lib/cli/configure/upgrade/patches/7.3.1/patchServerListener.js.map +7 -0
  48. package/lib/cli/format.js +7 -14
  49. package/lib/cli/format.js.map +2 -2
  50. package/lib/cli/init/getConfig.d.ts +4 -2
  51. package/lib/cli/init/getConfig.js +53 -26
  52. package/lib/cli/init/getConfig.js.map +2 -2
  53. package/lib/cli/init/git.d.ts +2 -1
  54. package/lib/cli/init/git.js +2 -9
  55. package/lib/cli/init/git.js.map +2 -2
  56. package/lib/cli/init/index.d.ts +1 -1
  57. package/lib/cli/init/index.js +19 -9
  58. package/lib/cli/init/index.js.map +2 -2
  59. package/lib/cli/init/prompts.d.ts +26 -3
  60. package/lib/cli/init/prompts.js +10 -2
  61. package/lib/cli/init/prompts.js.map +2 -2
  62. package/lib/cli/init/types.d.ts +21 -0
  63. package/lib/cli/init/types.js +5 -1
  64. package/lib/cli/init/types.js.map +2 -2
  65. package/lib/cli/init/writePackageJson.d.ts +6 -0
  66. package/lib/cli/init/writePackageJson.js.map +2 -2
  67. package/lib/cli/lint/annotate/buildkite/index.d.ts +2 -1
  68. package/lib/cli/lint/annotate/buildkite/index.js +5 -3
  69. package/lib/cli/lint/annotate/buildkite/index.js.map +2 -2
  70. package/lib/cli/lint/annotate/buildkite/internal.d.ts +2 -0
  71. package/lib/cli/lint/annotate/buildkite/internal.js +45 -0
  72. package/lib/cli/lint/annotate/buildkite/internal.js.map +7 -0
  73. package/lib/cli/lint/annotate/github/index.d.ts +2 -1
  74. package/lib/cli/lint/annotate/github/index.js +4 -2
  75. package/lib/cli/lint/annotate/github/index.js.map +2 -2
  76. package/lib/cli/lint/annotate/github/internal.d.ts +3 -0
  77. package/lib/cli/lint/annotate/github/internal.js +36 -0
  78. package/lib/cli/lint/annotate/github/internal.js.map +7 -0
  79. package/lib/cli/lint/annotate/index.d.ts +4 -3
  80. package/lib/cli/lint/annotate/index.js +9 -3
  81. package/lib/cli/lint/annotate/index.js.map +2 -2
  82. package/lib/cli/lint/autofix.d.ts +3 -1
  83. package/lib/cli/lint/autofix.js +36 -59
  84. package/lib/cli/lint/autofix.js.map +3 -3
  85. package/lib/cli/lint/external.d.ts +6 -1
  86. package/lib/cli/lint/external.js +6 -29
  87. package/lib/cli/lint/external.js.map +2 -2
  88. package/lib/cli/lint/index.d.ts +2 -1
  89. package/lib/cli/lint/index.js +46 -14
  90. package/lib/cli/lint/index.js.map +2 -2
  91. package/lib/cli/lint/internal.d.ts +12 -1
  92. package/lib/cli/lint/internal.js +55 -19
  93. package/lib/cli/lint/internal.js.map +3 -3
  94. package/lib/cli/lint/internalLints/deleteFiles.d.ts +3 -0
  95. package/lib/cli/lint/internalLints/deleteFiles.js +102 -0
  96. package/lib/cli/lint/internalLints/deleteFiles.js.map +7 -0
  97. package/lib/cli/lint/internalLints/noSkubaTemplateJs.d.ts +3 -0
  98. package/lib/cli/lint/internalLints/noSkubaTemplateJs.js +75 -0
  99. package/lib/cli/lint/internalLints/noSkubaTemplateJs.js.map +7 -0
  100. package/lib/cli/lint/internalLints/refreshConfigFiles.d.ts +11 -0
  101. package/lib/cli/lint/internalLints/refreshConfigFiles.js +147 -0
  102. package/lib/cli/lint/internalLints/refreshConfigFiles.js.map +7 -0
  103. package/lib/cli/test/index.js +0 -2
  104. package/lib/cli/test/index.js.map +2 -2
  105. package/lib/skuba.d.ts +1 -1
  106. package/lib/skuba.js.map +1 -1
  107. package/lib/utils/exec.d.ts +2 -1
  108. package/lib/utils/exec.js +1 -0
  109. package/lib/utils/exec.js.map +2 -2
  110. package/lib/utils/logging.d.ts +2 -0
  111. package/lib/utils/logging.js +1 -0
  112. package/lib/utils/logging.js.map +2 -2
  113. package/lib/utils/logo.js +6 -10
  114. package/lib/utils/logo.js.map +3 -3
  115. package/lib/utils/manifest.d.ts +1 -1
  116. package/lib/utils/manifest.js +1 -1
  117. package/lib/utils/manifest.js.map +2 -2
  118. package/lib/utils/npmrc.d.ts +1 -0
  119. package/lib/utils/npmrc.js +29 -0
  120. package/lib/utils/npmrc.js.map +7 -0
  121. package/lib/utils/packageManager.d.ts +24 -0
  122. package/lib/utils/packageManager.js +97 -0
  123. package/lib/utils/packageManager.js.map +7 -0
  124. package/lib/utils/template.d.ts +3 -0
  125. package/lib/utils/template.js +2 -0
  126. package/lib/utils/template.js.map +2 -2
  127. package/lib/utils/worker.d.ts +1 -0
  128. package/lib/wrapper/http.d.ts +1 -0
  129. package/package.json +39 -36
  130. package/template/base/_.dockerignore +0 -1
  131. package/template/base/_.eslintignore +1 -0
  132. package/template/base/_.gitignore +1 -1
  133. package/template/base/_.npmrc +8 -0
  134. package/template/express-rest-api/.buildkite/pipeline.yml +13 -10
  135. package/template/express-rest-api/.gantry/dev.yml +3 -0
  136. package/template/express-rest-api/Dockerfile +6 -12
  137. package/template/express-rest-api/Dockerfile.dev-deps +6 -5
  138. package/template/express-rest-api/README.md +6 -6
  139. package/template/express-rest-api/docker-compose.yml +0 -10
  140. package/template/express-rest-api/gantry.apply.yml +5 -0
  141. package/template/express-rest-api/gantry.build.yml +1 -2
  142. package/template/express-rest-api/package.json +2 -2
  143. package/template/express-rest-api/skuba.template.js +1 -0
  144. package/template/greeter/.buildkite/pipeline.yml +12 -9
  145. package/template/greeter/Dockerfile +6 -5
  146. package/template/greeter/README.md +6 -6
  147. package/template/greeter/docker-compose.yml +0 -10
  148. package/template/greeter/package.json +1 -1
  149. package/template/greeter/skuba.template.js +1 -0
  150. package/template/koa-rest-api/.buildkite/pipeline.yml +13 -10
  151. package/template/koa-rest-api/.gantry/dev.yml +3 -0
  152. package/template/koa-rest-api/.nvmrc +1 -1
  153. package/template/koa-rest-api/Dockerfile +6 -12
  154. package/template/koa-rest-api/Dockerfile.dev-deps +6 -5
  155. package/template/koa-rest-api/README.md +6 -6
  156. package/template/koa-rest-api/docker-compose.yml +0 -10
  157. package/template/koa-rest-api/gantry.apply.yml +5 -0
  158. package/template/koa-rest-api/gantry.build.yml +1 -2
  159. package/template/koa-rest-api/package.json +8 -6
  160. package/template/koa-rest-api/skuba.template.js +1 -0
  161. package/template/koa-rest-api/src/framework/validation.test.ts +48 -15
  162. package/template/koa-rest-api/src/framework/validation.ts +31 -8
  163. package/template/koa-rest-api/src/testing/types.ts +16 -4
  164. package/template/lambda-sqs-worker/.buildkite/pipeline.yml +21 -15
  165. package/template/lambda-sqs-worker/Dockerfile +6 -6
  166. package/template/lambda-sqs-worker/README.md +8 -8
  167. package/template/lambda-sqs-worker/_.npmrc +12 -0
  168. package/template/lambda-sqs-worker/docker-compose.yml +0 -15
  169. package/template/lambda-sqs-worker/package.json +3 -4
  170. package/template/lambda-sqs-worker/serverless.yml +4 -1
  171. package/template/lambda-sqs-worker/skuba.template.js +1 -0
  172. package/template/lambda-sqs-worker/src/hooks.ts +1 -2
  173. package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +42 -18
  174. package/template/lambda-sqs-worker-cdk/.nvmrc +1 -1
  175. package/template/lambda-sqs-worker-cdk/Dockerfile +9 -7
  176. package/template/lambda-sqs-worker-cdk/cdk.json +12 -6
  177. package/template/lambda-sqs-worker-cdk/docker-compose.yml +0 -15
  178. package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +1587 -225
  179. package/template/lambda-sqs-worker-cdk/infra/appStack.test.ts +23 -3
  180. package/template/lambda-sqs-worker-cdk/infra/appStack.ts +127 -14
  181. package/template/lambda-sqs-worker-cdk/package.json +5 -3
  182. package/template/lambda-sqs-worker-cdk/shared/context-types.ts +1 -0
  183. package/template/lambda-sqs-worker-cdk/skuba.template.js +1 -0
  184. package/template/lambda-sqs-worker-cdk/src/app.ts +14 -1
  185. package/template/lambda-sqs-worker-cdk/src/postHook.ts +154 -0
  186. package/template/lambda-sqs-worker-cdk/src/preHook.ts +95 -0
  187. package/template/oss-npm-package/.github/workflows/release.yml +10 -7
  188. package/template/oss-npm-package/.github/workflows/validate.yml +10 -7
  189. package/template/oss-npm-package/.releaserc +16 -0
  190. package/template/oss-npm-package/README.md +17 -17
  191. package/template/oss-npm-package/_package.json +3 -2
  192. package/template/oss-npm-package/skuba.template.js +1 -0
  193. package/template/private-npm-package/.releaserc +16 -0
  194. package/template/private-npm-package/README.md +16 -16
  195. package/template/private-npm-package/_package.json +3 -3
  196. package/template/private-npm-package/skuba.template.js +1 -0
  197. package/lib/cli/configure/addEmptyExports.js.map +0 -7
  198. package/lib/cli/configure/modules/tsconfig.d.ts +0 -2
  199. package/lib/cli/configure/modules/tsconfig.js +0 -87
  200. package/lib/cli/configure/modules/tsconfig.js.map +0 -7
  201. package/lib/cli/configure/patchDockerfile.d.ts +0 -1
  202. package/lib/cli/configure/patchDockerfile.js.map +0 -7
  203. package/lib/cli/configure/patchServerListener.d.ts +0 -3
  204. package/lib/cli/configure/patchServerListener.js.map +0 -7
  205. package/lib/cli/configure/refreshIgnoreFiles.d.ts +0 -3
  206. package/lib/cli/configure/refreshIgnoreFiles.js +0 -78
  207. package/lib/cli/configure/refreshIgnoreFiles.js.map +0 -7
@@ -17,6 +17,10 @@ env:
17
17
  {{$key}}: {{$value}}
18
18
  {{end}}
19
19
 
20
+ {{if .Values.cloudwatchDashboardDisabled}}
21
+ cloudwatchDashboardDisabled: {{values "cloudwatchDashboardDisabled"}}
22
+ {{end}}
23
+
20
24
  {{if .Values.datadogSecretId}}
21
25
  datadogSecretId: '{{values "datadogSecretId"}}'
22
26
  {{end}}
@@ -118,3 +122,4 @@ tags:
118
122
  {{end}}
119
123
 
120
124
  cpuArchitecture: <%- platformName %>
125
+ readOnlyRootFilesystem: true
@@ -6,8 +6,7 @@ image: '{{values "image"}}'
6
6
 
7
7
  buildArgs:
8
8
  # https://github.com/seek-oss/docker-ecr-cache-buildkite-plugin#building-on-the-resulting-image
9
- BASE_IMAGE: '{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_IMAGE}}'
10
- BASE_TAG: '{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_TAG}}'
9
+ BASE_IMAGE: '{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_IMAGE}}:{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_TAG}}'
11
10
 
12
11
  # SEEK-Jobs/gantry#1661
13
12
  failOnScanFindings: false
@@ -6,7 +6,7 @@
6
6
  "format": "skuba format",
7
7
  "lint": "skuba lint",
8
8
  "start": "skuba start --port <%- port %>",
9
- "start:debug": "yarn start --inspect-brk",
9
+ "start:debug": "pnpm run --silent start --inspect-brk",
10
10
  "test": "skuba test",
11
11
  "test:ci": "skuba test --coverage",
12
12
  "test:watch": "skuba test --watch"
@@ -19,7 +19,7 @@
19
19
  "devDependencies": {
20
20
  "@types/express": "^4.17.13",
21
21
  "@types/node": "^20.9.0",
22
- "@types/supertest": "^2.0.11",
22
+ "@types/supertest": "^6.0.0",
23
23
  "pino-pretty": "^10.0.0",
24
24
  "skuba": "*",
25
25
  "supertest": "^6.1.6"
@@ -45,5 +45,6 @@ module.exports = {
45
45
  validate: (value) => /^[a-z]{2}-[a-z]+-\d+$/.test(value),
46
46
  },
47
47
  ],
48
+ packageManager: 'pnpm',
48
49
  type: 'application',
49
50
  };
@@ -4,15 +4,13 @@ agents:
4
4
  configs:
5
5
  plugins:
6
6
  - &aws-sm
7
- seek-oss/aws-sm#v2.3.1:
7
+ seek-oss/aws-sm#v2.3.2:
8
8
  env:
9
9
  NPM_READ_TOKEN: arn:aws:secretsmanager:ap-southeast-2:987872074697:secret:npm/npm-read-token
10
10
 
11
11
  - &docker-ecr-cache
12
- seek-oss/docker-ecr-cache#v2.1.0:
13
- cache-on:
14
- - package.json
15
- - yarn.lock
12
+ seek-oss/docker-ecr-cache#v2.1.1:
13
+ cache-on: pnpm-lock.yaml
16
14
  secrets: id=npm,src=tmp/.npmrc
17
15
 
18
16
  - &private-npm
@@ -23,10 +21,12 @@ configs:
23
21
  steps:
24
22
  - label: 🧪 Test & Lint
25
23
  commands:
26
- - echo '+++ yarn test:ci'
27
- - yarn test:ci
28
- - echo '--- yarn lint'
29
- - yarn lint
24
+ - echo '--- pnpm install --offline'
25
+ - pnpm install --offline
26
+ - echo '+++ pnpm run test:ci'
27
+ - pnpm run test:ci
28
+ - echo '--- pnpm run lint'
29
+ - pnpm run lint
30
30
  env:
31
31
  GET_GITHUB_TOKEN: please
32
32
  plugins:
@@ -35,4 +35,7 @@ steps:
35
35
  - *docker-ecr-cache
36
36
  - docker-compose#v4.16.0:
37
37
  run: app
38
+ environment:
39
+ - GITHUB_API_TOKEN
40
+ propagate-environment: true
38
41
  timeout_in_minutes: 10
@@ -2,10 +2,11 @@
2
2
 
3
3
  FROM --platform=${BUILDPLATFORM:-<%- platformName %>} node:20-alpine AS dev-deps
4
4
 
5
- WORKDIR /workdir
5
+ RUN corepack enable pnpm
6
+ RUN pnpm config set store-dir /root/.pnpm-store
6
7
 
7
- COPY package.json yarn.lock ./
8
+ WORKDIR /workdir
8
9
 
9
- RUN \
10
- --mount=type=secret,id=npm,dst=/root/.npmrc \
11
- yarn install --frozen-lockfile --ignore-optional --non-interactive
10
+ RUN --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
11
+ --mount=type=secret,id=npm,dst=/root/.npmrc,required=true \
12
+ pnpm fetch
@@ -7,7 +7,7 @@ Next steps:
7
7
  1. [ ] Finish templating if this was skipped earlier:
8
8
 
9
9
  ```shell
10
- yarn skuba configure
10
+ pnpm exec skuba configure
11
11
  ```
12
12
 
13
13
  2. [ ] Create a new repository in the appropriate GitHub organisation.
@@ -36,27 +36,27 @@ It's a barebones Node.js application that comprises:
36
36
  ### Test
37
37
 
38
38
  ```shell
39
- yarn test
39
+ pnpm run test
40
40
  ```
41
41
 
42
42
  ### Lint
43
43
 
44
44
  ```shell
45
45
  # Fix issues
46
- yarn format
46
+ pnpm run format
47
47
 
48
48
  # Check for issues
49
- yarn lint
49
+ pnpm run lint
50
50
  ```
51
51
 
52
52
  ### Start
53
53
 
54
54
  ```shell
55
55
  # Start a live-reloading process
56
- yarn start
56
+ pnpm run start
57
57
 
58
58
  # Start with Node.js Inspector enabled
59
- yarn start:debug
59
+ pnpm run start:debug
60
60
  ```
61
61
 
62
62
  This runs a live-reloading Node.js process pointing to the [src/app.ts](src/app.ts) entrypoint.
@@ -2,16 +2,6 @@ version: '3.7'
2
2
 
3
3
  services:
4
4
  app:
5
- environment:
6
- # Enable Buildkite + GitHub integrations.
7
- - BUILDKITE
8
- - BUILDKITE_AGENT_ACCESS_TOKEN
9
- - BUILDKITE_BRANCH
10
- - BUILDKITE_BUILD_NUMBER
11
- - BUILDKITE_JOB_ID
12
- - BUILDKITE_PIPELINE_DEFAULT_BRANCH
13
- - BUILDKITE_STEP_ID
14
- - GITHUB_API_TOKEN
15
5
  image: ${BUILDKITE_PLUGIN_DOCKER_IMAGE:-''}
16
6
  init: true
17
7
  volumes:
@@ -6,7 +6,7 @@
6
6
  "format": "skuba format",
7
7
  "lint": "skuba lint",
8
8
  "start": "skuba start",
9
- "start:debug": "yarn start --inspect-brk",
9
+ "start:debug": "pnpm run --silent start --inspect-brk",
10
10
  "test": "skuba test",
11
11
  "test:ci": "skuba test --coverage",
12
12
  "test:watch": "skuba test --watch"
@@ -12,5 +12,6 @@ module.exports = {
12
12
  validate: (value) => /^.+:.+$/.test(value),
13
13
  },
14
14
  ],
15
+ packageManager: 'pnpm',
15
16
  type: 'application',
16
17
  };
@@ -4,15 +4,13 @@ agents:
4
4
  configs:
5
5
  plugins:
6
6
  - &aws-sm
7
- seek-oss/aws-sm#v2.3.1:
7
+ seek-oss/aws-sm#v2.3.2:
8
8
  env:
9
9
  NPM_READ_TOKEN: arn:aws:secretsmanager:ap-southeast-2:987872074697:secret:npm/npm-read-token
10
10
 
11
11
  - &docker-ecr-cache
12
- seek-oss/docker-ecr-cache#v2.1.0: &docker-ecr-cache-defaults
13
- cache-on:
14
- - package.json
15
- - yarn.lock
12
+ seek-oss/docker-ecr-cache#v2.1.1: &docker-ecr-cache-defaults
13
+ cache-on: pnpm-lock.yaml
16
14
  dockerfile: Dockerfile.dev-deps
17
15
  secrets: id=npm,src=tmp/.npmrc
18
16
 
@@ -37,16 +35,18 @@ steps:
37
35
  plugins:
38
36
  - *aws-sm
39
37
  - *private-npm
40
- - seek-oss/docker-ecr-cache#v2.1.0:
38
+ - seek-oss/docker-ecr-cache#v2.1.1:
41
39
  <<: *docker-ecr-cache-defaults
42
40
  skip-pull-from-cache: true
43
41
 
44
42
  - label: 🧪 Test & Lint
45
43
  commands:
46
- - echo '+++ yarn test:ci'
47
- - yarn test:ci
48
- - echo '--- yarn lint'
49
- - yarn lint
44
+ - echo '--- pnpm install --offline'
45
+ - pnpm install --offline
46
+ - echo '+++ pnpm run test:ci'
47
+ - pnpm run test:ci
48
+ - echo '--- pnpm run lint'
49
+ - pnpm run lint
50
50
  depends_on: warm-prod
51
51
  env:
52
52
  GET_GITHUB_TOKEN: please
@@ -56,6 +56,9 @@ steps:
56
56
  - *docker-ecr-cache
57
57
  - docker-compose#v4.16.0:
58
58
  run: app
59
+ environment:
60
+ - GITHUB_API_TOKEN
61
+ propagate-environment: true
59
62
  timeout_in_minutes: 10
60
63
 
61
64
  - label: 📦 Build & Package
@@ -7,5 +7,8 @@ isProduction: false
7
7
  maxInstanceCount: 1
8
8
  minInstanceCount: 1
9
9
 
10
+ # Disable dashboard for cost savings
11
+ cloudwatchDashboardDisabled: true
12
+
10
13
  openTelemetry:
11
14
  enabled: false
@@ -1 +1 @@
1
- 18
1
+ 20
@@ -1,29 +1,23 @@
1
1
  ARG BASE_IMAGE
2
- ARG BASE_TAG
3
2
 
4
3
  ###
5
4
 
6
- FROM ${BASE_IMAGE}:${BASE_TAG} AS deps
7
-
8
- RUN yarn install --ignore-optional --ignore-scripts --non-interactive --offline --production
9
-
10
- ###
11
-
12
- FROM ${BASE_IMAGE}:${BASE_TAG} AS build
5
+ FROM ${BASE_IMAGE} AS build
13
6
 
14
7
  COPY . .
15
8
 
16
- RUN yarn build
9
+ RUN pnpm install --offline
10
+ RUN pnpm run build
11
+ RUN pnpm install --offline --prod
17
12
 
18
13
  ###
19
14
 
20
- FROM --platform=${BUILDPLATFORM:-<%- platformName %>} gcr.io/distroless/nodejs20-debian11 AS runtime
15
+ FROM --platform=${BUILDPLATFORM:-<%- platformName %>} gcr.io/distroless/nodejs20-debian12 AS runtime
21
16
 
22
17
  WORKDIR /workdir
23
18
 
24
19
  COPY --from=build /workdir/lib lib
25
-
26
- COPY --from=deps /workdir/node_modules node_modules
20
+ COPY --from=build /workdir/node_modules node_modules
27
21
 
28
22
  ENV NODE_ENV=production
29
23
 
@@ -2,10 +2,11 @@
2
2
 
3
3
  FROM --platform=${BUILDPLATFORM:-<%- platformName %>} node:20-alpine AS dev-deps
4
4
 
5
- WORKDIR /workdir
5
+ RUN corepack enable pnpm
6
+ RUN pnpm config set store-dir /root/.pnpm-store
6
7
 
7
- COPY package.json yarn.lock ./
8
+ WORKDIR /workdir
8
9
 
9
- RUN \
10
- --mount=type=secret,id=npm,dst=/root/.npmrc \
11
- yarn install --frozen-lockfile --ignore-optional --non-interactive
10
+ RUN --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
11
+ --mount=type=secret,id=npm,dst=/root/.npmrc,required=true \
12
+ pnpm fetch
@@ -7,7 +7,7 @@ Next steps:
7
7
  1. [ ] Finish templating if this was skipped earlier:
8
8
 
9
9
  ```shell
10
- yarn skuba configure
10
+ pnpm exec skuba configure
11
11
  ```
12
12
 
13
13
  2. [ ] Create a new repository in the appropriate GitHub organisation.
@@ -48,27 +48,27 @@ This defaults to an HTTP request to the `GET /smoke` endpoint.
48
48
  ### Test
49
49
 
50
50
  ```shell
51
- yarn test
51
+ pnpm run test
52
52
  ```
53
53
 
54
54
  ### Lint
55
55
 
56
56
  ```shell
57
57
  # Fix issues
58
- yarn format
58
+ pnpm run format
59
59
 
60
60
  # Check for issues
61
- yarn lint
61
+ pnpm run lint
62
62
  ```
63
63
 
64
64
  ### Start
65
65
 
66
66
  ```shell
67
67
  # Start a local HTTP server
68
- yarn start
68
+ pnpm run start
69
69
 
70
70
  # Start with Node.js Inspector enabled
71
- yarn start:debug
71
+ pnpm run start:debug
72
72
  ```
73
73
 
74
74
  ### Deploy
@@ -2,16 +2,6 @@ version: '3.7'
2
2
 
3
3
  services:
4
4
  app:
5
- environment:
6
- # Enable Buildkite + GitHub integrations.
7
- - BUILDKITE
8
- - BUILDKITE_AGENT_ACCESS_TOKEN
9
- - BUILDKITE_BRANCH
10
- - BUILDKITE_BUILD_NUMBER
11
- - BUILDKITE_JOB_ID
12
- - BUILDKITE_PIPELINE_DEFAULT_BRANCH
13
- - BUILDKITE_STEP_ID
14
- - GITHUB_API_TOKEN
15
5
  image: ${BUILDKITE_PLUGIN_DOCKER_IMAGE:-''}
16
6
  init: true
17
7
  volumes:
@@ -18,6 +18,10 @@ env:
18
18
  {{$key}}: {{$value}}
19
19
  {{end}}
20
20
 
21
+ {{if .Values.cloudwatchDashboardDisabled}}
22
+ cloudwatchDashboardDisabled: {{values "cloudwatchDashboardDisabled"}}
23
+ {{end}}
24
+
21
25
  {{if .Values.datadogSecretId}}
22
26
  datadogSecretId: '{{values "datadogSecretId"}}'
23
27
  {{end}}
@@ -125,3 +129,4 @@ tags:
125
129
  {{end}}
126
130
 
127
131
  cpuArchitecture: <%- platformName %>
132
+ readOnlyRootFilesystem: true
@@ -6,8 +6,7 @@ image: '{{values "image"}}'
6
6
 
7
7
  buildArgs:
8
8
  # https://github.com/seek-oss/docker-ecr-cache-buildkite-plugin#building-on-the-resulting-image
9
- BASE_IMAGE: '{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_IMAGE}}'
10
- BASE_TAG: '{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_TAG}}'
9
+ BASE_IMAGE: '{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_IMAGE}}:{{.Env.BUILDKITE_PLUGIN_DOCKER_ECR_CACHE_EXPORT_TAG}}'
11
10
 
12
11
  # SEEK-Jobs/gantry#1661
13
12
  failOnScanFindings: false
@@ -6,7 +6,7 @@
6
6
  "format": "skuba format",
7
7
  "lint": "skuba lint",
8
8
  "start": "skuba start --port <%- port %>",
9
- "start:debug": "yarn start --inspect-brk",
9
+ "start:debug": "pnpm run --silent start --inspect-brk",
10
10
  "test": "skuba test",
11
11
  "test:ci": "skuba test --coverage",
12
12
  "test:watch": "skuba test --watch"
@@ -14,10 +14,12 @@
14
14
  "dependencies": {
15
15
  "@koa/router": "^12.0.0",
16
16
  "@opentelemetry/api": "^1.1.0",
17
- "@opentelemetry/exporter-trace-otlp-grpc": "^0.45.0",
18
- "@opentelemetry/instrumentation-aws-sdk": "^0.36.0",
19
- "@opentelemetry/instrumentation-http": "^0.45.0",
20
- "@opentelemetry/sdk-node": "^0.45.0",
17
+ "@opentelemetry/core": "^1.18.1",
18
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.48.0",
19
+ "@opentelemetry/instrumentation-aws-sdk": "^0.38.0",
20
+ "@opentelemetry/instrumentation-http": "^0.48.0",
21
+ "@opentelemetry/propagator-b3": "^1.18.1",
22
+ "@opentelemetry/sdk-node": "^0.48.0",
21
23
  "@seek/logger": "^6.0.0",
22
24
  "aws-sdk": "^2.1039.0",
23
25
  "hot-shots": "^10.0.0",
@@ -35,7 +37,7 @@
35
37
  "@types/koa-bodyparser": "^5.0.2",
36
38
  "@types/koa__router": "^12.0.0",
37
39
  "@types/node": "^20.9.0",
38
- "@types/supertest": "^2.0.11",
40
+ "@types/supertest": "^6.0.0",
39
41
  "chance": "^1.1.8",
40
42
  "pino-pretty": "^10.0.0",
41
43
  "skuba": "*",
@@ -45,5 +45,6 @@ module.exports = {
45
45
  validate: (value) => /^[a-z]{2}-[a-z]+-\d+$/.test(value),
46
46
  },
47
47
  ],
48
+ packageManager: 'pnpm',
48
49
  type: 'application',
49
50
  };
@@ -43,13 +43,15 @@ describe('validate', () => {
43
43
  .expect(422)
44
44
  .expect(({ body }) =>
45
45
  expect(body).toMatchInlineSnapshot(`
46
- {
47
- "invalidFields": {
48
- "/id": "Expected string, received null",
49
- },
50
- "message": "Input validation failed",
51
- }
52
- `),
46
+ {
47
+ "invalidFields": {
48
+ "~union0/id": "Expected string, received null",
49
+ "~union1/id": "Expected number, received null",
50
+ "~union1/summary": "Required",
51
+ },
52
+ "message": "Input validation failed",
53
+ }
54
+ `),
53
55
  );
54
56
  });
55
57
 
@@ -60,13 +62,44 @@ describe('validate', () => {
60
62
  .expect(422)
61
63
  .expect(({ body }) =>
62
64
  expect(body).toMatchInlineSnapshot(`
63
- {
64
- "invalidFields": {
65
- "/description": "Required",
66
- "/id": "Required",
67
- },
68
- "message": "Input validation failed",
69
- }
70
- `),
65
+ {
66
+ "invalidFields": {
67
+ "~union0/description~union0": "Required",
68
+ "~union0/description~union1": "Required",
69
+ "~union0/id": "Required",
70
+ "~union1/id": "Required",
71
+ "~union1/summary": "Required",
72
+ },
73
+ "message": "Input validation failed",
74
+ }
75
+ `),
71
76
  ));
77
+
78
+ it('blocks invalid nested union prop', () => {
79
+ const idDescription = {
80
+ ...mockIdDescription(),
81
+ description: {
82
+ fontSize: chance.integer(),
83
+ },
84
+ };
85
+
86
+ return agent
87
+ .post('/')
88
+ .send({ ...idDescription, id: null })
89
+ .expect(422)
90
+ .expect(({ body }) =>
91
+ expect(body).toMatchInlineSnapshot(`
92
+ {
93
+ "invalidFields": {
94
+ "~union0/description~union0": "Expected string, received object",
95
+ "~union0/description~union1/content": "Required",
96
+ "~union0/id": "Expected string, received null",
97
+ "~union1/id": "Expected number, received null",
98
+ "~union1/summary": "Required",
99
+ },
100
+ "message": "Input validation failed",
101
+ }
102
+ `),
103
+ );
104
+ });
72
105
  });
@@ -1,8 +1,10 @@
1
1
  import { ErrorMiddleware } from 'seek-koala';
2
- import type { z } from 'zod';
2
+ import { ZodIssueCode, type z } from 'zod';
3
3
 
4
4
  import type { Context } from 'src/types/koa';
5
5
 
6
+ type InvalidFields = Record<string, string>;
7
+
6
8
  /**
7
9
  * Converts a `ZodError` into an `invalidFields` object
8
10
  *
@@ -28,13 +30,33 @@ import type { Context } from 'src/types/koa';
28
30
  * ```json
29
31
  * { "/advertiserId": "advertiserId is required in the URL" }
30
32
  * ```
33
+ *
34
+ * For union errors, the path will be appended with `~union${unionIdx}` to indicate which union type failed.
35
+ * @see [union error example](./validation.test.ts)
31
36
  */
32
- const parseInvalidFieldsFromError = ({
33
- errors,
34
- }: z.ZodError): Record<string, string> =>
35
- Object.fromEntries(
36
- errors.map((err) => [`/${err.path.join('/')}`, err.message]),
37
- );
37
+ const parseInvalidFieldsFromError = (err: z.ZodError): InvalidFields =>
38
+ Object.fromEntries(parseTuples(err, {}));
39
+
40
+ const parseTuples = (
41
+ { errors }: z.ZodError,
42
+ unions: Record<number, number[]>,
43
+ ): Array<readonly [string, string]> =>
44
+ errors.flatMap((issue) => {
45
+ if (issue.code === ZodIssueCode.invalid_union) {
46
+ return issue.unionErrors.flatMap((err, idx) =>
47
+ parseTuples(err, {
48
+ ...unions,
49
+ [issue.path.length]: [...(unions[issue.path.length] ?? []), idx],
50
+ }),
51
+ );
52
+ }
53
+
54
+ const path = ['', ...issue.path]
55
+ .map((prop, idx) => [prop, ...(unions[idx] ?? [])].join('~union'))
56
+ .join('/');
57
+
58
+ return [[path, issue.message]] as const;
59
+ });
38
60
 
39
61
  export const validate = <
40
62
  Output,
@@ -51,11 +73,12 @@ export const validate = <
51
73
  }): Output => {
52
74
  const parseResult = schema.safeParse(input);
53
75
  if (parseResult.success === false) {
76
+ const invalidFields = parseInvalidFieldsFromError(parseResult.error);
54
77
  return ctx.throw(
55
78
  422,
56
79
  new ErrorMiddleware.JsonResponse('Input validation failed', {
57
80
  message: 'Input validation failed',
58
- invalidFields: parseInvalidFieldsFromError(parseResult.error),
81
+ invalidFields,
59
82
  }),
60
83
  );
61
84
  }
@@ -5,10 +5,22 @@ import type { JobInput } from 'src/types/jobs';
5
5
 
6
6
  export type IdDescription = z.infer<typeof IdDescriptionSchema>;
7
7
 
8
- export const IdDescriptionSchema = z.object({
9
- id: z.string(),
10
- description: z.string(),
11
- });
8
+ export const IdDescriptionSchema = z.union([
9
+ z.object({
10
+ id: z.string(),
11
+ description: z.union([
12
+ z.string(),
13
+ z.object({
14
+ fontSize: z.number(),
15
+ content: z.string(),
16
+ }),
17
+ ]),
18
+ }),
19
+ z.object({
20
+ id: z.number(),
21
+ summary: z.string(),
22
+ }),
23
+ ]);
12
24
 
13
25
  export const chance = new Chance();
14
26