skuba 13.0.0-subpath-imports-20250722044721 → 13.0.0-subpath-imports-20251003044159
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.
- package/README.md +1 -2
- package/config/tsconfig.json +2 -1
- package/jest/moduleNameMapper.js +3 -11
- package/lib/cli/build/assets.js +4 -8
- package/lib/cli/build/assets.js.map +2 -2
- package/lib/cli/build/esbuild.d.ts +2 -1
- package/lib/cli/build/esbuild.js +5 -4
- package/lib/cli/build/esbuild.js.map +2 -2
- package/lib/cli/build/index.js +9 -5
- package/lib/cli/build/index.js.map +2 -2
- package/lib/cli/build/tsc.d.ts +9 -2
- package/lib/cli/build/tsc.js +76 -40
- package/lib/cli/build/tsc.js.map +3 -3
- package/lib/cli/configure/analyseDependencies.d.ts +2 -2
- package/lib/cli/configure/analyseDependencies.js.map +1 -1
- package/lib/cli/configure/analysis/package.d.ts +1 -1
- package/lib/cli/configure/analysis/package.js +1 -1
- package/lib/cli/configure/analysis/package.js.map +2 -2
- package/lib/cli/configure/ensureTemplateCompletion.d.ts +2 -2
- package/lib/cli/configure/ensureTemplateCompletion.js.map +1 -1
- package/lib/cli/configure/getEntryPoint.d.ts +2 -2
- package/lib/cli/configure/getEntryPoint.js.map +1 -1
- package/lib/cli/configure/getProjectType.d.ts +2 -2
- package/lib/cli/configure/getProjectType.js.map +1 -1
- package/lib/cli/configure/processing/configFile.d.ts +1 -1
- package/lib/cli/configure/processing/configFile.js +48 -6
- package/lib/cli/configure/processing/configFile.js.map +2 -2
- package/lib/cli/configure/processing/package.js +8 -2
- package/lib/cli/configure/processing/package.js.map +2 -2
- package/lib/cli/init/getConfig.js +1 -1
- package/lib/cli/init/getConfig.js.map +2 -2
- package/lib/cli/init/git.js +1 -1
- package/lib/cli/init/git.js.map +2 -2
- package/lib/cli/init/index.js +4 -4
- package/lib/cli/init/index.js.map +3 -3
- package/lib/cli/lint/annotate/buildkite/eslint.js +1 -1
- package/lib/cli/lint/annotate/buildkite/eslint.js.map +2 -2
- package/lib/cli/lint/annotate/buildkite/index.js +1 -1
- package/lib/cli/lint/annotate/buildkite/index.js.map +2 -2
- package/lib/cli/lint/annotate/buildkite/internal.js +1 -1
- package/lib/cli/lint/annotate/buildkite/internal.js.map +2 -2
- package/lib/cli/lint/annotate/buildkite/prettier.js +1 -1
- package/lib/cli/lint/annotate/buildkite/prettier.js.map +2 -2
- package/lib/cli/lint/annotate/buildkite/tsc.js +1 -1
- package/lib/cli/lint/annotate/buildkite/tsc.js.map +2 -2
- package/lib/cli/lint/annotate/github/eslint.d.ts +1 -1
- package/lib/cli/lint/annotate/github/eslint.js.map +2 -2
- package/lib/cli/lint/annotate/github/index.js +3 -4
- package/lib/cli/lint/annotate/github/index.js.map +2 -2
- package/lib/cli/lint/annotate/github/internal.d.ts +1 -1
- package/lib/cli/lint/annotate/github/internal.js.map +2 -2
- package/lib/cli/lint/annotate/github/prettier.d.ts +1 -1
- package/lib/cli/lint/annotate/github/prettier.js.map +2 -2
- package/lib/cli/lint/annotate/github/tsc.d.ts +1 -1
- package/lib/cli/lint/annotate/github/tsc.js.map +2 -2
- package/lib/cli/lint/autofix.d.ts +1 -1
- package/lib/cli/lint/autofix.js +3 -3
- package/lib/cli/lint/autofix.js.map +2 -2
- package/lib/cli/lint/internal.js +1 -1
- package/lib/cli/lint/internal.js.map +2 -2
- package/lib/cli/lint/internalLints/patchRenovateConfig.js +3 -3
- package/lib/cli/lint/internalLints/patchRenovateConfig.js.map +2 -2
- package/lib/cli/lint/internalLints/refreshConfigFiles.js +5 -3
- package/lib/cli/lint/internalLints/refreshConfigFiles.js.map +2 -2
- package/lib/cli/lint/internalLints/upgrade/index.d.ts +2 -2
- package/lib/cli/lint/internalLints/upgrade/index.js.map +1 -1
- package/lib/{api/buildkite/md.js → cli/lint/internalLints/upgrade/patches/12.0.2/index.js} +13 -11
- package/lib/cli/lint/internalLints/upgrade/patches/12.0.2/index.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.0.2/unhandledRejections.d.ts +4 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.0.2/unhandledRejections.js +162 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.0.2/unhandledRejections.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.1.1/index.d.ts +2 -0
- package/lib/{api/net → cli/lint/internalLints/upgrade/patches/12.1.1}/index.js +12 -6
- package/lib/cli/lint/internalLints/upgrade/patches/12.1.1/index.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.1.1/patchJestSnapshots.d.ts +3 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.1.1/patchJestSnapshots.js +105 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.1.1/patchJestSnapshots.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/index.d.ts +2 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/index.js +40 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/index.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/patchApiTokenFromEnvironment.d.ts +3 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/patchApiTokenFromEnvironment.js +100 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/patchApiTokenFromEnvironment.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/patchDockerfileSyntaxDirective.d.ts +3 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/patchDockerfileSyntaxDirective.js +99 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.3.0/patchDockerfileSyntaxDirective.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.4.0/index.d.ts +2 -0
- package/lib/{api/buildkite → cli/lint/internalLints/upgrade/patches/12.4.0}/index.js +12 -9
- package/lib/cli/lint/internalLints/upgrade/patches/12.4.0/index.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.4.0/patchDockerfileCIVariable.d.ts +3 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.4.0/patchDockerfileCIVariable.js +101 -0
- package/lib/cli/lint/internalLints/upgrade/patches/12.4.0/patchDockerfileCIVariable.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/13.0.0/index.d.ts +2 -0
- package/lib/cli/lint/internalLints/upgrade/patches/{12.2.0 → 13.0.0}/index.js.map +1 -1
- package/lib/cli/lint/internalLints/upgrade/patches/13.0.0/rewriteSrcImports.d.ts +13 -0
- package/lib/cli/lint/internalLints/upgrade/patches/13.0.0/rewriteSrcImports.js +221 -0
- package/lib/cli/lint/internalLints/upgrade/patches/13.0.0/rewriteSrcImports.js.map +7 -0
- package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/upgradeESLint.js +1 -1
- package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/upgradeESLint.js.map +2 -2
- package/lib/cli/node/index.js +8 -2
- package/lib/cli/node/index.js.map +2 -2
- package/lib/cli/start/index.js +8 -2
- package/lib/cli/start/index.js.map +2 -2
- package/lib/cli/test/index.d.ts +1 -1
- package/lib/cli/test/index.js +18 -4
- package/lib/cli/test/index.js.map +2 -2
- package/lib/cli/test/reporters/github/annotations.d.ts +1 -1
- package/lib/cli/test/reporters/github/annotations.js.map +1 -1
- package/lib/cli/test/reporters/github/index.js +3 -4
- package/lib/cli/test/reporters/github/index.js.map +2 -2
- package/lib/index.d.ts +4 -4
- package/lib/index.js +4 -4
- package/lib/index.js.map +2 -2
- package/lib/utils/args.d.ts +2 -0
- package/lib/utils/args.js +5 -0
- package/lib/utils/args.js.map +2 -2
- package/lib/utils/dir.js +2 -2
- package/lib/utils/dir.js.map +3 -3
- package/lib/utils/manifest.d.ts +6 -2
- package/lib/utils/manifest.js +17 -8
- package/lib/utils/manifest.js.map +2 -2
- package/lib/utils/template.d.ts +1 -1
- package/package.json +21 -24
- package/template/base/_.prettierrc.js +1 -1
- package/template/base/_eslint.config.js +1 -1
- package/template/base/_pnpm-workspace.yaml +14 -3
- package/template/base/jest.config.ts +7 -12
- package/template/base/jest.setup.ts +1 -1
- package/template/express-rest-api/.buildkite/pipeline.yml +6 -0
- package/template/express-rest-api/.env +1 -1
- package/template/express-rest-api/.gantry/dev.yml +5 -1
- package/template/express-rest-api/.gantry/prod.yml +5 -1
- package/template/express-rest-api/Dockerfile +2 -2
- package/template/express-rest-api/Dockerfile.dev-deps +0 -2
- package/template/express-rest-api/README.md +5 -5
- package/template/express-rest-api/gantry.apply.yml +17 -1
- package/template/express-rest-api/package.json +11 -5
- package/template/express-rest-api/src/api/healthCheck.ts +2 -2
- package/template/express-rest-api/src/config.ts +7 -7
- package/template/express-rest-api/src/framework/logging.ts +11 -7
- package/template/express-rest-api/src/framework/metrics.ts +1 -1
- package/template/express-rest-api/src/listen.ts +6 -0
- package/template/express-rest-api/src/tracing.ts +56 -0
- package/template/greeter/Dockerfile +0 -2
- package/template/greeter/README.md +2 -2
- package/template/greeter/package.json +2 -2
- package/template/koa-rest-api/.buildkite/pipeline.yml +6 -0
- package/template/koa-rest-api/.env +1 -1
- package/template/koa-rest-api/.gantry/dev.yml +3 -3
- package/template/koa-rest-api/.gantry/prod.yml +3 -3
- package/template/koa-rest-api/Dockerfile +1 -1
- package/template/koa-rest-api/Dockerfile.dev-deps +0 -2
- package/template/koa-rest-api/README.md +6 -6
- package/template/koa-rest-api/gantry.apply.yml +15 -3
- package/template/koa-rest-api/package.json +13 -14
- package/template/koa-rest-api/src/api/healthCheck.ts +2 -2
- package/template/koa-rest-api/src/config.ts +7 -7
- package/template/koa-rest-api/src/framework/logging.ts +12 -8
- package/template/koa-rest-api/src/framework/metrics.ts +1 -1
- package/template/koa-rest-api/src/framework/server.test.ts +7 -8
- package/template/koa-rest-api/src/framework/server.ts +1 -4
- package/template/koa-rest-api/src/listen.ts +6 -0
- package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +6 -2
- package/template/lambda-sqs-worker-cdk/.env +1 -1
- package/template/lambda-sqs-worker-cdk/Dockerfile +0 -2
- package/template/lambda-sqs-worker-cdk/README.md +8 -8
- package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +54 -26
- package/template/lambda-sqs-worker-cdk/infra/appStack.test.ts +5 -22
- package/template/lambda-sqs-worker-cdk/infra/appStack.ts +16 -9
- package/template/lambda-sqs-worker-cdk/infra/config.ts +34 -20
- package/template/lambda-sqs-worker-cdk/infra/index.ts +1 -1
- package/template/lambda-sqs-worker-cdk/package.json +7 -9
- package/template/lambda-sqs-worker-cdk/src/app.test.ts +91 -51
- package/template/lambda-sqs-worker-cdk/src/app.ts +10 -9
- package/template/lambda-sqs-worker-cdk/src/config.ts +11 -16
- package/template/lambda-sqs-worker-cdk/src/framework/handler.test.ts +10 -5
- package/template/lambda-sqs-worker-cdk/src/framework/handler.ts +48 -24
- package/template/lambda-sqs-worker-cdk/src/framework/logging.ts +23 -11
- package/template/lambda-sqs-worker-cdk/src/framework/metrics.ts +1 -4
- package/template/lambda-sqs-worker-cdk/src/testing/handler.ts +4 -1
- package/template/oss-npm-package/.github/workflows/release.yml +7 -8
- package/template/oss-npm-package/.github/workflows/validate.yml +6 -6
- package/template/oss-npm-package/README.md +1 -1
- package/template/oss-npm-package/_package.json +0 -3
- package/template/oss-npm-package/skuba.template.js +1 -1
- package/lib/api/buildkite/annotate.d.ts +0 -28
- package/lib/api/buildkite/annotate.js +0 -62
- package/lib/api/buildkite/annotate.js.map +0 -7
- package/lib/api/buildkite/index.d.ts +0 -3
- package/lib/api/buildkite/index.js.map +0 -7
- package/lib/api/buildkite/md.d.ts +0 -6
- package/lib/api/buildkite/md.js.map +0 -7
- package/lib/api/git/commit.d.ts +0 -15
- package/lib/api/git/commit.js +0 -52
- package/lib/api/git/commit.js.map +0 -7
- package/lib/api/git/commitAllChanges.d.ts +0 -19
- package/lib/api/git/commitAllChanges.js +0 -83
- package/lib/api/git/commitAllChanges.js.map +0 -7
- package/lib/api/git/currentBranch.d.ts +0 -10
- package/lib/api/git/currentBranch.js +0 -59
- package/lib/api/git/currentBranch.js.map +0 -7
- package/lib/api/git/findRoot.d.ts +0 -9
- package/lib/api/git/findRoot.js +0 -52
- package/lib/api/git/findRoot.js.map +0 -7
- package/lib/api/git/getChangedFiles.d.ts +0 -20
- package/lib/api/git/getChangedFiles.js +0 -81
- package/lib/api/git/getChangedFiles.js.map +0 -7
- package/lib/api/git/index.d.ts +0 -12
- package/lib/api/git/index.js +0 -61
- package/lib/api/git/index.js.map +0 -7
- package/lib/api/git/isFileGitIgnored.d.ts +0 -4
- package/lib/api/git/isFileGitIgnored.js +0 -49
- package/lib/api/git/isFileGitIgnored.js.map +0 -7
- package/lib/api/git/log.d.ts +0 -19
- package/lib/api/git/log.js +0 -71
- package/lib/api/git/log.js.map +0 -7
- package/lib/api/git/pull.d.ts +0 -35
- package/lib/api/git/pull.js +0 -69
- package/lib/api/git/pull.js.map +0 -7
- package/lib/api/git/push.d.ts +0 -52
- package/lib/api/git/push.js +0 -70
- package/lib/api/git/push.js.map +0 -7
- package/lib/api/git/remote.d.ts +0 -20
- package/lib/api/git/remote.js +0 -73
- package/lib/api/git/remote.js.map +0 -7
- package/lib/api/git/reset.d.ts +0 -12
- package/lib/api/git/reset.js +0 -62
- package/lib/api/git/reset.js.map +0 -7
- package/lib/api/git/statusMatrix.d.ts +0 -7
- package/lib/api/git/statusMatrix.js +0 -47
- package/lib/api/git/statusMatrix.js.map +0 -7
- package/lib/api/github/checkRun.d.ts +0 -44
- package/lib/api/github/checkRun.js +0 -81
- package/lib/api/github/checkRun.js.map +0 -7
- package/lib/api/github/environment.d.ts +0 -17
- package/lib/api/github/environment.js +0 -48
- package/lib/api/github/environment.js.map +0 -7
- package/lib/api/github/index.d.ts +0 -7
- package/lib/api/github/index.js +0 -48
- package/lib/api/github/index.js.map +0 -7
- package/lib/api/github/issueComment.d.ts +0 -61
- package/lib/api/github/issueComment.js +0 -99
- package/lib/api/github/issueComment.js.map +0 -7
- package/lib/api/github/octokit.d.ts +0 -6
- package/lib/api/github/octokit.js +0 -42
- package/lib/api/github/octokit.js.map +0 -7
- package/lib/api/github/pullRequest.d.ts +0 -21
- package/lib/api/github/pullRequest.js +0 -69
- package/lib/api/github/pullRequest.js.map +0 -7
- package/lib/api/github/push.d.ts +0 -85
- package/lib/api/github/push.js +0 -166
- package/lib/api/github/push.js.map +0 -7
- package/lib/api/net/compose.d.ts +0 -4
- package/lib/api/net/compose.js +0 -51
- package/lib/api/net/compose.js.map +0 -7
- package/lib/api/net/index.d.ts +0 -1
- package/lib/api/net/index.js.map +0 -7
- package/lib/api/net/socket.d.ts +0 -5
- package/lib/api/net/socket.js +0 -68
- package/lib/api/net/socket.js.map +0 -7
- package/lib/api/net/waitFor.d.ts +0 -22
- package/lib/api/net/waitFor.js +0 -40
- package/lib/api/net/waitFor.js.map +0 -7
- package/lib/cli/lint/internalLints/upgrade/patches/12.2.0/rewriteSrcImports.d.ts +0 -6
- package/lib/cli/lint/internalLints/upgrade/patches/12.2.0/rewriteSrcImports.js +0 -104
- package/lib/cli/lint/internalLints/upgrade/patches/12.2.0/rewriteSrcImports.js.map +0 -7
- /package/lib/cli/lint/internalLints/upgrade/patches/{12.2.0 → 12.0.2}/index.d.ts +0 -0
- /package/lib/cli/lint/internalLints/upgrade/patches/{12.2.0 → 13.0.0}/index.js +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PublishCommand } from '@aws-sdk/client-sns';
|
|
2
|
+
import type { SQSBatchResponse } from 'aws-lambda';
|
|
2
3
|
|
|
3
4
|
import * as app from './app.js';
|
|
4
5
|
import { stdoutMock } from './framework/logging.js';
|
|
@@ -40,42 +41,100 @@ describe('handler', () => {
|
|
|
40
41
|
it('handles one record', async () => {
|
|
41
42
|
const event = createSqsEvent([JSON.stringify(jobPublished)]);
|
|
42
43
|
|
|
43
|
-
await expect(app.handler(event, ctx)).resolves.
|
|
44
|
+
await expect(app.handler(event, ctx)).resolves.toEqual<SQSBatchResponse>({
|
|
45
|
+
batchItemFailures: [],
|
|
46
|
+
});
|
|
44
47
|
|
|
45
48
|
expect(scoringService.request).toHaveBeenCalledTimes(1);
|
|
46
49
|
|
|
47
50
|
expect(stdoutMock.calls).toMatchObject([
|
|
51
|
+
{ count: 1, level: 20, msg: 'Received jobs' },
|
|
48
52
|
{
|
|
49
|
-
awsRequestId: '-',
|
|
50
|
-
count: 1,
|
|
51
53
|
level: 20,
|
|
52
|
-
msg: '
|
|
54
|
+
msg: 'Scored job',
|
|
55
|
+
snsMessageId: expect.any(String),
|
|
56
|
+
sqsMessageId: event.Records[0]!.messageId,
|
|
53
57
|
},
|
|
58
|
+
{ level: 20, msg: 'Function completed' },
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
expect(distribution.mock.calls).toEqual([
|
|
62
|
+
['job.received', 1],
|
|
63
|
+
['job.scored', 1],
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
expect(sns.client).toReceiveCommandTimes(PublishCommand, 1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('handles multiple records', async () => {
|
|
70
|
+
const event = createSqsEvent([
|
|
71
|
+
JSON.stringify(jobPublished),
|
|
72
|
+
JSON.stringify(jobPublished),
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
await expect(app.handler(event, ctx)).resolves.toEqual<SQSBatchResponse>({
|
|
76
|
+
batchItemFailures: [],
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
80
|
+
{ count: 2, level: 20, msg: 'Received jobs' },
|
|
54
81
|
{
|
|
55
|
-
awsRequestId: '-',
|
|
56
82
|
level: 20,
|
|
57
83
|
msg: 'Scored job',
|
|
58
84
|
snsMessageId: expect.any(String),
|
|
85
|
+
sqsMessageId: event.Records[0]!.messageId,
|
|
59
86
|
},
|
|
60
87
|
{
|
|
61
|
-
awsRequestId: '-',
|
|
62
88
|
level: 20,
|
|
63
|
-
msg: '
|
|
89
|
+
msg: 'Scored job',
|
|
90
|
+
snsMessageId: expect.any(String),
|
|
91
|
+
sqsMessageId: event.Records[1]!.messageId,
|
|
64
92
|
},
|
|
93
|
+
{ level: 20, msg: 'Function completed' },
|
|
65
94
|
]);
|
|
95
|
+
});
|
|
66
96
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
97
|
+
it('handles partial batch failure', async () => {
|
|
98
|
+
const event = createSqsEvent([
|
|
99
|
+
JSON.stringify('}'),
|
|
100
|
+
JSON.stringify(jobPublished),
|
|
70
101
|
]);
|
|
71
102
|
|
|
72
|
-
expect(
|
|
103
|
+
await expect(app.handler(event, ctx)).resolves.toEqual<SQSBatchResponse>({
|
|
104
|
+
batchItemFailures: [{ itemIdentifier: event.Records[0]!.messageId }],
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
expect(stdoutMock.calls).toMatchObject([
|
|
108
|
+
{ count: 2, level: 20, msg: 'Received jobs' },
|
|
109
|
+
{
|
|
110
|
+
error: {
|
|
111
|
+
name: 'ZodError',
|
|
112
|
+
type: 'ZodError',
|
|
113
|
+
},
|
|
114
|
+
level: 50,
|
|
115
|
+
msg: 'Processing record failed',
|
|
116
|
+
sqsMessageId: event.Records[0]!.messageId,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
level: 20,
|
|
120
|
+
msg: 'Scored job',
|
|
121
|
+
snsMessageId: expect.any(String),
|
|
122
|
+
sqsMessageId: event.Records[1]!.messageId,
|
|
123
|
+
},
|
|
124
|
+
{ level: 20, msg: 'Function completed' },
|
|
125
|
+
]);
|
|
73
126
|
});
|
|
74
127
|
|
|
75
|
-
it('
|
|
128
|
+
it('returns a batchItemFailure on invalid input', () => {
|
|
76
129
|
const event = createSqsEvent(['}']);
|
|
77
130
|
|
|
78
|
-
return expect(app.handler(event, ctx)).
|
|
131
|
+
return expect(app.handler(event, ctx)).resolves.toEqual<SQSBatchResponse>({
|
|
132
|
+
batchItemFailures: [
|
|
133
|
+
{
|
|
134
|
+
itemIdentifier: event.Records[0]!.messageId,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
});
|
|
79
138
|
});
|
|
80
139
|
|
|
81
140
|
it('bubbles up scoring service error', async () => {
|
|
@@ -85,24 +144,22 @@ describe('handler', () => {
|
|
|
85
144
|
|
|
86
145
|
const event = createSqsEvent([JSON.stringify(jobPublished)]);
|
|
87
146
|
|
|
88
|
-
await expect(app.handler(event, ctx)).
|
|
147
|
+
await expect(app.handler(event, ctx)).resolves.toEqual<SQSBatchResponse>({
|
|
148
|
+
batchItemFailures: [{ itemIdentifier: event.Records[0]!.messageId }],
|
|
149
|
+
});
|
|
89
150
|
|
|
90
151
|
expect(stdoutMock.calls).toMatchObject([
|
|
152
|
+
{ count: 1, level: 20, msg: 'Received jobs' },
|
|
91
153
|
{
|
|
92
|
-
|
|
93
|
-
count: 1,
|
|
94
|
-
level: 20,
|
|
95
|
-
msg: 'Received jobs',
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
awsRequestId: '-',
|
|
99
|
-
err: {
|
|
154
|
+
error: {
|
|
100
155
|
message: err.message,
|
|
101
156
|
type: 'Error',
|
|
102
157
|
},
|
|
103
158
|
level: 50,
|
|
104
|
-
msg: '
|
|
159
|
+
msg: 'Processing record failed',
|
|
160
|
+
sqsMessageId: event.Records[0]!.messageId,
|
|
105
161
|
},
|
|
162
|
+
{ level: 20, msg: 'Function completed' },
|
|
106
163
|
]);
|
|
107
164
|
});
|
|
108
165
|
|
|
@@ -113,23 +170,28 @@ describe('handler', () => {
|
|
|
113
170
|
|
|
114
171
|
const event = createSqsEvent([JSON.stringify(jobPublished)]);
|
|
115
172
|
|
|
116
|
-
await expect(app.handler(event, ctx)).
|
|
173
|
+
await expect(app.handler(event, ctx)).resolves.toEqual<SQSBatchResponse>({
|
|
174
|
+
batchItemFailures: [{ itemIdentifier: event.Records[0]!.messageId }],
|
|
175
|
+
});
|
|
117
176
|
|
|
118
177
|
expect(stdoutMock.calls).toMatchObject([
|
|
119
178
|
{
|
|
120
|
-
awsRequestId: '-',
|
|
121
179
|
count: 1,
|
|
122
180
|
level: 20,
|
|
123
181
|
msg: 'Received jobs',
|
|
124
182
|
},
|
|
125
183
|
{
|
|
126
|
-
|
|
127
|
-
err: {
|
|
184
|
+
error: {
|
|
128
185
|
message: err.message,
|
|
129
186
|
type: 'Error',
|
|
130
187
|
},
|
|
131
188
|
level: 50,
|
|
132
|
-
msg: '
|
|
189
|
+
msg: 'Processing record failed',
|
|
190
|
+
sqsMessageId: event.Records[0]!.messageId,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
level: 20,
|
|
194
|
+
msg: 'Function completed',
|
|
133
195
|
},
|
|
134
196
|
]);
|
|
135
197
|
});
|
|
@@ -141,8 +203,7 @@ describe('handler', () => {
|
|
|
141
203
|
|
|
142
204
|
expect(stdoutMock.calls).toMatchObject([
|
|
143
205
|
{
|
|
144
|
-
|
|
145
|
-
err: {
|
|
206
|
+
error: {
|
|
146
207
|
message: 'Received 0 records',
|
|
147
208
|
type: 'Error',
|
|
148
209
|
},
|
|
@@ -151,25 +212,4 @@ describe('handler', () => {
|
|
|
151
212
|
},
|
|
152
213
|
]);
|
|
153
214
|
});
|
|
154
|
-
|
|
155
|
-
it('throws on multiple records', async () => {
|
|
156
|
-
const event = createSqsEvent([
|
|
157
|
-
JSON.stringify(jobPublished),
|
|
158
|
-
JSON.stringify(jobPublished),
|
|
159
|
-
]);
|
|
160
|
-
|
|
161
|
-
await expect(app.handler(event, ctx)).rejects.toThrow('Function failed');
|
|
162
|
-
|
|
163
|
-
expect(stdoutMock.calls).toMatchObject([
|
|
164
|
-
{
|
|
165
|
-
awsRequestId: '-',
|
|
166
|
-
err: {
|
|
167
|
-
message: 'Received 2 records',
|
|
168
|
-
type: 'Error',
|
|
169
|
-
},
|
|
170
|
-
level: 50,
|
|
171
|
-
msg: 'Function failed',
|
|
172
|
-
},
|
|
173
|
-
]);
|
|
174
|
-
});
|
|
175
215
|
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { isLambdaHook } from '@seek/aws-codedeploy-hooks';
|
|
2
2
|
import type { SQSEvent } from 'aws-lambda';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
createBatchSQSHandler,
|
|
6
|
+
createHandler,
|
|
7
|
+
} from '#src/framework/handler.js';
|
|
5
8
|
import { logger } from '#src/framework/logging.js';
|
|
6
9
|
import { metricsClient } from '#src/framework/metrics.js';
|
|
7
10
|
import { validateJson } from '#src/framework/validation.js';
|
|
@@ -34,19 +37,17 @@ export const handler = createHandler<SQSEvent>(async (event, ctx) => {
|
|
|
34
37
|
|
|
35
38
|
const count = event.Records.length;
|
|
36
39
|
|
|
37
|
-
if (count
|
|
38
|
-
throw Error(
|
|
40
|
+
if (!count) {
|
|
41
|
+
throw Error('Received 0 records');
|
|
39
42
|
}
|
|
40
|
-
|
|
41
43
|
logger.debug({ count }, 'Received jobs');
|
|
42
44
|
|
|
43
|
-
metricsClient.distribution('job.received',
|
|
45
|
+
metricsClient.distribution('job.received', count);
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
throw new Error('Malformed SQS event with no records');
|
|
48
|
-
}
|
|
47
|
+
return recordHandler(event, ctx);
|
|
48
|
+
});
|
|
49
49
|
|
|
50
|
+
const recordHandler = createBatchSQSHandler(async (record, _ctx) => {
|
|
50
51
|
const { body } = record;
|
|
51
52
|
|
|
52
53
|
// TODO: this throws an error, which will cause the Lambda function to retry
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import { Env } from 'skuba-dive';
|
|
2
2
|
|
|
3
3
|
interface Config {
|
|
4
|
-
|
|
4
|
+
deployment: Deployment;
|
|
5
5
|
|
|
6
6
|
logLevel: string;
|
|
7
|
-
metrics: boolean;
|
|
8
7
|
name: string;
|
|
9
8
|
version: string;
|
|
10
9
|
|
|
11
10
|
destinationSnsTopicArn: string;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
type
|
|
13
|
+
type Deployment = (typeof deployments)[number];
|
|
15
14
|
|
|
16
|
-
const
|
|
15
|
+
const deployments = ['local', 'test', 'dev', 'prod'] as const;
|
|
17
16
|
|
|
18
|
-
const
|
|
17
|
+
const deployment = Env.oneOf(deployments)('DEPLOYMENT');
|
|
19
18
|
|
|
20
19
|
/* istanbul ignore next: config verification makes more sense in a smoke test */
|
|
21
|
-
const configs: Record<
|
|
20
|
+
const configs: Record<Deployment, () => Omit<Config, 'deployment'>> = {
|
|
22
21
|
local: () => ({
|
|
23
22
|
logLevel: 'debug',
|
|
24
|
-
metrics: false,
|
|
25
23
|
name: '<%- serviceName %>',
|
|
26
24
|
version: 'local',
|
|
27
25
|
|
|
@@ -30,7 +28,6 @@ const configs: Record<Environment, () => Omit<Config, 'environment'>> = {
|
|
|
30
28
|
|
|
31
29
|
test: () => ({
|
|
32
30
|
logLevel: Env.string('LOG_LEVEL', { default: 'debug' }),
|
|
33
|
-
metrics: false,
|
|
34
31
|
name: '<%- serviceName %>',
|
|
35
32
|
version: 'test',
|
|
36
33
|
|
|
@@ -39,24 +36,22 @@ const configs: Record<Environment, () => Omit<Config, 'environment'>> = {
|
|
|
39
36
|
|
|
40
37
|
dev: () => ({
|
|
41
38
|
logLevel: 'debug',
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
version: Env.string('VERSION'),
|
|
39
|
+
name: Env.string('DD_SERVICE'),
|
|
40
|
+
version: Env.string('DD_VERSION'),
|
|
45
41
|
|
|
46
42
|
destinationSnsTopicArn: Env.string('DESTINATION_SNS_TOPIC_ARN'),
|
|
47
43
|
}),
|
|
48
44
|
|
|
49
45
|
prod: () => ({
|
|
50
46
|
logLevel: 'info',
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
version: Env.string('VERSION'),
|
|
47
|
+
name: Env.string('DD_SERVICE'),
|
|
48
|
+
version: Env.string('DD_VERSION'),
|
|
54
49
|
|
|
55
50
|
destinationSnsTopicArn: Env.string('DESTINATION_SNS_TOPIC_ARN'),
|
|
56
51
|
}),
|
|
57
52
|
};
|
|
58
53
|
|
|
59
54
|
export const config: Config = {
|
|
60
|
-
...configs[
|
|
61
|
-
|
|
55
|
+
...configs[deployment](),
|
|
56
|
+
deployment,
|
|
62
57
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { SQSEvent } from 'aws-lambda';
|
|
2
|
+
|
|
1
3
|
import { createHandler } from './handler.js';
|
|
2
4
|
import { logger, stdoutMock } from './logging.js';
|
|
3
5
|
|
|
@@ -6,12 +8,14 @@ import { chance } from '#src/testing/types.js';
|
|
|
6
8
|
|
|
7
9
|
describe('createHandler', () => {
|
|
8
10
|
const ctx = createCtx();
|
|
9
|
-
const input =
|
|
11
|
+
const input: SQSEvent = {
|
|
12
|
+
Records: [],
|
|
13
|
+
};
|
|
10
14
|
|
|
11
15
|
afterEach(stdoutMock.clear);
|
|
12
16
|
|
|
13
17
|
it('handles happy path', async () => {
|
|
14
|
-
const output = chance.
|
|
18
|
+
const output = chance.sentence();
|
|
15
19
|
|
|
16
20
|
const handler = createHandler((event) => {
|
|
17
21
|
expect(event).toBe(input);
|
|
@@ -32,7 +36,8 @@ describe('createHandler', () => {
|
|
|
32
36
|
{
|
|
33
37
|
awsRequestId: '-',
|
|
34
38
|
level: 20,
|
|
35
|
-
|
|
39
|
+
output,
|
|
40
|
+
msg: 'Function completed',
|
|
36
41
|
},
|
|
37
42
|
]);
|
|
38
43
|
});
|
|
@@ -47,7 +52,7 @@ describe('createHandler', () => {
|
|
|
47
52
|
expect(stdoutMock.calls).toMatchObject([
|
|
48
53
|
{
|
|
49
54
|
awsRequestId: '-',
|
|
50
|
-
|
|
55
|
+
error: {
|
|
51
56
|
message: err.message,
|
|
52
57
|
type: 'Error',
|
|
53
58
|
},
|
|
@@ -69,7 +74,7 @@ describe('createHandler', () => {
|
|
|
69
74
|
expect(stdoutMock.calls).toMatchObject([
|
|
70
75
|
{
|
|
71
76
|
awsRequestId: '-',
|
|
72
|
-
|
|
77
|
+
error: {
|
|
73
78
|
message: err.message,
|
|
74
79
|
type: 'Error',
|
|
75
80
|
},
|
|
@@ -1,40 +1,64 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
Context as LambdaContext,
|
|
3
|
+
SQSBatchItemFailure,
|
|
4
|
+
SQSBatchResponse,
|
|
5
|
+
SQSEvent,
|
|
6
|
+
SQSRecord,
|
|
7
|
+
} from 'aws-lambda';
|
|
3
8
|
|
|
4
|
-
import {
|
|
5
|
-
|
|
9
|
+
import {
|
|
10
|
+
lambdaContext,
|
|
11
|
+
logger,
|
|
12
|
+
recordContext,
|
|
13
|
+
} from '#src/framework/logging.js';
|
|
6
14
|
|
|
7
15
|
type Handler<Event, Output> = (
|
|
8
16
|
event: Event,
|
|
9
17
|
ctx: LambdaContext,
|
|
10
18
|
) => Promise<Output>;
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
fn: Handler<Event, Output>,
|
|
19
|
-
): Handler<Event, Output> =>
|
|
20
|
-
// istanbul ignore next
|
|
21
|
-
config.metrics ? (datadog(fn) as Handler<Event, Output>) : fn;
|
|
22
|
-
|
|
23
|
-
export const createHandler = <Event, Output = unknown>(
|
|
24
|
-
fn: (event: Event, ctx: LambdaContext) => Promise<Output>,
|
|
25
|
-
) =>
|
|
26
|
-
withDatadog<Event>((event, ctx) =>
|
|
27
|
-
loggerContext.run({ awsRequestId: ctx.awsRequestId }, async () => {
|
|
20
|
+
export const createHandler =
|
|
21
|
+
<Event extends SQSEvent, Output = unknown>(
|
|
22
|
+
fn: (event: Event, ctx: LambdaContext) => Promise<Output>,
|
|
23
|
+
): Handler<Event, Output> =>
|
|
24
|
+
async (event, ctx) =>
|
|
25
|
+
lambdaContext.run({ awsRequestId: ctx.awsRequestId }, async () => {
|
|
28
26
|
try {
|
|
29
27
|
const output = await fn(event, ctx);
|
|
30
28
|
|
|
31
|
-
logger.debug('Function
|
|
29
|
+
logger.debug({ output }, 'Function completed');
|
|
32
30
|
|
|
33
31
|
return output;
|
|
34
32
|
} catch (err) {
|
|
35
|
-
logger.error(
|
|
33
|
+
logger.error(err, 'Function failed');
|
|
36
34
|
|
|
37
35
|
throw new Error('Function failed');
|
|
38
36
|
}
|
|
39
|
-
})
|
|
40
|
-
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const createBatchSQSHandler =
|
|
40
|
+
(
|
|
41
|
+
fn: (record: SQSRecord, ctx: LambdaContext) => Promise<unknown>,
|
|
42
|
+
): Handler<SQSEvent, SQSBatchResponse> =>
|
|
43
|
+
async (event, ctx) => {
|
|
44
|
+
const processRecord = (
|
|
45
|
+
record: SQSRecord,
|
|
46
|
+
): Promise<SQSBatchItemFailure | undefined> =>
|
|
47
|
+
recordContext.run({ sqsMessageId: record.messageId }, async () => {
|
|
48
|
+
try {
|
|
49
|
+
await fn(record, ctx);
|
|
50
|
+
return;
|
|
51
|
+
} catch (err) {
|
|
52
|
+
logger.error(err, 'Processing record failed');
|
|
53
|
+
return {
|
|
54
|
+
itemIdentifier: record.messageId,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const results = await Promise.all(event.Records.map(processRecord));
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
batchItemFailures: results.filter((item) => item !== undefined),
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { createDestination, createLogger } from '@seek/logger';
|
|
4
4
|
|
|
5
5
|
import { config } from '#src/config.js';
|
|
6
6
|
|
|
7
|
-
interface
|
|
7
|
+
interface LambdaContext {
|
|
8
8
|
awsRequestId: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface RecordContext {
|
|
12
|
+
sqsMessageId: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const lambdaContext = new AsyncLocalStorage<LambdaContext>();
|
|
16
|
+
export const recordContext = new AsyncLocalStorage<RecordContext>();
|
|
12
17
|
|
|
13
18
|
const { destination, stdoutMock } = createDestination({
|
|
14
|
-
mock: config.
|
|
19
|
+
mock: config.deployment === 'test' && {
|
|
15
20
|
redact: ['awsRequestId'],
|
|
16
21
|
},
|
|
17
22
|
});
|
|
@@ -20,19 +25,26 @@ export { stdoutMock };
|
|
|
20
25
|
|
|
21
26
|
export const logger = createLogger(
|
|
22
27
|
{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
eeeoh: {
|
|
29
|
+
/**
|
|
30
|
+
* TODO: choose an appropriate Datadog log tier.
|
|
31
|
+
*
|
|
32
|
+
* https://github.com/seek-oss/logger/blob/master/docs/eeeoh.md#datadog-log-tiers
|
|
33
|
+
*/
|
|
34
|
+
datadog: 'tin',
|
|
35
|
+
team: '<%- teamName %>',
|
|
36
|
+
use: 'environment',
|
|
26
37
|
},
|
|
27
38
|
|
|
28
39
|
level: config.logLevel,
|
|
29
40
|
|
|
30
|
-
mixin: () => ({
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
mixin: () => ({
|
|
42
|
+
...lambdaContext.getStore(),
|
|
43
|
+
...recordContext.getStore(),
|
|
44
|
+
}),
|
|
33
45
|
|
|
34
46
|
transport:
|
|
35
|
-
config.
|
|
47
|
+
config.deployment === 'local' ? { target: 'pino-pretty' } : undefined,
|
|
36
48
|
},
|
|
37
49
|
destination,
|
|
38
50
|
);
|
|
@@ -7,8 +7,5 @@ const prefix = `${config.name}.`;
|
|
|
7
7
|
export const metricsClient = {
|
|
8
8
|
distribution: (
|
|
9
9
|
...[name, ...rest]: Parameters<typeof sendDistributionMetric>
|
|
10
|
-
) =>
|
|
11
|
-
config.metrics
|
|
12
|
-
? sendDistributionMetric(`${prefix}${name}`, ...rest)
|
|
13
|
-
: undefined,
|
|
10
|
+
) => sendDistributionMetric(`${prefix}${name}`, ...rest),
|
|
14
11
|
};
|
|
@@ -3,7 +3,7 @@ name: Release
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
|
-
-
|
|
6
|
+
- main
|
|
7
7
|
- beta
|
|
8
8
|
|
|
9
9
|
permissions: {}
|
|
@@ -18,17 +18,17 @@ jobs:
|
|
|
18
18
|
timeout-minutes: 20
|
|
19
19
|
steps:
|
|
20
20
|
- name: Check out repo
|
|
21
|
-
uses: actions/checkout@
|
|
21
|
+
uses: actions/checkout@v5
|
|
22
22
|
with:
|
|
23
23
|
fetch-depth: 0
|
|
24
24
|
|
|
25
|
+
- name: Set up pnpm
|
|
26
|
+
uses: pnpm/action-setup@v4
|
|
27
|
+
|
|
25
28
|
- name: Set up Node.js
|
|
26
|
-
uses: actions/setup-node@
|
|
29
|
+
uses: actions/setup-node@v5
|
|
27
30
|
with:
|
|
28
|
-
node-version:
|
|
29
|
-
|
|
30
|
-
- name: Set up pnpm
|
|
31
|
-
run: corepack enable pnpm && corepack install
|
|
31
|
+
node-version-file: .nvmrc
|
|
32
32
|
|
|
33
33
|
- name: Install dependencies
|
|
34
34
|
run: pnpm install --frozen-lockfile
|
|
@@ -37,4 +37,3 @@ jobs:
|
|
|
37
37
|
run: pnpm release
|
|
38
38
|
env:
|
|
39
39
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
40
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -16,15 +16,15 @@ jobs:
|
|
|
16
16
|
timeout-minutes: 20
|
|
17
17
|
steps:
|
|
18
18
|
- name: Check out repo
|
|
19
|
-
uses: actions/checkout@
|
|
19
|
+
uses: actions/checkout@v5
|
|
20
|
+
|
|
21
|
+
- name: Set up pnpm
|
|
22
|
+
uses: pnpm/action-setup@v4
|
|
20
23
|
|
|
21
24
|
- name: Set up Node.js
|
|
22
|
-
uses: actions/setup-node@
|
|
25
|
+
uses: actions/setup-node@v5
|
|
23
26
|
with:
|
|
24
|
-
node-version:
|
|
25
|
-
|
|
26
|
-
- name: Set up pnpm
|
|
27
|
-
run: corepack enable pnpm && corepack install
|
|
27
|
+
node-version-file: .nvmrc
|
|
28
28
|
|
|
29
29
|
- name: Install dependencies
|
|
30
30
|
run: pnpm install --frozen-lockfile
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export type AnnotationStyle = 'success' | 'info' | 'warning' | 'error';
|
|
2
|
-
interface AnnotationOptions {
|
|
3
|
-
context?: string;
|
|
4
|
-
/**
|
|
5
|
-
* Scopes an annotation's context to the Buildkite step ID.
|
|
6
|
-
*
|
|
7
|
-
* This lets you emit distinct annotations per step, and only takes effect if
|
|
8
|
-
* the `BUILDKITE_STEP_ID` environment variable is present.
|
|
9
|
-
*/
|
|
10
|
-
scopeContextToStep?: boolean;
|
|
11
|
-
style?: AnnotationStyle;
|
|
12
|
-
}
|
|
13
|
-
export declare const MAX_SIZE: number;
|
|
14
|
-
export declare const TRUNCATION_WARNING = "... [Truncated due to size limit]";
|
|
15
|
-
/**
|
|
16
|
-
* Asynchronously uploads a Buildkite annotation.
|
|
17
|
-
*
|
|
18
|
-
* If the following environment variables are not present,
|
|
19
|
-
* the function will silently return without attempting to annotate:
|
|
20
|
-
*
|
|
21
|
-
* - `BUILDKITE`
|
|
22
|
-
* - `BUILDKITE_AGENT_ACCESS_TOKEN`
|
|
23
|
-
* - `BUILDKITE_JOB_ID`
|
|
24
|
-
*
|
|
25
|
-
* The `buildkite-agent` binary must also be on your `PATH`.
|
|
26
|
-
*/
|
|
27
|
-
export declare const annotate: (markdown: string, opts?: AnnotationOptions) => Promise<void>;
|
|
28
|
-
export {};
|