WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
30c1251
initial concept for split cdk build generator
johnduffell Jun 26, 2025
a8755a9
make split cdk build generator generate all templated files
johnduffell Jul 7, 2025
5928d9f
move alarms handler CDK to generated project and make GHA use that in…
johnduffell Jul 16, 2025
d7bb312
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Jul 16, 2025
2f66bc0
generate templated files in GHA also prevent handler package from fin…
johnduffell Jul 16, 2025
9a08655
generate package.json before running pnpm install
johnduffell Jul 16, 2025
877630b
don't generate unncessary package.json
johnduffell Jul 16, 2025
61a6c10
add missing jest setup file
johnduffell Jul 16, 2025
d681c73
keep track of the correct cdk dir more globally
johnduffell Jul 16, 2025
3589983
rewrite generator in typescript
johnduffell Jul 18, 2025
de5205c
rewrite generator in typescript
johnduffell Jul 18, 2025
3f48f10
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Aug 13, 2025
7446b83
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 10, 2025
34e71a8
make buildgen manage the build files in-place
johnduffell Sep 10, 2025
58b2ca1
extract SR cdk constructs to cd module
johnduffell Sep 11, 2025
69db350
fix up import paths
johnduffell Sep 11, 2025
ba3928e
change buildgen readme file to markdown
johnduffell Sep 11, 2025
47ebe7d
add lint/prettier to buildgen
johnduffell Sep 11, 2025
2ed2ba1
add lint/prettier to buildgen and fix test
johnduffell Sep 11, 2025
cfcff1b
rebrand to buildcheck
johnduffell Sep 11, 2025
d44757f
improve comments and docs
johnduffell Sep 11, 2025
e0f9be6
move buildcheck data up a level
johnduffell Sep 11, 2025
ddf189d
docs/naming updates, improve build definition
johnduffell Sep 11, 2025
b4f3806
remove duplicate node-version file
johnduffell Sep 11, 2025
c5a1af2
improvements from value team mob review
johnduffell Sep 17, 2025
90eeada
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 17, 2025
3621c94
additional fixes after merging branch 'main' into jd/split-cdk-build-…
johnduffell Sep 17, 2025
5cf57da
only run buildcheck on handlers that have been converted
johnduffell Sep 18, 2025
5650745
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 18, 2025
18379eb
only run buildcheck on handlers that have been converted
johnduffell Sep 18, 2025
5258e7e
correct cdk module name
johnduffell Sep 18, 2025
ce1887f
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 19, 2025
a34f509
move CDK of discount-api and alarms-handler CDK into the handler folder
johnduffell Sep 19, 2025
5d4d02b
Merge branch 'jd/split-cdk' into jd/split-cdk-build-generator
johnduffell Sep 22, 2025
7d5272c
remove accidental jest ignore line
johnduffell Sep 22, 2025
ba1efb0
Merge branch 'jd/split-cdk' into jd/split-cdk-build-generator
johnduffell Sep 22, 2025
e710778
remove accidental jest ignore line
johnduffell Sep 22, 2025
8536ac2
reduce duplication in tsconfig
johnduffell Sep 22, 2025
a6dd755
Merge branch 'main' into jd/split-cdk
johnduffell Sep 22, 2025
db6aca3
Merge branch 'jd/split-cdk' into jd/split-cdk-build-generator
johnduffell Sep 22, 2025
05b6809
reformat tsconfig
johnduffell Sep 22, 2025
13912c4
Merge branch 'refs/heads/jd/split-cdk' into jd/split-cdk-build-generator
johnduffell Sep 22, 2025
4be633a
remove duplication from tsconfig template
johnduffell Sep 22, 2025
48ed4c9
fix pnpm lock file
johnduffell Sep 22, 2025
b852f24
improved internal generator structure
johnduffell Sep 24, 2025
cf2f6ac
make pnpm catalog the primary dependency list
johnduffell Sep 24, 2025
36b6ecc
Merge branch 'refs/heads/main' into jd/split-cdk-build-generator
johnduffell Sep 24, 2025
3772f19
remove split cdk changes
johnduffell Sep 24, 2025
66f63f6
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 24, 2025
0228913
Merge branch 'jd/split-cdk-build-generator' into jd/split-cdk-build-g…
johnduffell Sep 24, 2025
09ba6f4
remove split cdk changes
johnduffell Sep 24, 2025
e1df36d
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 24, 2025
8cb8b3a
Merge branch 'jd/split-cdk-build-generator' into jd/split-cdk-build-g…
johnduffell Sep 24, 2025
692c394
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 24, 2025
d29b996
Merge branch 'jd/split-cdk-build-generator' into jd/split-cdk-build-g…
johnduffell Sep 24, 2025
f05804f
run time check for AWS SDK v2 instead of compile time
johnduffell Sep 24, 2025
2c1ba95
tidy up generate functions
johnduffell Sep 26, 2025
a412285
Merge branch 'jd/split-cdk-build-generator' into jd/split-cdk-build-g…
johnduffell Sep 26, 2025
422c254
generic structure for templates, get template name from stacktrace
johnduffell Sep 26, 2025
a3352f9
Merge branch 'jd/split-cdk-build-generator' into jd/split-cdk-build-g…
johnduffell Sep 26, 2025
de89c78
Merge branch 'main' into jd/split-cdk-build-generator
johnduffell Sep 26, 2025
439eb83
check root level build files in common build
johnduffell Sep 26, 2025
e9641b1
generate repo path rather than using stack traces
johnduffell Sep 29, 2025
870016c
more logical naming of file/template objects
johnduffell Sep 29, 2025
045aad1
Merge branch 'jd/split-cdk-build-generator' into jd/split-cdk-build-g…
johnduffell Sep 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci-typescript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ jobs:
node-version-file: '.nvmrc'
cache: 'pnpm'
- run: pnpm install
- run: |
if [ -f "./handlers/${{ matrix.subproject }}/BUILDCHECK.md" ]; then
pnpm --filter "./buildcheck" type-check
pnpm --filter "./buildcheck" check-formatting
pnpm --filter "./buildcheck" lint
pnpm --filter "./buildcheck" snapshot:assert handlers/${{ matrix.subproject }}
fi
- run: pnpm --filter cdk package
- run: pnpm --filter ${{ matrix.subproject }} package

Expand Down
23 changes: 23 additions & 0 deletions BUILDCHECK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
MANAGED FILE: to push changes see buildcheck/README.md - template: buildcheck/data/snippets/BUILDCHECK.md.ts
# Buildcheck managed file list

The files listed below are managed by buildcheck and their content is checked by the build.

## HOWTO edit managed files
1. edit the build definition in buildcheck/data/
2. run `pnpm update-build` at the root

For further details, see [buildcheck/README.md](./buildcheck/README.md)

## Generated file list:
- [handlers/alarms-handler/jest.config.js](handlers/alarms-handler/jest.config.js)
- [handlers/alarms-handler/package.json](handlers/alarms-handler/package.json)
- [handlers/alarms-handler/riff-raff.yaml](handlers/alarms-handler/riff-raff.yaml)
- [handlers/alarms-handler/tsconfig.json](handlers/alarms-handler/tsconfig.json)
- [handlers/alarms-handler/BUILDCHECK.md](handlers/alarms-handler/BUILDCHECK.md)
- [handlers/discount-api/jest.config.js](handlers/discount-api/jest.config.js)
- [handlers/discount-api/package.json](handlers/discount-api/package.json)
- [handlers/discount-api/riff-raff.yaml](handlers/discount-api/riff-raff.yaml)
- [handlers/discount-api/tsconfig.json](handlers/discount-api/tsconfig.json)
- [handlers/discount-api/BUILDCHECK.md](handlers/discount-api/BUILDCHECK.md)
- [BUILDCHECK.md](BUILDCHECK.md)
4 changes: 4 additions & 0 deletions buildcheck/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
dist/
*.log
/src/dynamic/generated/
47 changes: 47 additions & 0 deletions buildcheck/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Buildcheck - build file checker

## What is buildcheck?
Buildcheck checks the content of the build files for all lambda modules and their associated cdk modules during CI.

The expected content is defined programmatically in typescript, similar to how CDK defines cloudformation.

If you edit the build definition, it's easy to refresh the build files using the update command provided.

## Quick start: How do I...?
### ...add a dependency
1. open [data/build.ts](data/build.ts)
1. add it to the dependencies section of your lambda definition
1. run `pnpm snapshot:update`
### ...bump a version
1. open [data/dependencies.ts](data/dependencies.ts)
1. edit the version number accordingly
1. `pnpm snapshot:update`
### ...quickly fix buildcheck in CI
1. run `pnpm snapshot:update` to refresh the full set of build files
2. commit and push

## Migrating an existing handler to use buildcheck
This requires the project to be restructured, and the definition added to buildcheck and then tested and refined.

1. Add your new handler to [data/build.ts](data/build.ts)
1. Run `pnpm snapshot:assert <handler-name>` to see any differences
1. Edit the buildcheck data (and existing files) to resolve any differences
1. retest until you are happy
1. Run `pnpm snapshot:assert` to ensure no other handler has been affected
1. Run `pnpm snapshot:update` to generate and overwrite the full set of build files (this should have no effect)
1. Push and test your changes in CODE.

## Pros and cons of buildcheck
The benefits and drawbacks of buildcheck are similar to CDK or SBT:
- prevent inconsistencies between lambdas/modules including dependency versions and pnpm scripts
- have a central list of recommended dependencies
- files can be generated where necessary, or buildcheck can be pulled in as a module to reuse definitions
- allows more fine grained modules to be manageable improving build times and organisation
- easier to add and review new lambda boilerplate as it's guaranteed to be standard
- all the usual DRY benefits

The disadvantages are mainly around tooling:
- automated PRs to bump dependencies will fail unless the dependencies.ts file is updated accordingly (although dependabot etc doesn't yet work with pnpm catalog either)
- harder to add dependencies as you need to add them to build.ts and then run snapshot:update.
- non standard, could surprise new people
- extra level of abstraction, could slow down regular developers
45 changes: 45 additions & 0 deletions buildcheck/data/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { pnpmCatalog } from '../src/dynamic/dependencies';

/*
This is the main build definition for all handlers.

Each record defines one handler and contains anything unique compared with the
assumed build structure.
*/

export interface HandlerDefinition {
name: string;
functionNames?: string[];
entryPoints?: string[];
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
}

const alarmsHandler: HandlerDefinition = {
name: 'alarms-handler',
functionNames: ['alarms-handler-', 'alarms-handler-scheduled-'],
entryPoints: ['src/index.ts', 'src/indexScheduled.ts'],
dependencies: {
...pnpmCatalog['@aws-sdk/client-cloudwatch'],
...pnpmCatalog['@aws-sdk/credential-providers'],
...pnpmCatalog.zod,
},
devDependencies: {
...pnpmCatalog['@types/aws-lambda'],
...pnpmCatalog.dayjs,
},
};

const discountApi: HandlerDefinition = {
name: 'discount-api',
dependencies: {
...pnpmCatalog.dayjs,
...pnpmCatalog['source-map-support'],
...pnpmCatalog.zod,
Copy link
Member Author

@johnduffell johnduffell Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just code, so it can be overridden as below, but the paved path is use the pnpm catalog and it gives you auto-complete to help out.

Suggested change
...pnpmCatalog.zod,
...{ 'zod': '1.2.3' },

},
devDependencies: {
...pnpmCatalog['@types/aws-lambda'],
},
};

export const build: HandlerDefinition[] = [alarmsHandler, discountApi];
14 changes: 14 additions & 0 deletions buildcheck/data/handlerTemplate/jest.config.js.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { notice } from '../snippets/notices';

export default `// ${notice(__filename)}
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
runner: 'groups',
moduleNameMapper: {
'@modules/(.*)/(.*)$': '<rootDir>/../../modules/$1/src/$2',
'@modules/(.*)$': '<rootDir>/../../modules/$1',
},
};
`;
28 changes: 28 additions & 0 deletions buildcheck/data/handlerTemplate/package.json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { HandlerDefinition } from '../build';
import { notice } from '../snippets/notices';

export default (pkg: HandlerDefinition) => {
const entryPoints = pkg.entryPoints
? pkg.entryPoints?.join(' ')
: 'src/index.ts';
return {
name: `${pkg.name}`,
scripts: {
test: 'jest --group=-integration',
'it-test': 'jest --group=integration',
'type-check': 'tsc --noEmit',
build:
'esbuild --bundle --platform=node --target=node18 --outdir=target/ ' +
entryPoints +
' --sourcemap',
lint: 'eslint src/**/*.ts test/**/*.ts',
package: `pnpm type-check && pnpm lint && pnpm check-formatting && pnpm test && pnpm build && cd target && zip -qr ${pkg.name}.zip ./*.js.map ./*.js`,
'check-formatting': 'prettier --check **.ts',
'fix-formatting': 'prettier --write **.ts',
},
NOTICE1: notice(__filename),
NOTICE2: 'all dependencies are defined in buildcheck/data/build.ts',
dependencies: pkg.dependencies,
devDependencies: pkg.devDependencies,
};
};
29 changes: 29 additions & 0 deletions buildcheck/data/handlerTemplate/riff-raff.yaml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { HandlerDefinition } from '../build';

export default (pkg: HandlerDefinition) => ({
stacks: ['support'],
regions: ['eu-west-1'],
allowedStages: ['CODE', 'PROD'],
deployments: {
[`${pkg.name}-cloudformation`]: {
type: 'cloud-formation',
app: pkg.name,
parameters: {
templateStagePaths: {
CODE: `${pkg.name}-CODE.template.json`,
PROD: `${pkg.name}-PROD.template.json`,
},
},
},
[pkg.name]: {
type: 'aws-lambda',
parameters: {
fileName: `${pkg.name}.zip`,
bucketSsmLookup: true,
prefixStack: false,
functionNames: pkg.functionNames ?? [pkg.name + '-'],
},
dependencies: [`${pkg.name}-cloudformation`],
},
},
});
3 changes: 3 additions & 0 deletions buildcheck/data/handlerTemplate/tsconfig.json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
extends: '../../tsconfig.json',
};
54 changes: 54 additions & 0 deletions buildcheck/data/snippets/BUILDCHECK.md.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { notice, relativePath } from './notices';
import path from 'path';
import { GeneratedFile } from '../../src/steps/generatedFile';

// the generated file is named after this file.
// if you rename it, clean the snapshot first, then generate afterwards
const basename = path.basename(__filename);
if (!basename.endsWith('.ts')) {
throw new Error(
`Expected warning file name to end with .ts, got: ${basename}`,
);
}
export const warningFileName = basename.slice(0, -3);

export function generateWarningFile(
generatedFiles: string[],
pathToRoot: string,
): GeneratedFile {
const buildGenHeader = `${notice(__filename)}
# Buildcheck managed file list

The files listed below are managed by buildcheck and their content is checked by the build.

## HOWTO edit managed files
1. edit the build definition in buildcheck/data/
2. run \`pnpm update-build\` at the root

For further details, see [buildcheck/README.md](${pathToRoot}/buildcheck/README.md)

## Generated file list:
`;

return {
relativePath: warningFileName,
content:
buildGenHeader +
[...generatedFiles, warningFileName]
.map((name) => '- [' + name + '](' + name + ')\n')
.join(''),
templatePath: relativePath(__filename),
};
}

export function parseGeneratedFilenames(fileLines: string[]): string[] {
// lines to look for are like this: "- [filename](filepath)"
return fileLines
.filter((line) => line.startsWith('- ['))
.map((line) => {
const getTheContentsOfRoundBrackets = /\(([^)]+)\)/;
const match = line.match(getTheContentsOfRoundBrackets);
return match ? match[1] : '';
})
.filter((filepath) => filepath !== '');
}
12 changes: 12 additions & 0 deletions buildcheck/data/snippets/notices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function relativePath(filename: string) {
// not watertight logic, but it isn't security critical
const moduleName = 'buildcheck';
const repoRootIndex = filename.indexOf('/' + moduleName + '/');
return repoRootIndex !== -1
? filename.substring(repoRootIndex + 1)
: filename;
}

export const notice = (filename: string) =>
'MANAGED FILE: to push changes see buildcheck/README.md - template: ' +
relativePath(filename);
6 changes: 6 additions & 0 deletions buildcheck/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
runner: 'groups',
};
29 changes: 29 additions & 0 deletions buildcheck/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "buildcheck",
"version": "1.0.0",
"private": true,
"description": "Build file generator for handlers",
"scripts": {
"update-build": "pnpm snapshot:update",
"snapshot:update": "pnpm generate && REPO_ROOT=\"$(pwd | sed 's|/buildcheck.*||')\" && ts-node src/cli.ts --generate \"$REPO_ROOT\"",
"snapshot:clean": "pnpm generate && REPO_ROOT=\"$(pwd | sed 's|/buildcheck.*||')\" && ts-node src/cli.ts --clean \"$REPO_ROOT\"",
"snapshot:assert": "pnpm generate && REPO_ROOT=\"$(pwd | sed 's|/buildcheck.*||')\" && bash -c 'jest --testNamePattern=\"$*\"' -- \"$@\"",
"clean": "rm -rf src/dynamic/generated dist",
"generate": "bash src/dynamic/generate-template-list.sh && bash src/dynamic/generate-deps-list.sh",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the extra script reads pnpm-workspace.yaml and makes a typescript version, to allow static type checking.

"test": "pnpm generate && jest",
"type-check": "pnpm generate && tsc --noEmit",
"lint": "pnpm generate && eslint src/**/*.ts test/**/*.ts",
"check-formatting": "pnpm generate && prettier --check **.ts",
"fix-formatting": "pnpm generate && prettier --write **.ts"
},
"dependencies": {
"js-yaml": "^4.1.0"
},
"devDependencies": {
"@jest/globals": "^30.0.4",
"@types/js-yaml": "^4.0.9",
"@types/node": "^22.15.14",
"ts-node": "^10.9.2",
"typescript": "^5.0.0"
}
}
31 changes: 31 additions & 0 deletions buildcheck/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { generate } from './steps/generate';
import { writeFiles, deleteRepoFiles, readLines } from './util/file-writer';
import { parseArguments } from './util/argsParser';
import {
parseGeneratedFilenames,
warningFileName,
} from '../data/snippets/BUILDCHECK.md';

// main entry point from pnpm
try {
const { mode, repoRoot } = parseArguments(process.argv);

const previouslyGeneratedFiles = parseGeneratedFilenames(
readLines(repoRoot, warningFileName),
);
console.log('previouslyGeneratedFiles to delete', previouslyGeneratedFiles);

switch (mode) {
case 'generate':
deleteRepoFiles(repoRoot, previouslyGeneratedFiles);
const files = generate();
writeFiles(repoRoot, files);
break;
case 'clean':
deleteRepoFiles(repoRoot, previouslyGeneratedFiles);
break;
}
} catch (error) {
console.error(error);
process.exit(1);
}
7 changes: 7 additions & 0 deletions buildcheck/src/dynamic/dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getPnpmCatalog } from '../util/dependencyMapper';
import { rawCatalogList } from './generated/generatedDepsList';

/**
* catalog is populated from the pnpm workspace catalog when you run `pnpm generate`
*/
export const pnpmCatalog = getPnpmCatalog(rawCatalogList);
20 changes: 20 additions & 0 deletions buildcheck/src/dynamic/extractCatalog.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/^[[:space:]]*catalog:/ {
found = 1
next
}
found {
# Always keep comment lines, regardless of indentation or blankness
if ($0 ~ /^[[:space:]]*#/) {
sub(/^[[:space:]]+/, "", $0)
print
next
}
# If line is not indented and not blank, exit
if ($0 !~ /^[[:space:]]+/ && length($0) > 0) {
exit
}
# Trim leading and trailing whitespace
sub(/^[[:space:]]+/, "", $0)
sub(/[[:space:]]+$/, "", $0)
print
}
Comment on lines +1 to +20
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this awk script extracts the catalog section of the yaml including comments and spacing

Loading