-
deps: Drop
strip-ansi
dependency in favour ofutil.stripVTControlCharacters
(#1713) -
lint, format, template: Use pinned
pnpm
version in Dockerfiles (#1714)This fixes an issue where
pnpm
commands in Dockerfiles incorrectly use the latest pnpm version instead of the pinned version.
-
template/lambda-sqs-worker-cdk: Align template with Serverless template (#1577)
This adds the same boilerplate code available in
lambda-sqs-worker
along with Datadog integration. -
deps: libnpmsearch ^8.0.0 (#1698)
-
lint, format: Put back logic which skips autofixing Renovate branches when there is no open pull request. (#1699)
Previously, this was put in place to prevent an issue where a Renovate branch can get stuck in the
Edited/Blocked
state without a pull request being raised. This was subsequently removed because Skuba's default autofix commits were ignored by skuba's recommended renovate configuration.However, this has resulted in some build-rebase-build-rebase-... loops, and so the Renovate config change has been reverted, and requires investigation before reinstating.
skuba 9 is a reasonably large release but it shouldn't be too much trouble to upgrade.
The main changes are:
- ESLint 9 and flat config migration (where
skuba format
should handle most of the work) - Swapping out
ts-node
fortsx
- Some fixes in Buildkite & Docker files
Read the full changelog:
-
deps: ESLint 9 +
typescript-eslint
8 (#1537)This major upgrade bundles the following changes:
-
Migration to flat config format
skuba format
will attempt to migrate your existing.eslintignore
and.eslintrc.js
files to a flateslint.config.js
file.See the migration guide for more information.
-
Some lint rules have been changed or renamed
You will likely need to manually review and adjust your code after running
skuba lint
. -
eslint-plugin-import
has been replaced witheslint-plugin-import-x
To migrate, replace references to
eslint-plugin-import
witheslint-plugin-import-x
, andimport/
rules withimport-x/
.
Wider changes may be necessary if your project has a custom ESLint configuration. Refer to the following resources to get started:
-
-
node, start: Replace
ts-node
withtsx
(#1623)skuba node
andskuba start
now usetsx
instead ofts-node
to execute TypeScript files.tsx
improves support for ESM features like dynamicimport()
s. However, if you use its REPL by runningskuba node
without any arguments, there are a couple regressions to note:- Static
import
declarations are no longer supported. Userequire
andawait import()
instead. - Pasting code into the editor may be more finicky by default. Consider using
.editor
mode.
skuba node <file>
andskuba start
should continue to work as expected, but we have marked this as a major upgrade as it is difficult to comprehensively test every scenario. We strongly recommend to manually verify usage ofskuba node
andskuba start
when you upgrade. - Static
-
format, lint: Point Docker base images to AWS ECR Public and remove constant
--platform
arguments (#1684)This updates references to
node:
orpython:
Docker images in your Dockerfiles anddocker-compose.yml
files to point to AWS ECR Public to avoid Docker Hub rate limiting. It also removes constant--platform
arguments from Dockerfiles.- FROM --platform=arm64 node:20-alpine AS dev-deps + FROM public.ecr.aws/docker/library/node:20-alpine AS dev-deps
Your Dockerfiles may not be set up to build multi-platform images, so keep in mind that building them locally on an Intel x86 laptop may not yield images that can execute on AWS Graviton instances.
-
format, lint: Remove obsolete
version
field fromdocker-compose.yml
files (#1638) -
format, lint, template: Mount Buildkite
.npmrc
in/tmp/
rather than<workdir>/tmp/
(#1693)This avoids accidental inclusion in Git commits or published artifacts, as per the original intent of this handling.
- secrets: id=npm,src=tmp/.npmrc + secrets: id=npm,src=/tmp/.npmrc - output-path: tmp/ + output-path: /tmp/
-
deps: TypeScript 5.6 (#1655)
This major release includes breaking changes. See the TypeScript 5.6 announcement for more information.
-
format, lint: Fix duplicated YAML merge keys in
.buildkite/
pipelines (#1537)- - <<: *deploy - <<: *docker + - <<: [*deploy, *docker] label: stuff
This change supports standardised YAML parsing across tools such as ESLint; it should not functionally alter the behaviour of your build pipeline.
The bundled patch is fairly conservative and will not attempt to migrate more complex scenarios, such as where there are other keys between the merge keys. Take care with preserving the order of merge keys when manually updating other occurrences.
- - <<: *deploy + - <<: [*deploy, *docker] label: stuff - <<: *docker
-
format, lint: Remove logic to skip autofixing Renovate branches when there is no open pull request (#1687)
Previously, this was put in place to prevent an issue where a Renovate branch could get stuck in an
Edited/Blocked
state without a pull request being raised.skuba's default autofix commits are now ignored in our recommended Renovate configuration.
-
template/koa-rest-api: Switch from
koa-bodyparser
to@koa/bodyparser
(#1605) -
template/koa-rest-api: Enable secure headers middleware by default (#1601)
See the Koala documentation for more information.
-
template/lambda-sqs-worker-cdk: Comply with AWS tagging guidance (#1643)
-
api: Truncate Buildkite annotations over 1 MiB to resolve
buildkite-agent
crash (#1645) -
deps: validate-npm-package-name ^6.0.0 (#1682)
-
deps: normalize-package-data ^7.0.0 (#1681)
-
deps: esbuild ~0.24.0 (#1671)
-
deps: concurrently ^9.0.0 (#1666)
-
template/lambda-sqs-worker-cdk: Replace custom hooks with
@seek/aws-codedeploy-infra
(#1644) -
template: Point Docker base images to AWS ECR Public and remove constant
--platform
arguments (#1684)
-
template: Remove JSON schema definitions from Buildkite pipeline files (#1624)
This reverts #1611 due to incompatibility with pipeline signing.
-
template: docker-compose v5.3.0 (#1620)
-
template/lambda-sqs-worker-cdk: Fix deploy:hotswap script (#1616)
-
deps: esbuild 0.23 (#1610)
- format, lint: Set
package-manager-strict-version=true
for pnpm projects (#1572)
-
configure: Fix
[object Object]
output appearing duringskuba configure
(#1597) -
template/koa-rest-api: Clean up
src/app.test.ts
(#1606) -
template: Add JSON schema definitions to Buildkite pipeline files (#1611)
-
deps: @octokit/rest ^21.0.0 (#1599)
-
lint: Skip generation of config files when present in
.gitignore
(#1554)skuba lint
andskuba format
now skip the generation of config files, like.dockerignore
and.npmrc
, if they are ignored by.gitignore
files. -
deps: esbuild 0.21 (#1569)
-
deps: TypeScript 5.5 (#1596)
This major release includes breaking changes. See the TypeScript 5.5 announcement for more information.
-
api: Add Git.isFileGitIgnored (#1554)
-
lint: Add coverage to .prettierignore (#1552)
-
configure: Accept template data from stdin to allow for integration testing (#1558)
-
lint: Swap out
detect-package-manager
for manual lockfile detection (#1552)detect-package-manager
has been removed, in lieu of usingfind-up
to detect the closestpnpm-lock.yaml
oryarn.lock
to infer the package manager. -
lint: Patch installing specific pnpm version via Corepack (#1534)
-
deps: prettier 3.3 (#1580)
-
template: Add extension recommendations to
.vscode/extensions.json
(#1556) -
Git: Explicitly declare return types to enable compatibility with the
Node16
module (#1589) -
template/oss-npm-package: Skip excessive action runs (#1586)
-
template/lambda-sqs-worker-cdk: Add worker config file (#1548)
-
lint: Exclude
.vscode/extensions.json
from being ignored by.gitignore
(#1556) -
template: Make all configuration values explicit (#1560)
Previously,
src/config.ts
included optional configuration values and inheritance between environments in the spirit of DRY. While the templated file was wired up in a "safe" way—the production environment never inherited from other environments and explicitly specified all its configuration values—its pattern was misappropriated elsewhere and led to local configuration values affecting production environments.Instead, we now list all configuration values explicitly against each environment.
-
template: Remove deprecated
docker-compose.yml
version (#1570)Docker has ignored this for a while, and now generates a warning on every build: https://github.com/compose-spec/compose-spec/blob/master/04-version-and-name.md
-
template/*-rest-api: Clean up templated environment variables (#1562)
-
AWS_NODEJS_CONNECTION_REUSE_ENABLED
is no longer required with AWS SDK V3. -
The
env
boilerplate in Gantry values files was largely unnecessary and confusing.Our templates prefer to declare configuration values directly in
src/config.ts
.
-
-
deps: eslint 8.56.0 (#1521)
This upgrade is required for eslint-config-seek 13.
-
template: Install specific pnpm version via Corepack (#1515)
Previously, our Dockerfiles ran
corepack enable pnpm
without installing a specific version. This does not guarantee installation of the pnpm version specified inpackage.json
, which could cause a subsequentpnpm install --offline
to run Corepack online or otherwise hang on stdin:FROM --platform=arm64 node:20-alpine RUN corepack enable pnpm
{ "packageManager": "[email protected]", "engines": { "node": ">=20" } }
Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-8.15.4.tgz. Do you want to continue? [Y/n]
To avoid this issue, modify (1) Buildkite pipelines to cache on the
packageManager
property inpackage.json
, and (2) Dockerfiles to mountpackage.json
and runcorepack install
:- seek-oss/docker-ecr-cache#v2.1.0: + seek-oss/docker-ecr-cache#v2.2.0: cache-on: - .npmrc + - package.json#.packageManager - pnpm-lock.yaml
FROM --platform=arm64 node:20-alpine - RUN corepack enable pnpm + RUN --mount=type=bind,source=package.json,target=package.json \ + corepack enable pnpm && corepack install
-
template/*-rest-api: Fix lint failure (#1514)
This resolves the following failure on a newly-initialised project due to a regression in the
@types/express
dependency chain:error TS2688: Cannot find type definition file for 'mime'. The file is in the program because: Entry point for implicit type library 'mime'
A temporary workaround is to install
mime
as a dev dependency. -
deps: @octokit/types ^13.0.0 (#1536)
-
template/lambda-sqs-worker-cdk: Align dead letter queue naming with Serverless template (#1542)
-
Jest.mergePreset: Fudge
Bundler
module resolution (#1513)This extends #1481 to work around a
ts-jest
issue where test cases fail to run. -
template/oss-npm-package: Set timeout to 20 minutes for GitHub Actions (#1501)
-
template/lambda-sqs-worker-cdk: Replace CDK context based config with TypeScript config (#1541)
This version of skuba looks more scary than it is. The major change is that our dependencies have bumped their minimum Node.js requirement from 18.12 to 18.18. Most SEEK projects do not pin minor Node.js versions and are unlikely to be affected by this change.
In the spirit of upgrades, we recently refreshed our ARM64 migration guide and also have one for pnpm. A previous release landed a skuba migrate
command to simplify upgrades to Node.js 20 (active LTS) before Node.js 18 reaches EOL in April 2025.
-
deps: eslint-config-seek 13 + eslint-config-skuba 4 + typescript-eslint ^7.2.0 (#1487)
These major upgrades bump our minimum requirement from Node.js 18.12 to 18.18.
See the typescript-eslint v7 announcement for more information, and consider upgrading your project to the active LTS release with
skuba migrate
before Node.js 18 reaches EOL in April 2025.
-
deps: semantic-release 22 (#1492)
-
deps: TypeScript 5.4 (#1491)
This major release includes breaking changes. See the TypeScript 5.4 announcement for more information.
-
template: Remove
BUILDPLATFORM
from Dockerfiles (#1350)Previously, the built-in templates made use of
BUILDPLATFORM
and a fallback value:FROM --platform=${BUILDPLATFORM:-arm64} gcr.io/distroless/nodejs20-debian11
- Choose the platform of the host machine running the Docker build. An AWS Graviton Buildkite agent or Apple Silicon laptop will build under
arm64
, while an Intel laptop will build underamd64
. - Fall back to
arm64
if the build platform is not available. This maintains compatibility with toolchains like Gantry that lack support for theBUILDPLATFORM
argument.
This approach allowed you to quickly build images and run containers in a local environment without emulation. For example, you could
docker build
anarm64
image on an Apple Silicon laptop for local troubleshooting, while your CI/CD solution employedamd64
hardware across its build and runtime environments. The catch is that your localarm64
image may exhibit different behaviour, and is unsuitable for use in youramd64
runtime environment without cross-compilation.The built-in templates now hardcode
--platform
as we have largely converged onarm64
across local, build and runtime environments:FROM --platform=arm64 gcr.io/distroless/nodejs20-debian11
This approach is more explicit and predictable, reducing surprises when working across different environments and toolchains. Building an image on a different platform will be slower and rely on emulation.
- Choose the platform of the host machine running the Docker build. An AWS Graviton Buildkite agent or Apple Silicon laptop will build under
-
Jest.mergePreset: Fudge
Node16
andNodeNext
module resolutions (#1481)This works around a
ts-jest
issue where test cases fail to run if yourmoduleResolution
is set to a modern mode:{ "compilerOptions": { "moduleResolution": "Node16 | NodeNext" } }
error TS5110: Option 'module' must be set to 'Node16' when option 'moduleResolution' is set to 'Node16'. error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
-
pkg: Exclude
jest/*.test.ts
files (#1481) -
template: Remove account-level tags from resources (#1494)
This partially reverts #1459 and #1461 to avoid unnecessary duplication of account-level tags in our templates.
-
template/lambda-sqs-worker: Comply with latest AWS tagging guidance (#1461)
-
GitHub.putIssueComment: Support
userId: 'seek-build-agency'
(#1474)The
userId
parameter is an optimisation to skip user lookup. A descriptive constant is now supported on SEEK build agents:await GitHub.putIssueComment({ body, - userId: 87109344, // https://api.github.com/users/buildagencygitapitoken[bot] + userId: 'seek-build-agency', });
-
deps: Remove
why-is-node-running
(#1476)why-is-node-running
was previously added to the skuba CLI to troubleshoot scenarios where commands were timing out in CI. This has now been removed to avoid disruption to commands such asjest --detectOpenHandles
. -
deps: Remove
fdir
(#1463)This dependency is no longer used internally.
-
template/*-rest-api: Comply with latest AWS tagging guidance (#1459)
This includes an upgrade to Gantry v3.
-
deps: @octokit/graphql ^8.0.0 (#1473)
-
deps: @octokit/graphql-schema ^15.3.0 (#1473)
-
cli: Add 30-minute timeout to skuba commands in CI to avoid potential hanging builds. (#1444)
If there are use cases this breaks, please file an issue. A
SKUBA_NO_TIMEOUT
environment variable is supported on all commands to use the old behaviour. Timeout duration can be adjusted with aSKUBA_TIMEOUT_MS
environment variable. -
migrate: Introduce
skuba migrate node20
to automatically upgrade a project's Node.js version (#1382)skuba migrate node20
will attempt to automatically upgrade projects to Node.js 20. It will look in the project root for Dockerfiles,.nvmrc
, and Serverless files, as well as CDK files ininfra/
and.buildkite/
files, and try to upgrade them to a Node.js 20 version.skuba might not be able to upgrade all projects, so please check your project for any files that skuba missed. It's possible that skuba will modify a file incorrectly, in which case please open an issue.
Node.js 20 comes with its own breaking changes, so please read the Node.js 20 release notes alongside the skuba release notes. In addition,
- For AWS Lambda runtime updates to
nodejs20.x
, consider reading the release announcement as there are some breaking changes with this upgrade. - You may need to upgrade your versions of CDK and Serverless as appropriate to support nodejs20.x.
- For AWS Lambda runtime updates to
-
lint: Remove
Dockerfile-incunabulum
rule (#1441)Previously,
skuba lint
would search for and delete a file namedDockerfile-incunabulum
to correct a historical issue that had it committed to source control. This rule has been removed as the file has been cleaned up from most SEEK repositories. -
template/lambda-sqs-worker-cdk: Update tests to use a stable identifier for the
AWS::Lambda::Version
logical IDs in snapshots. This avoid snapshot changes on unrelated source code changes. (#1450) -
deps: picomatch ^4.0.0 (#1442)
- lint: Fix issue where
skuba lint
would fail ingutenberg
projects due to the existence ofDockerfile-incunabulum
files (#1439)
This version of skuba should not require significant upgrade effort for most projects, but it does contain some notable changes:
-
Internal linting and patching have been overhauled to streamline code generation on version upgrades.
To make upgrades easy now and going forward, we recommend setting up GitHub autofixes.
-
New projects will now be initialised with pnpm, along with improved pnpm support.
A future release of skuba may transition existing projects to pnpm.
Continue reading for more details on these changes and other improvements in this release.
-
lint: Overhaul internal linting system (#1370)
Previously, internal lint rules would not fail a
skuba lint
check but would silently make changes to your working tree. These changes may have never been committed and may have caused subsequent noise when runningskuba format
orskuba lint
.Now, internal linting is now promoted to a top-level tool alongside ESLint, Prettier, and tsc. Rules will report whether changes need to be made, and changes will only be applied in
format
or autofix modes (in CI). As a consequence,skuba lint
may fail upon upgrading to this version if your project has internal lint violations that have been left unaddressed up to this point.You can configure
skuba lint
to automatically push autofixes; this eases adoption of linting rule changes and automatically resolves issues arising from a forgottenskuba format
. You'll need to configure your CI environment to support this feature. See our GitHub autofixes documentation to learn more. -
format: Switch Distroless image from
nodejs-debian11
tonodejs-debian12
(#1381) -
deps: Prettier 3.2 (#1384)
See the release notes for more information.
-
init: Initialise new projects with pnpm (#1289)
New projects based on built-in templates will now use pnpm as their package manager as per updated organisational guidance.
Custom templates will continue to default to Yarn 1.x until a future major version, though you can opt in to pnpm via
skuba.template.js
:module.exports = { + packageManager: 'pnpm', };
-
lint: Manage
.npmrc
for pnpm projects (#1413)skuba now manages a section of
.npmrc
when a project usespnpm
to enable dependency hoisting. It will continue to avoid committing autofixes to the file if it contains auth secrets. -
deps: TypeScript 5.3 (#1324)
This major release includes breaking changes. See the TypeScript 5.3 announcement for more information.
-
lint: Manage
.dockerignore
(#1433)skuba now manages a section of
.dockerignore
for you, ensuring that the file is up to date with the latest enhancements in skuba. -
init: Default to
arm64
platform andmain
branch (#1343) -
init: Run Prettier after templating (#1337)
-
init: Support
main
default branch (#1335) -
lint: Introduce skuba patches (#1274)
This feature adds patches which are run only once on the
lint
orformat
commands following a skuba update. If your build pipeline is utilising autofixes, these changes will be pushed up automatically.
-
lint: Disable
Promise<void>
return checks in tests (#1366)This works around an existing incompatibility between Koa and the built-in
http.RequestListener
type:const app = new Koa(); const agent = supertest.agent(app.callback()); // ~~~~~~~~~~~~~~ // Promise returned in function argument where a void return was expected. // @typescript-eslint/no-misused-promises
-
deps: picomatch ^3.0.0 (#1309)
-
Jest: Export
Config
type (#1360)This resolves a TypeScript error that could present itself when using
Jest.mergePreset
with thedeclaration
compiler option:TS4082: Default export of the module has or is using private name
ConfigGlobals
. -
template/lambda-sqs-worker: Remove
@aws-sdk/util-utf8-node
library (#1326) -
build, build-package, test: Remove empty export synthesis for Jest setup files (#1274)
isolatedModules
was enabled by default in v5.0.0. To ease this migration, the commands listed above were updated to dynamically synthesise an empty export forjest.setup.ts
andjest.setup.int.ts
files; this compatibility logic has now been removed.Up-to-date projects are unlikely to be affected, but you can easily add an empty export statement to placate the TypeScript compiler:
jest.setup.ts(1,1): error TS1208: 'jest.setup.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.
process.env.ENVIRONMENT = 'test'; + export {};
-
template/lambda-sqs-worker-cdk: Switch to
aws-cdk-lib/assertions
(#1372) -
template/*-rest-api: Set
readonlyRootFilesystem
as a security best practice (#1394) -
template: Use
propagate-environment
for Docker Compose Buildkite plugin (#1392)This simplifies the Docker Compose environment variable configuration required for Buildkite and GitHub integrations.
In your
docker-compose.yml
:services: app: - environment: - # Enable Buildkite + GitHub integrations. - - BUILDKITE - - BUILDKITE_AGENT_ACCESS_TOKEN - - BUILDKITE_BRANCH - - BUILDKITE_BUILD_NUMBER - - BUILDKITE_JOB_ID - - BUILDKITE_PIPELINE_DEFAULT_BRANCH - - BUILDKITE_STEP_ID - - GITHUB_API_TOKEN image: ${BUILDKITE_PLUGIN_DOCKER_IMAGE:-''} init: true volumes: - ./:/workdir # Mount agent for Buildkite annotations. - /usr/bin/buildkite-agent:/usr/bin/buildkite-agent # Mount cached dependencies. - /workdir/node_modules
In your
.buildkite/pipeline.yml
:steps: - commands: - pnpm lint - pnpm test env: # At SEEK, this instructs the build agent to populate the GITHUB_API_TOKEN environment variable for this step. GET_GITHUB_TOKEN: 'please' plugins: - *aws-sm - *private-npm - *docker-ecr-cache - docker-compose#v4.16.0: + environment: + - GITHUB_API_TOKEN + propagate-environment: true run: app
-
template/*-rest-api: Disable dev CloudWatch dashboards for cost savings (#1395)
-
template/lambda-sqs-worker-cdk: Add blue-green deployment, smoke test and version pruning functionality (#1327)
-
template/lambda-sqs-worker*: Set maximum concurrency (#1412)
This prevents messages from going directly to the DLQ when the function reaches its reserved concurrency limit.
-
template/koa-rest-api: Improve input validation error response for Zod unions (#1339)
-
template/lambda-sqs-worker-cdk: Introduce bundling with esbuild,
--hotswap
and--watch
(#1321)This template now uses the
aws_lambda_nodejs.NodejsFunction
construct which uses esbuild to bundle the Lambda function. This reduces cold start time and time to build on CI.The
--hotswap
and--watch
options allow you to rapidly deploy your code changes to AWS, enhancing the developer feedback loop. This change introducesdeploy:hotswap
anddeploy:watch
scripts to thepackage.json
manifest and aDeploy Dev (Hotswap)
step to the Buildkite pipeline. Read more about watch and hotswap on the AWS Developer Tools Blog.
-
deps: Prettier 3.1 (#1314)
See the release notes for more information.
-
init: Fix
skuba.template.js
validation (#1325)This resolves an "Invalid function return type" error on
skuba init
. -
template: Update to Node 20 (#1317)
Consider upgrading the Node.js version for your project across:
.nvmrc
package.json#/engines/node
serverless.yml
@types/node
package version- CI/CD configuration (
.buildkite/pipeline.yml
,Dockerfile
, etc.)
If you are updating your AWS Lambda runtime to
nodejs20.x
, consider reading the release announcement as there are some breaking changes with this upgrade.
-
Jest.mergePreset: Propagate root-level configuration options to
projects
(#1294)Jest.mergePreset
now propagates themoduleNameMapper
andtransform
options from root-level configuration to theprojects
array.If you were referencing the base config in the
projects
array:const baseConfig = Jest.mergePreset({ // ... }); export default { ...baseConfig, projects: [ { ...baseConfig, displayName: 'unit', setupFiles: ['<rootDir>/jest.setup.ts'], testPathIgnorePatterns: ['\\.int\\.test\\.ts'], }, { ...baseConfig, displayName: 'integration', setupFiles: ['<rootDir>/jest.setup.ts'], testMatch: ['**/*.int.test.ts'], }, ], };
You can replace it with the following:
export default Jest.mergePreset({ // ... projects: [ { displayName: 'unit', setupFiles: ['<rootDir>/jest.setup.ts'], testPathIgnorePatterns: ['\\.int\\.test\\.ts'], }, { displayName: 'integration', setupFiles: ['<rootDir>/jest.setup.ts'], testMatch: ['**/*.int.test.ts'], }, ], });
The
projects
option allows you to reuse a single Jest config file for different test types. View the Jest documentation for more information. -
Net.waitFor: Use Docker Compose V2 (#1281)
This function now executes
docker compose
under the hood asdocker-compose
stopped receiving updates in July 2023. See the Docker manual for more information. -
lint: Add
prettier-plugin-packagejson
(#1276)This Prettier plugin sorts and formats your
package.json
file.
-
Git: Handle non-root working directories in
commitAllChanges
(#1269) -
template/koa-rest-api: Fix
app.test.ts
assertions (#1282)Previously, custom
.expect((res) => {})
assertions were incorrectly defined to return false rather than throw an error. The template has been updated to avoid this syntax, but the most straightforward diff to demonstrate the fix is as follows:- await agent.get('/').expect(({ status }) => status !== 404); + await agent.get('/').expect(({ status }) => expect(status).not.toBe(404));
-
template: seek-oss/docker-ecr-cache 2.1 (#1266)
This update brings a new
skip-pull-from-cache
option which is useful onWarm
/Build Cache
steps.At SEEK, our build agents no longer persist their Docker build cache from previous steps. This option allows a preparatory step to proceed on a cache hit without pulling the image from ECR, which can save on average ~1 minute per build for a 2GB Docker image.
-
lint: Resolve infinite autofix loop (#1262)
-
GitHub: Add working directory parameter to
readFileChanges
(#1269)The input
ChangedFiles
need to be evaluated against a working directory. While this is technically a breaking change, we have not found any external usage of the function inSEEK-Jobs
.- GitHub.readFileChanges(changedFiles) + GitHub.readFileChanges(dir, changedFiles)
-
lint: Handle non-root working directories in autofix commits (#1269)
Previously,
skuba lint
could produce surprising autofix commits if it was invoked in a directory other than the Git root. Now, it correctly evaluates its working directory in relation to the Git root, and will only commit file changes within its working directory. -
cli: Migrate from Runtypes to Zod (#1288)
The skuba CLI now uses Zod internally. This should not result in noticeable differences for consumers.
-
template: Mount npm build secret to a separate directory (#1278)
Our templated Buildkite pipelines currently retrieve a temporary
.npmrc
. This file contains an npm read token that allows us to fetch private@seek
-scoped packages.New projects now write this file to
/tmp/
on the Buildkite agent and mount it as a secret to/root/
in Docker. This separation allows you to commit a non-sensitive.npmrc
to your GitHub repository while avoiding accidental exposure of the npm read token. This is especially important if you are migrating a project to pnpm, which houses some of its configuration options in.npmrc
.Existing projects are generally advised to wait until we've paved a cleaner migration path for pnpm.
-
deps: TypeScript 5.2 (#1247)
This major release includes breaking changes. See the TypeScript 5.2 announcement for more information.
-
deps: libnpmsearch 7 (#1255)
-
deps: Prettier 3.0.3 (#1247)
See the release notes for more information.
-
deps: sort-package-json 2.5.1 (#1257)
This should resolve the following TypeScript compiler error:
node_modules/@types/glob/index.d.ts(29,42): error TS2694: Namespace '"node_modules/minimatch/dist/cjs/index"' has no exported member 'IOptions'.
-
init: Resolve directory path when patching Renovate config (#1241)
This should fix the
Failed to patch Renovate config.
warning when creating a new repo.
-
format, lint: Skip autofixing on Renovate branches when there is no open pull request (#1226)
This prevents an issue where a Renovate branch can get stuck in the
Edited/Blocked
state without a pull request being raised. -
deps: eslint-config-skuba 3 (#1234)
This major upgrade brings in new rules from typescript-eslint v6.
Diff patch from eslint-config-skuba 2 and eslint-config-skuba 3
{ + '@typescript-eslint/array-type': '...', + '@typescript-eslint/ban-tslint-comment': '...', + '@typescript-eslint/class-literal-property-style': '...', + '@typescript-eslint/consistent-generic-constructors': '...', + '@typescript-eslint/consistent-indexed-object-style': '...', + '@typescript-eslint/consistent-type-assertions': '...', + 'dot-notation': '...', + '@typescript-eslint/dot-notation': '...', + '@typescript-eslint/no-base-to-string': '...', + '@typescript-eslint/no-confusing-non-null-assertion': '...', + '@typescript-eslint/no-duplicate-enum-values': '...', + '@typescript-eslint/no-duplicate-type-constituents': '...', + '@typescript-eslint/no-redundant-type-constituents': '...', + '@typescript-eslint/no-unsafe-declaration-merging': '...', + '@typescript-eslint/no-unsafe-enum-comparison': '...', + '@typescript-eslint/prefer-for-of': '...', + '@typescript-eslint/prefer-function-type': '...', + '@typescript-eslint/prefer-nullish-coalescing': '...', + '@typescript-eslint/prefer-optional-chain': '...', + '@typescript-eslint/prefer-string-starts-ends-with': '...', - 'no-extra-semi': '...', - '@typescript-eslint/no-extra-semi': '...', }
-
format, lint: Add
pnpm-lock.yaml
to.prettierignore
(#1225) -
deps: esbuild 0.19 (#1236)
-
format, lint: Switch distroless image from
nodejs
tonodejs-debian11
(#1224)skuba format
andskuba lint
will now automatically switch yourgcr.io/distroless/nodejs:18
image togcr.io/distroless/nodejs18-debian11
. This is now the recommended base image for Node.js.
- template/*-rest-api: Switch distroless image from
nodejs:18
tonodejs18-debian11
(#1224)
-
test: Fix Prettier snapshot formatting (#1220)
Jest is not yet compatible with Prettier 3, causing snapshot updates to fail with the following error:
TypeError: prettier.resolveConfig.sync is not a function at runPrettier (node_modules/jest-snapshot/build/InlineSnapshots.js:308:30)
Our Jest preset now implements custom formatting as a workaround until jestjs/jest#14305 is resolved.
If you do not use our preset, you can temporarily disable formatting in your
jest.config.ts
then manually runskuba format
after updating snapshots:export default { + prettierPath: null, }
-
deps: tsconfig-seek 2 (#1175)
This change sets the
noUncheckedIndexedAccess
compiler option totrue
by default.This will flag possible issues with indexed access of arrays and records.
Before:
const a: string[] = []; const b = a[0]; // ^? const b: string
After:
const a: string[] = []; const b = a[0]; // ^? const b: string | undefined
Unfortunately, this change is a double edged sword as your previous code which may look like this may now be invalid.
if (list.length === 3) { const b = list[1]; // ^? const b: string | undefined }
To address this you will need to also explicitly check the index you are accessing.
if (list.length === 3 && list[1]) { const b = list[1]; // ^? const b: string }
This may seem like overkill, however, when you consider that Javascript will also allow this it may make sense
const a: string[] = []; a[1000] = 'foo'; console.log(a.length); // 1001
You can override this setting in your project's
tsconfig.json
by setting it to false.{ "compilerOptions": { "noUncheckedIndexedAccess": false } }
-
deps: Require Node.js 18.12+ (#1206)
Node.js 16 will reach end of life by September 2023. We have aligned our version support with sku 12.
Consider upgrading the Node.js version for your project across:
.nvmrc
package.json#/engines/node
@types/node
package version- CI/CD configuration (
.buildkite/pipeline.yml
,Dockerfile
, etc.)
-
deps: esbuild 0.18 (#1190)
skuba build
will continue to infertarget
fromtsconfig.json
at this time. See the esbuild release notes for other details. -
format, lint: Have Prettier respect
.gitignore
(#1217)This aligns with the behaviour of the Prettier 3.0 CLI.
-
deps: TypeScript 5.1 (#1183)
This major release includes breaking changes. See the TypeScript 5.1 announcement for more information.
-
deps: Prettier 3.0 (#1202)
See the release notes for more information.
-
template: Require Node.js 18.12+ (#1206)
-
template/oss-npm-package: Set
publishConfig.provenance
totrue
(#1182)See https://github.blog/2023-04-19-introducing-npm-package-provenance/ for more information.
-
template/lambda-sqs-worker: Change some info logs to debug (#1178)
The "Function succeeded" log message was changed from
info
todebug
to reduce the amount of unnecessary logs in production. The message will still be logged in dev environments but at adebug
level. -
tsconfig: Turn off
noUnusedLocals
andnoUnusedParameters
(#1181)SEEK's ESLint config has a rule which works for both function and types. We do not need both tools to do the same thing and ESLint has better support for ignoring files if needed.
-
lint: Resolve Git root before attempting to autofix (#1215)
-
configure: Resolve Git root before attempting to patch Renovate config (#1215)
-
template/lambda-sqs-worker: Bump aws-sdk-client-mock to 3.0.0 (#1197)
AWS SDK v3.363.0 shipped with breaking type changes.
-
build, build-package: Add a skuba config key named
assets
to copy assets to the output directory. (#1163)In your
package.json
:{ "skuba": { + "assets": [ + "**/*.vocab/*translations.json" + ], "entryPoint": "src/index.ts", "type": "package", } }
This will instruct skuba to copy the files matching the list of globs to the output directory/ies, preserving the directory structure from the source:
- for
skuba build-package
it will copy them tolib-commonjs
andlib-es2015
- for
skuba build
it will copy them totsconfig.json#/compilerOptions.outDir
(lib
by default)
- for
-
template: Include manifest files in CODEOWNERS (#1162)
Our templates previously excluded
package.json
andyarn.lock
from CODEOWNERS. This was intended to support advanced workflows such as auto-merging PRs and augmenting GitHub push notifications with custom tooling. However, we are reverting this configuration as it is more common for SEEKers to prefer a simpler CODEOWNERS-based workflow.This will not affect existing projects. If you create a new project and wish to restore the previous behaviour, you can manually extend
.github/CODEOWNERS
:* @<%- ownerName %> + # Configured by Renovate + package.json + yarn.lock
-
deps: Bump @octokit dependencies (#1174)
This should resolve the following compiler error:
error TS2339: Property 'annotations' does not exist on type '{}'.
-
deps: ts-jest ^29.1.0 (#1166)
This resolves the following
skuba test
warning:Version 5.0.2 of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=4.3.0 <5.0.0-0). Please do not report issues in ts-jest if you are using unsupported versions.
-
template/*-rest-api: Remove Gantry
ignoreAlarms
override (#1160)This issue has been resolved in Gantry v2.2.0; see its release notes for more information.
deployment: - # SEEK-Jobs/gantry#488 - ignoreAlarms: true
-
deps: eslint-config-skuba 2 (#1155)
This major upgrade removes eslint-plugin-react due to configuration issues experienced on non-React projects.
Raise a GitHub issue or send us a Slack message if this negatively affects your project.
-
start: Add
http.Server
support (#1159)skuba start
can now be used to create a live-reloading server forhttp.Server
instances. See theskuba start
documentation for more information. -
deps: eslint-config-seek 11 (#1155)
This major upgrade enforces consistent type imports and exports.
- import { Context } from 'aws-lambda'; + import type { Context } from 'aws-lambda';
skuba format
will modify your imports and exports to be consistent with linting rules. These changes are automatically committed if you have GitHub autofixes enabled on your project.
- lint: Avoid patching Renovate config when it already extends a
SEEK-Jobs
orseekasia
preset (#1132)
-
lint: Avoid committing
.npmrc
changes (#1129)skuba lint
can automatically commit codegen changes if you have GitHub autofixes enabled on your project. Previously we made sure to exclude a new.npmrc
file from the commit, but we now exclude changes to an existing.npmrc
too.
-
deps: Require Node.js 16.11+ (#1124)
Node.js 14 will reach end of life by April 2023.
Consider upgrading the Node.js version for your project across:
.nvmrc
package.json#/engines/node
- CI/CD configuration (
.buildkite/pipeline.yml
,Dockerfile
, etc.)
-
format, lint: Prepend baseline SEEK
renovate-config
preset (#1117)skuba format
andskuba lint
will now automatically prepend an appropriate baseline preset if your project is configured with aSEEK-Jobs
orseekasia
remote:// SEEK-Jobs { - extends: ['seek'], + extends: ['local>seek-jobs/renovate-config', 'seek'], } // seekasia { - extends: ['seek'], + extends: ['local>seekasia/renovate-config', 'seek'], }
Renovate requires this new configuration to reliably access private SEEK packages. Adding the preset should fix recent issues where Renovate would open then autoclose pull requests, and report ⚠ Dependency Lookup Warnings ⚠.
See SEEK-Jobs/renovate-config and seekasia/renovate-config for more information.
-
format, lint, template/*-rest-api: Set
keepAliveTimeout
to 31 seconds to prevent HTTP 502s (#1111)The default Node.js server keep-alive timeout is set to 5 seconds. However, the Gantry default ALB idle timeout is 30 seconds. This would lead to the occasional issues where the sidecar would throw
proxyStatus=502
errors. AWS recommends setting an application timeout larger than the ALB idle timeout.skuba format
andskuba lint
will now automatically append a keep-alive timeout to a typicalsrc/listen.ts
:// With a listener callback const listener = app.listen(config.port, () => { const address = listener.address(); }) + + listener.keepAliveTimeout = 31000; // Without a listener callback - app.listen(config.port); + const listener = app.listen(config.port); + + listener.keepAliveTimeout = 31000;
A more detailed explanation can be found in the below links:
-
format, lint: Bundle
eslint-plugin-yml
(#1107)eslint-plugin-yml is now supported on
skuba format
andskuba lint
. While the default configuration should be unobtrusive, you can opt in to stricter rules in your.eslintrc.js
:module.exports = { extends: ['skuba'], + overrides: [ + { + files: ['my/strict/config.yaml'], + rules: { + 'yml/sort-keys': 'error', + }, + }, + ], };
YAML files with non-standard syntax may fail ESLint parsing with this change. Gantry resource files should be excluded by default due to their custom templating syntax, and you can list additional exclusions in your
.eslintignore
. -
start: Add Fastify support (#1101)
skuba start
can now be used to create a live-reloading server for Fastify based projects. See theskuba start
documentation for more information. -
format, lint: Configure ESLint for
{cjs,cts,mjs,mts}
files (#1126) -
lint: Commit codegen updates (#1078)
skuba lint
can locally codegen updates to ignore files, module exports and Renovate configuration. These changes are now automatically committed if you have GitHub autofixes enabled on your project. -
deps: TypeScript 5.0 (#1118)
This major release includes breaking changes. See the TypeScript 5.0 announcement for more information.
-
init: Include baseline SEEK
renovate-config
preset (#1117) -
template/*-package: Require Node.js 16.11+ (#1124)
-
lint: Delete
Dockerfile-incunabulum
(#1078)skuba lint
may have accidentally committed this internal file to source control in prior versions. It is now automatically removed if you have GitHub autofixes enabled on your project.
-
lint: Exclude internal files from autofix commits (#1074)
skuba lint
now avoids committing the following internal files in a GitHub autofix:.npmrc
Dockerfile-incunabulum
-
deps: Prettier 2.8 (#1056)
See the release notes for more information.
-
deps: TypeScript 4.9 (#1046)
This major release includes breaking changes. See the TypeScript 4.9 announcement for more information.
-
template/lambda-sqs-worker: Declare
dd-trace
dependency (#1051)This resolves a
Runtime.ImportModuleError
that occurs if this transitive dependency is not installed:Runtime.ImportModuleError Error: Cannot find module 'dd-trace'
Alternatively, you can configure the Datadog Serverless plugin to bundle these dependencies via Lambda layers:
serverless.yml custom: datadog: - addLayers: false + addLayers: true
package.json { "dependencies": { - "datadog-lambda-js: "x.y.z", - "dd-trace: "x.y.z" }, "devDependencies": { + "datadog-lambda-js: "x.y.z", + "dd-trace: "x.y.z" } }
-
template/lambda-sqs-worker*: Bump Node.js version to 18 (#1049)
This release contains some breaking changes to the Lambda runtime such as the removal of AWS SDK V2 in favour of AWS SDK V3. See the AWS Lambda Node.js 18.x runtime announcement for more information.
-
template: Prompt for target platform (
amd64
orarm64
) (#1041) -
template/lambda-sqs-worker*: Use single hyphen in
renovate-
branch name prefix (#1050) -
deps: esbuild ~0.16.0 (#1062)
-
template/*-rest-api: Replace
'{{.Environment}}'
with a customenvironment
Gantry value. (#1065) -
lint: Require package.json to be sorted (#1048)
-
jest: Fix
isolatedModules
transform config (#1036) -
deps: eslint-config-skuba 1.2.0 (#1035)
This introduces an autofix for the TS1205 compiler error.
-
test: Remove default
src
module alias (#987)Our Jest preset automatically registers your
tsconfig.json
paths as module aliases, but would previously fall back to thesrc
alias if the option was omitted or failed to load. This default has now been removed.This is not expected to affect most projects. If yours makes use of the
src
alias and its tests are now failing on imports like the following:import { app } from 'src/app.ts';
Ensure that you declare this path in a
tsconfig.json
located in your project root:{ "compilerOptions": { + "paths": { + "src": ["src"] + } }, "extends": "skuba/config/tsconfig.json" }
-
build, test: Default to isolated modules (#987)
Our Jest and TypeScript presets now enable
isolatedModules
by default. Your Jest tests should start quicker, consume less resources, and no longer get stuck on pesky type errors. This should not compromise the type safety of your project asskuba lint
is intended to type check all production and testing code.If your project contains files without imports and exports like
jest.setup.ts
, you can add an empty export statement to them to placate the TypeScript compiler:jest.setup.ts(1,1): error TS1208: 'jest.setup.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.
process.env.ENVIRONMENT = 'test'; + export {};
If you previously enabled
isolatedModules
via theglobals
option in your Jest config, this is no longer functional due to syntax changes in ts-jest 29. You should be able to rely on our default going forward.skuba configure
can attempt to clean up the stale option, or you can remove it from yourjest.config.ts
manually:export default Jest.mergePreset({ - globals: { - 'ts-jest': { - // seek-oss/skuba#626 - isolatedModules: true, - }, - }, // Rest of config });
Isolated modules are incompatible with certain language features like
const enum
s. We recommend migrating away from such features as they are not supported by the broader ecosystem, including transpilers like Babel and esbuild. If your project is not yet ready for isolated modules, you can override the default in yourtsconfig.json
:{ "compilerOptions": { + "isolatedModules": false }, "extends": "skuba/config/tsconfig.json" }
-
format: Sort package.json (#1016)
-
build: Add experimental esbuild support (#681)
You can now build your project with esbuild. Note that this integration is still experimental, only includes the bare minimum to supplant a basic
tsc
-based build, and is not guaranteed to matchtsc
output. See the esbuild deep dive for more information.To opt in, modify your
package.json
:{ "skuba": { + "build": "esbuild", "template": null } }
-
configure: Fix
tsconfig.json#/compilerOptions/lib
clobbering (#1031) -
template: Bump greeter and API templates to Node.js 18 (#1011)
Node.js 18 is now in active LTS. The Lambda templates are stuck on Node.js 16 until the new AWS Lambda runtime is released.
-
template/lambda-sqs-worker-cdk: Replace Runtypes with Zod as default schema validator (#984)
-
template/lambda-sqs-worker: Replace Runtypes with Zod as default schema validator (#984)
-
configure: Fix package version lookups (#974)
This resolves the following error:
Error: Package "xyz" does not have a valid package.json manifest
-
configure: Fix
jest.setup.js
clobbering (#1031) -
template/lambda-sqs-worker*: Adjust Buildkite pipelines for new
renovate--
branch name prefix (#1022)See the pull request that aligns our Renovate presets for more information.
-
template: Support AMD64 Docker builds via
BUILDPLATFORM
(#1021)See the Docker documentation for more information. Note that this does not allow you to build on AMD64 hardware then deploy to ARM64 hardware and vice versa. It is provided for convenience if you need to revert to an AMD64 workflow and/or build and run an image on local AMD64 hardware.
-
template/koa-rest-api: Replace Runtypes with Zod as default schema validator (#984)
-
template/lambda-sqs-worker: Switch to modern Datadog integration (#965)
Datadog's CloudWatch integration and the associated
createCloudWatchClient
function fromseek-datadog-custom-metrics
have been deprecated. We recommend Datadog's Serverless Framework Plugin along with their first-party datadog-lambda-js and dd-trace npm packages. -
deps: Drop
package-json
(#962)This circumvents the following TypeScript compilation error on a clean install:
Error: node_modules/@types/cacheable-request/index.d.ts(0,0): error TS2709: Cannot use namespace 'ResponseLike' as a type.
If you run into this issue elsewhere in your project, you can temporarily work around it with a resolution in your
package.json
:{ "resolutions": { "@types/responselike": "1.0.0" } }
-
template/koa-rest-api: Drop
uuid
(#964)V4 UUIDs can be generated using the built-in
crypto.randomUUID()
function starting from Node.js 14.17. This is analogous to theCrypto.randomUUID()
Web API.- import { v4 as randomUUID } from 'uuid'; + import { randomUUID } from 'crypto';
-
deps: Jest 29 (#953)
This major release includes breaking changes. See the announcement post for more information.
The
collectCoverageOnlyFrom
configuration option has been removed, and the default snapshot format has been simplified:- Expected: \\"a\\" + Expected: "a" - Object { - Array [] - } + { + [] + }
-
deps: eslint-plugin-jest 27 (#959)
This major release includes breaking changes. See the release note for more information.
The
jest/no-alias-methods
rule is now enforced and autofixed to discourage usage of alias methods that will be removed in Jest 30.- .toBeCalled() + .toHaveBeenCalled()
-
configure, init: Format
package.json
with sort-package-json (#951) -
deps: TypeScript 4.8 (#954)
This major release includes breaking changes. See the TypeScript 4.8 announcement for more information.
-
configure, template: Ignore linting on
.cdk.staging
directory (#957) -
configure, template: Ignore linting on
cdk.out
directory (#940) -
template/*-npm-package: Use SSH scheme in repository URL (#955)
We have changed the templated format of the
package.json#repository/url
field. This may resolveskuba release
errors that reference Git password authentication is shutting down on the GitHub Blog.- git+https://github.com/org/repo.git + git+ssh://[email protected]/org/repo.git
-
configure, template: Allow
.idea
and.vscode
ignore overrides (#956)You can now append lines like
!.vscode/launch.json
to your ignore files to allow specific editor files to be committed, formatted and/or linted.
-
deps: jest-watch-typeahead ^2.0.0 (#925)
-
template/*-rest-api: seek-jobs/gantry v2.0.0 (#935)
-
template/lambda-sqs-worker: Remove tty disable from pipeline (#918)
-
test: Prefer verbose failure message in execution error annotations (#910)
-
template/lambda-sqs-worker: Remove unnecessary IAM permission (#908)
-
template: Fix README link to ARM64 guide (#913)
-
template/*-rest-api: Fix Gantry documentation links (#931)
-
test: Add
jest-watch-typeahead
plugin (#893)This enables typeahead suggestions when filtering by file or test name in watch mode.
-
Git: Add fastForwardBranch function (#882)
-
deps: TypeScript 4.7 (#877)
This major release includes breaking changes. See the TypeScript 4.7 announcement for more information.
While ECMAScript Module support for Node.js is now stable in TypeScript, other aspects of our toolchain have not caught up yet; notably, Node.js still lacks stable APIs for Jest to implement its usual suite of mocking capabilities. We are holding off on recommending existing repositories to make the switch and on providing reference implementations via our templates. As it stands, migrating from CJS to ESM is still an arduous exercise in rewriting import statements and restructuring mocks and test suites at the bare minimum.
-
GitHub: Add functions to create and upload verified commits using the GitHub GraphQL API (#882)
See our GitHub API documentation for more information.
-
deps: Prettier 2.7 (#899)
See the release notes for more information.
-
test: Improve file detection for GitHub annotations (#885)
-
deps: package-json ^7.0.0 (#903)
Resolves SNYK-JS-GOT-2932019.
-
template/*-rest-api: seek-jobs/gantry v1.8.1 (#887)
-
template/*: Remove
.me
files (#902)SEEK is moving away from Codex to off-the-shelf software powered by Backstage
catalog-info.yaml
files.At the moment we're only asking teams to document their systems, which typically span across multiple repositories. We may add
catalog-info.yaml
files back to the templates if there's a need for teams to document their components at a repository level. -
lint: Use GitHub GraphQL API to upload verified autofix commits (#882)
-
template: Use ARM64 architecture (#873)
We now recommend building and running projects on ARM64 hardware for greater cost efficiency. This requires a Graviton-based Buildkite cluster; see our ARM64 guide for more information.
-
template/lambda-sqs-worker: Avoid mutation of logger context (#879)
We now perform a shallow copy when retrieving the logger context from
AsyncLocalStorage
.- mixin: () => loggerContext.getStore() ?? {}, + mixin: () => ({ ...loggerContext.getStore() }),
-
template/private-npm-package: Use
npm2
build agent queue (#843) -
lint, test: Set timeout for Buildkite and GitHub integrations (#835)
Transient network failures can impact annotations and autofixes. We now specify a 30 second timeout for these integration features to prevent them from hanging and indefinitely preoccupying your build agents.
-
template: Time out Buildkite test steps after 10 minutes (#842)
Successful testing and linting should complete within this window. This timeout prevents commands from hanging and indefinitely preoccupying your Buildkite agents.
steps: - label: 🧪 Test & Lint + timeout_in_minutes: 10
-
cli: Make warning logs more verbose (#826)
-
template/lambda-sqs-worker: Change deployment method to
direct
(#868) -
template/koa-rest-api: Use AsyncLocalStorage to track logger context (#864)
We now employ RequestLogging.createContextStorage to thread logging context through the middleware stack of your Koa application. This enables use of a singleton
logger
instance instead of manually propagating Koa context and jugglingrootLogger
s andcontextLogger
s.Before:
import createLogger from '@seek/logger'; import Koa, { Context } from 'koa'; import { RequestLogging } from 'seek-koala'; const rootLogger = createLogger(); const contextLogger = (ctx: Context) => rootLogger.child(RequestLogging.contextFields(ctx)); const app = new Koa().use((ctx) => { rootLogger.info('Has no context'); contextLogger(ctx).info('Has context'); });
After:
import createLogger from '@seek/logger'; import Koa from 'koa'; import { RequestLogging } from 'seek-koala'; const { createContextMiddleware, mixin } = RequestLogging.createContextStorage(); const contextMiddleware = createContextMiddleware(); const logger = createLogger({ mixin }); const app = new Koa().use(contextMiddleware).use((ctx) => { logger.info('Has context'); });
-
template/lambda-sqs-worker: Use AsyncLocalStorage to track logger context (#871)
We now employ this Node.js API to thread logging context through the handler of your Lambda function. This enables use of a singleton
logger
instance instead of manually propagating Lambda context and jugglingrootLogger
s andcontextLogger
s, and is equivalent to #864.Before:
import createLogger from '@seek/logger'; import { Context } from 'aws-lambda'; const rootLogger = createLogger(); const contextLogger = ({ awsRequestId }: Context) => rootLogger.child({ awsRequestId }); const handler = async (_event: unknown, ctx: Context) => { rootLogger.info('Has no context'); contextLogger(ctx).info('Has context'); };
After:
import { AsyncLocalStorage } from 'async_hooks'; import createLogger from '@seek/logger'; import { Context } from 'aws-lambda'; const loggerContext = new AsyncLocalStorage<{ awsRequestId: string }>(); const logger = createLogger({ mixin: () => ({ ...loggerContext.getStore() }), }); const handler = (_event: unknown, { awsRequestId }: Context) => loggerContext.run({ awsRequestId }, async () => { logger.info('Has context'); });
-
template/lambda-sqs-worker*: Bump Node.js version to 16 (#862)
-
build-package, lint: Improve detection of SEEK Buildkite queues for serial execution (#829)
-
lint: Detect and autofix ESLint warnings (#844)
-
lint: Skip autofixing when ESLint reports no fixable issues (#844)
-
format, lint: Avoid unnecessary template literals (#849)
We now automatically convert unnecessary template literals into single-quoted strings for consistency.
-
deps: Jest 28 (#856)
This major release includes breaking changes. See the announcement post for more information.
-
deps: TypeScript 4.6 (#811)
This major release includes breaking changes. See the TypeScript 4.5 and TypeScript 4.6 announcements for more information.
-
lint: Autofix in CI (#800)
skuba lint
can now automatically push ESLint and Prettier autofixes. This eases adoption of linting rule changes and automatically resolves issues arising from a forgottenskuba format
.You'll need to configure your CI environment to support this feature. See our GitHub autofixes documentation to learn more.
-
deps: ESLint 8 + eslint-config-seek 9 (#806)
These major upgrades bundle new parser and plugin versions. See the ESLint 8 guide and eslint-config-seek 9 release for more details on the underlying changes.
We've introduced new linting rules like @typescript-eslint/no-unsafe-argument, and resolved the following installation warning:
babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.
If you wish to relax some of the new rules, extend your
.eslintrc.js
config:module.exports = { extends: ['skuba'], rules: { // Demote new TypeScript ESLint rule from 'error' to 'warn'. '@typescript-eslint/no-unsafe-argument': 'warn', }, };
-
template/lambda-sqs-worker-cdk: Fix progress configuration in
cdk.json
(#797) -
Jest.mergePreset: Allow additional props via type parameter (#806)
-
Git.currentBranch: Add helper function (#804)
-
test: Strip ANSI escape codes from error messages for GitHub annotations (#825)
-
Git.commitAllChanges: Skip commit and return
undefined
when there are no changes (#804) -
template/oss-npm-package: Lock down GitHub workflow permissions (#807)
This aligns with OpenSSF guidance.
-
template: Propagate Buildkite environment variables for lint autofixing (#800)
-
template: Exclude DOM type definitions by default (#822)
TypeScript will now raise compiler errors when DOM globals like
document
andwindow
are referenced in new projects. This catches unsafe usage of Web APIs that will throw exceptions in a Node.js context.If you are developing a new npm package for browser use or require specific Node.js-compatible Web APIs like the Encoding API, you can opt in to DOM type definitions in your
tsconfig.json
:{ "compilerOptions": { - "lib": ["ES2020"] + "lib": ["DOM", "ES2020"] } }
If you have an existing backend project, you can opt out of DOM type definitions in your
tsconfig.json
.For Node.js 14:
{ "compilerOptions": { + "lib": ["ES2020"], "target": "ES2020" } }
For Node.js 16:
{ "compilerOptions": { + "lib": ["ES2021"], "target": "ES2021" } }
-
Git.getOwnerAndRepo: Support reading from CI environment variables (#804)
-
Git.getHeadCommitMessage: Add helper function (#804)
-
template/*-rest-api: Avoid alternative syntax for ENV instructions (#823)
Omitting the
=
symbol in ENV instructions is discouraged and may be disallowed in future.- ENV NODE_ENV production + ENV NODE_ENV=production
-
template/oss-npm-package: Pin GitHub action versions (#805)
-
template/*-rest-api: seek-jobs/gantry v1.7.0 (#824)
-
template: Disable type checking in tests (#787)
Newly initialised projects will skip TypeScript type checking on
skuba test
as it's already covered byskuba lint
. You can now iterate on your tests without running into annoying compilation errors like TS6133 (unused declarations).This will be defaulted for existing projects in a future major version. You can opt in early by setting the
globals
configuration option in yourjest.config.ts
:export default Jest.mergePreset({ globals: { 'ts-jest': { // seek-oss/skuba#626 isolatedModules: true, }, }, // Rest of config });
-
template: Specify default Buildkite agent (#775)
-
format, lint: Suppress
eslint-plugin-react
warning (#786)Warning: React version was set to "detect" in eslint-plugin-react settings, but the "react" package is not installed. Assuming latest React version for linting.
-
deps: Prettier 2.6 (#792)
See the release notes for more information.
-
node: Throw unhandled rejections under Node.js 14 (#777)
When a rejected promise is left unhandled in Node.js 14, it simply logs a warning. This caused
skuba node
to effectively swallow such failures and report a process exit code of 0. We now override this behaviour with--unhandled-rejections=throw
to predictably fail with a non-zero exit code across supported Node.js versions. -
template/*-rest-api: seek-jobs/gantry v1.6.2 (#778)
-
node, start: Load environment variables from
.env
file (#774) -
deps: ts-node ^10.5.0 (#764)
This major release includes breaking changes. If your project uses a complex
ts-node
configuration either directly or on top ofskuba node
andskuba start
, see the changelog for more information.
-
template: skuba-dive ^2.0.0 (#766)
-
template/lambda-sqs-worker: Remove
variablesResolutionMode
(#768)This resolves the following deprecation warning in Serverless Framework v3:
Starting with v3.0, the "variablesResolutionMode" option is now useless. You can safely remove it from the configuration More info: https://serverless.com/framework/docs/deprecations/#VARIABLES_RESOLUTION_MODE
-
template/*-rest-api: Ignore deployment alarms and ECR scanning (#773)
-
configure: Fix
@seek/seek-module-toolkit
migration guide link (#762) -
template/lambda-sqs-worker-cdk: Add
NODE_ENV=production
to environment variables (#763) -
template/lambda-sqs-worker: Add
NODE_ENV=production
to environment variables (#763) -
deps: ts-node-dev ^2.0.0-0 (#764)
-
template/lambda-sqs-worker: Move environment variables to
provider.environment
to reduce repetition (#767)
-
deps: Require Node.js 14.18+ (#760)
Node.js 12 will reach end of life by April 2022. The
semantic-release
package and stable--enable-source-maps
flag necessitate this new minimum version.Consider upgrading the Node.js version for your project across:
.nvmrc
package.json#/engines/node
- CI/CD configuration (
.buildkite/pipeline.yml
,Dockerfile
, etc.)
-
deps: semantic-release ^19.0.0 (#757)
Resolves SNYK-JS-MARKED-2342073 and SNYK-JS-MARKED-2342082.
This may alleviate the following
skuba release
error:[semantic-release] › ✖ EGHNOPERMISSION The GitHub token doesn't allow to push on the repository owner/repo. The user associated with the GitHub token (https://github.com/semantic-release/github/blob/master/README.md#github-authentication) configured in the GH_TOKEN or GITHUB_TOKEN environment variable must allows to push to the repository owner/repo.
-
template: Use
--enable-source-maps
(#761)Stable source map support has landed in Node.js 14.18+ via the built-in
--enable-source-maps
option.We recommend migrating off of custom source map implementations in favour of this option. Upgrading to skuba-dive v2 will remove
source-map-support
from theskuba-dive/register
hook.For a containerised application, update your Dockerfile:
- FROM gcr.io/distroless/nodejs:12 AS runtime + FROM gcr.io/distroless/nodejs:16 AS runtime + # https://nodejs.org/api/cli.html#cli_node_options_options + ENV NODE_OPTIONS=--enable-source-maps
For a Serverless Lambda application, update your
serverless.yml
:provider: - runtime: nodejs12.x + runtime: nodejs14.x functions: Worker: environment: + # https://nodejs.org/api/cli.html#cli_node_options_options + NODE_OPTIONS: --enable-source-maps
For a CDK Lambda application, update your stack:
new aws_lambda.Function(this, 'worker', { - runtime: aws_lambda.Runtime.NODEJS_12_X, + runtime: aws_lambda.Runtime.NODEJS_14_X, environment: { + // https://nodejs.org/api/cli.html#cli_node_options_options + NODE_OPTIONS: '--enable-source-maps', }, });
-
template/lambda-sqs-worker: Disable
tty
on deploy step (#753)Serverless Framework v3 renders progress spinners on interactive terminals. We recommend disabling tty in CI/CD for cleaner log output.
-
template/lambda-sqs-worker: serverless ^3.0.0 (#748)
-
template/lambda-sqs-worker: Replace
custom.env
configuration withparams
(#752)You can now define environment specific variables using the new Serverless parameters feature. See https://www.serverless.com/framework/docs/guides/parameters for more details.
-
template/*-rest-api: seek-jobs/gantry v1.6.1 (#759)
-
template/lambda-sqs-worker: Remove
provider.lambdaHashingVersion
(#751)This resolves the following deprecation warning in Serverless Framework v3:
Setting "20201221" for "provider.lambdaHashingVersion" is no longer effective as new hashing algorithm is now used by default. You can safely remove this property from your configuration.
-
deps: eslint-config-skuba 1.0.14 (#758)
This disables the
tsdoc/syntax
ESLint rule in tests for compatibility with/** @jest-environment env */
directives. -
deps: isomorphic-git ^1.11.1 (#750)
Resolves SNYK-JS-SIMPLEGET-2361683.
-
init: Fix GitHub template cloning (#739)
This resolves the following error when cloning a project template from GitHub:
UnknownTransportError: Git remote "[email protected]:owner/repo.git" uses an unrecognized transport protocol: "ssh"
-
template/lambda-sqs-worker: Remove qualifier from smoke test invocation (#743)
Previously, this template's smoke test hook specified a
$LATEST
qualifier in itsLambda.Invoke
API call. AWS authorised the call based on the unqualified Lambda ARN in ourserverless.yml
IAM policy, but will stop doing so after April 2022.To avoid deployment failures, remove the qualifier in
src/hooks.ts
. An unqualified call is equivalent to targeting$LATEST
.- Qualifier: '$LATEST', + Qualifier: undefined,
-
node: Register
tsconfig-paths
in REPL (#745)This resolves the following error:
Error: Cannot find module '/node_modules/skuba/lib/register' Require stack: - internal/preload
-
deps: ts-jest ^27.1.2 (#729)
This resolves the following import issue in older 27.0.x versions of
ts-jest
:TypeError: pathsToModuleNameMapper is not a function
-
test: Restore Node.js 12 compatibility (#730)
This resolves the following error in Node.js 12 environments:
Object.entries(parsedConfig.options.paths ?? DEFAULT_PATHS).flatMap( ^ SyntaxError: Unexpected token '?'
Note that Node.js 12 will reach its end of life in May 2022.
-
template/koa-rest-api: Add opt-in OpenTelemetry support (#706)
-
deps: Prettier 2.5 (#701)
See the release notes for more information.
-
node, start: Register
tsconfig-paths
(#678)You can now define module aliases other than
src
for local development and scripting. Specify these through thepaths
compiler option in yourtsconfig.json
:// tsconfig.json { "compilerOptions": { "baseUrl": ".", "paths": { "src": ["src"], }, }, }
-
GitHub.buildNameFromEnvironment: Export helper function (#676)
-
jest: Support
tsconfig.json
paths (#698)Module aliases other than
src
are now supported inskuba test
. Our Jest preset includes a dynamicmoduleNameMapper
that reads thepaths
compiler option from yourtsconfig.json
. -
git: Export helper functions (#689)
-
test: Add GitHub check run annotations (#648)
skuba test
can now automatically annotate GitHub commits when you propagate CI environment variables and a GitHub API token. These annotations also appear inline with code under the “Files changed” tab in pull requests. -
GitHub.getPullRequestNumber: Export helper function (#690)
-
GitHub.putIssueComment: Export helper function (#690)
This enables use cases like a persistent bot comment at the top of a pull request a la Changesets that reflects the current status of a CI check.
-
GitHub.enabledFromEnvironment: Export helper function (#676)
-
GitHub.createCheckRun: Support
text
parameter (#673) -
template: Retrieve GitHub token on Test & Lint (#667)
-
template: serverless-prune-plugin ^2.0.0 (#719)
-
test: Fix
ts-jest
imports (#715)This resolves the following warning:
Replace any occurrences of "ts-jest/utils" with just "ts-jest".
If you're using the
mocked
utility fromts-jest
, switch over to the built-in Jest function:import git from 'isomorphic-git'; - import { mocked } from 'ts-jest'; jest.mock('isomorphic-git'); - mocked(git.commit).mockResolvedValue(''); + jest.mocked(git.commit).mockResolvedValue('');
-
template/lambda-sqs-worker-cdk: Migrate to AWS CDK v2 (#714)
-
node, start: Deregister
source-map-support
(#679)ts-node
takes care of this for us. -
template/lambda-sqs-worker-cdk: Fix docker-compose volume mount and deploy output (#695)
-
Jest.mergePreset: Allow
displayName
andprojects
(#648)
-
format, lint: Skip reading unsupported Prettier files into memory (#662)
-
format, lint: Fix file descriptor warnings (#664)
This resolves the following warning when processing files that Prettier cannot parse:
(node:123) Warning: File descriptor 456 closed but not opened in unmanaged mode
-
deps: Include
@octokit/types
(#660)This should fix the following compilation error:
node_modules/skuba/lib/api/github/checkRun.d.ts(2,45): error TS2339: Property 'POST /repos/{owner}/{repo}/check-runs' does not exist on type 'Endpoints'.
-
GitHub.createCheckRun: Add development API for writing annotations (#625)
-
lint: Add GitHub check run annotations (#625)
skuba lint
can now automatically annotate GitHub commits when you propagate Buildkite environment variables and a GitHub API token. These annotations also appear inline with code under the “Files changed” tab in pull requests. -
format, lint: Enable ESLint caching (#645)
ESLint now writes to a local
.eslintcache
store. This speeds up subsequent runs ofskuba format
andskuba lint
as they can skip unchanged files. -
deps: eslint-config-skuba 1.0.12 (#623)
This adds a couple new linting rules:
Run
skuba format
to automatically align your code with these rules. -
format, lint: Synchronise ignore files (#646)
skuba format
andskuba lint
will now keep.eslintignore
,.gitignore
and.prettierignore
in sync. This automatically applies new exclusions like.eslintcache
without the need for a manualskuba configure
.
-
template: Use correct
environment
key indocker-compose.yml
(#654) -
template/lambda-sqs-worker: Switch to ARM64 architecture (#640)
These are a bit cheaper and a bit faster than x86 Lambdas: https://aws.amazon.com/blogs/aws/aws-lambda-functions-powered-by-aws-graviton2-processor-run-your-functions-on-arm-and-get-up-to-34-better-price-performance/
The underlying Lambda architecture should be invisible to typical TypeScript Lambdas.
-
template: Bump non-Lambda templates to Node.js 16 (#633)
Node.js 16 is now in active LTS. The Lambda templates are stuck on Node.js 14 until the new AWS Lambda runtime is released.
-
template: seek-jobs/gantry v1.5.2 (#634)
-
deps: typescript 4.4.4 (#616)
-
start: Add a
?
placeholder for unnamed function arguments (#647) -
deps: Relax ranges (#622)
Projects can now upgrade to new Prettier and TypeScript patches and
ts-node-dev
minors without us having to cut a new release. -
template: hot-shots ^9.0.0 (#639)
-
template/lambda-sqs-worker: Remove
pino.Logger
indirection (#624) -
template: @seek/logger ^5.0.0 (#621)
-
template: Ignore
.gantry
YAML paths via.prettierignore
(#636)Gantry resource and value files often live in the
.gantry
subdirectory and may use non-standard template syntax. -
template: Propagate environment variables for GitHub annotations (#642)
This enables GitHub annotations for newly-initialised projects with the appropriate Buildkite configuration.
-
Jest.mergePreset: Do not mutate underlying defaults (#595)
Jest.mergePreset
no longer mutates the internaljest-preset
object. Subsequent calls toJest.mergePreset
will no longer return results merged in from previous calls.Warning: If you rely on mutating the core
jest-preset
object for later access, this is a Breaking Change. -
template/lambda-sqs-worker: Convert Serverless
isProduction
config value to boolean (#602)This avoids potentially surprising behaviour if you try to make use of this config value in a context that tests for truthiness. The boolean is still correctly applied as a string
seek:env:production
tag value. -
node, start: Handle void function inputs and outputs (#597)
When running a function entrypoint,
skuba node
andskuba start
now handle an omitted request body the same as an empty JSON array of arguments[]
. The function can also returnundefined
to omit a response body. -
template/lambda-sqs-worker: Opt in to new Serverless variables resolver (#601)
-
lint: Use worker threads when running
--serial
ly (#607)This aims to reduce the memory footprint of
skuba lint --serial
. ESLint and Prettier are now run in worker threads so their memory can be more readily freed on thread exit. -
template: Remove README tables of contents (#596)
GitHub's Markdown renderer now generates its own table of contents.
-
configure, init: Drop dependency on external Git installation (#599)
We now interface with
isomorphic-git
internally, which ensures compatibility and affords finer control over log output. -
format, lint: Run Prettier serially on files (#606)
This aims to reduce the memory footprint of
skuba lint
. -
template: seek-jobs/gantry v1.5.1 (#604)
-
Jest.mergePreset: Allow configuration of test environment (#592)
Jest's
testEnvironment
can now be passed toJest.mergePreset
:export default Jest.mergePreset({ testEnvironment: 'jsdom', });
-
template/lambda-sqs-worker: Fail fast on invalid Serverless config (#605)
-
template: pino-pretty ^6.0.0 (#594)
pino-pretty@7 requires pino@7, which has not been released on its stable channel yet.
-
node, start: Print function entrypoint parameters (#600)
When running a function entrypoint,
skuba node
andskuba start
now print the function and parameter names as a usage hint:yarn skuba node 'src/api/buildkite/annotate.ts#annotate' // annotate (markdown, opts) // listening on port 9001 curl --data '["_Hello there_", {}]' --include localhost:9001
-
configure: Tone down Dockerfile
outDir
processing (#585)This avoids rewriting sequences like "distroless" as "libroless".
-
template: Remove
unknown
specifier in catch clauses (#580)Strict TypeScript 4.4 now defaults to typing catch clause variables as
unknown
. -
build-package, lint: Handle worker thread errors more gracefully (#583)
The worker threads now correctly propagate an exit code and log errors instead of triggering an
UnhandledPromiseRejectionWarning
. -
format, lint: Limit Prettier to 25 parallel file I/O operations (#584)
This should alleviate file descriptor issues that are not handled by
graceful-fs
such asEBADF: bad file description, close
.
-
lint: Run ESLint and Prettier in worker threads (#548)
This reduces the number of Node.js processes spawned by
skuba lint
. We've also been able to significantly enhance our logging output as a result, particularly when the--debug
flag is supplied. -
build-package, lint: Add
--serial
flag (#556)This explicitly disables concurrent command execution.
Propagating the
BUILDKITE
environment variable to these commands no longer constrains their concurrency. If you were relying on this behaviour to reduce resource contention on undersized Buildkite agents, update your commands to pass in the flag:- build-package + build-package --serial - lint + lint --serial
See our Buildkite guide for more information.
-
node: Run REPL in process (#534)
This avoids creating a separate Node.js process just to run the REPL.
-
Buildkite.annotate: Add development API for writing annotations (#558)
-
format: Execute ESLint with
--report-unused-disable-directives
(#512)skuba format
will now flag unused disable directives, and will automatically remove them once ESLint v8 is released. -
deps: Prettier 2.4 (#507)
This includes TypeScript 4.4 support. See the release notes for more information.
-
deps: TypeScript 4.4 (#497)
This major release includes breaking changes. See the announcement for more information.
Note that new syntax in TypeScript 4.4 will only be supported by
skuba format
andskuba lint
once ESLint v8 is released. -
format: Run ESLint and Prettier in process (#539)
This eliminates the overhead of spinning up separate Node.js processes. We've also been able to significantly enhance our logging output as a result, particularly when the
--debug
flag is supplied. -
build: Remove experimental Babel support (#513)
There's limited upside to switching to Babel-based builds for backend use cases, and it would be difficult to guarantee backwards compatibility with existing
tsconfig.json
-based configuration. Dropping Babel dependencies reduces our package size and resolves SNYK-JS-SETVALUE-1540541. -
lint: Support Buildkite annotations (#558)
skuba lint
can now output issues as Buildkite annotations.See our Buildkite guide for more information.
-
template: pino-pretty ^7.0.0 (#506)
-
template: Configure environment variables and volume mounts for Buildkite annotations (#558)
-
template: serverless-plugin-canary-deployments ^0.7.0 (#508)
-
template/lambda-sqs-worker*: Prime dev ECR cache in Buildkite pipeline (#503)
This should result in faster "Deploy Dev" times as the ECR cache will already be warm.
-
template: seek-jobs/gantry v1.4.1 (#504)
-
template: Remove
@types/node
resolution override (#498)Jest 27.1 is compatible with newer versions of
@types/node
. -
template/*-rest-api: Suggest using a secure header middleware (#579)
-
template/lambda-sqs-worker-cdk: Run "Test, Lint & Build" step in prod (#503)
This reduces our dependence on a dev environment to successfully deploy to prod.
-
build-package, lint: Simplify logging prefix (#535)
-
Jest.mergePreset: Allow
watchPathIgnorePatterns
(#555) -
build-package, lint: Limit max concurrency to CPU core count (#540)
-
template: Remove Yarn cache from worker Docker images (#499)
This shrinks the cached Docker images that our worker templates generate.
- template: @types/node ^14.17.19 (#490)
- template: seek-jobs/gantry v1.4.0 (#483)
- deps: @types/jest ^27.0.0 (#489)
- template/*-rest-api: Parameterise AWS region (#488)
-
template: seek-oss/docker-ecr-cache v1.11.0 (#467)
-
template: Add
test:ci
script (#473) -
template: Force
@jest/types
resolution to fix clean installs (#468) -
template/lambda-sqs-worker: Use Docker Build secrets (#476)
-
template/greeter: Use Docker Build secrets (#476)
-
template/lambda-sqs-worker-cdk: Use Docker Build secrets (#476)
-
template: Group Buildkite pipeline anchors (#474)
This provides a bit more structure to our
pipeline.yml
s and allows anchored plugins to be recognised by Renovate. -
deps: ts-node-dev 1.1.8 (#462)
-
template/express-rest-api: Use Docker Build secrets (#471)
-
template/*-rest-api: Reduce app boilerplate (#478)
-
template: Default Docker Compose image to empty string (#469)
This suppresses Docker Compose CLI warnings and errors when running outside of Buildkite.
-
template: Use BUILDKITE_PIPELINE_DEFAULT_BRANCH in
pipeline.yml
(#475) -
configure, init: Deduplicate dependencies (#470)
-
template: Add placeholder test coverage configuration (#472)
-
template/lambda-sqs-worker-*: Build once upfront (#477)
This employs Buildkite artifacts to share compiled code with each subsequent deployment step.
-
deps: TypeScript 4.3.5 (#463)
-
template/koa-rest-api: Use Docker Build secrets (#471)
-
deps: TypeScript 4.3.4 (#455)
-
deps: prettier 2.3.2 (#460)
-
template/koa-rest-api: Include success message in smoke test body (#459)
-
template/greeter: Use
seek-oss/docker-ecr-cache
Buildkite plugin (#453) -
template/lambda-sqs-worker: Set
memorySize
for smoke test hook to 128 MiB (#457) -
template/koa-rest-api: Use
seek-oss/docker-ecr-cache
Buildkite plugin (#453) -
template/express-rest-api: Use
seek-oss/docker-ecr-cache
Buildkite plugin (#453) -
template: Reuse ECR cache in Docker Compose (#453)
-
deps: ts-node-dev 1.1.7 (#461)
Resolves CVE-2021-33623.
-
deps: Prettier 2.3.1 (#446)
skuba format
andskuba lint
now support TypeScript 4.3 syntax. See the full Prettier changelog for more information. -
template: pino-pretty ^5.0.0 (#441)
-
template: seek-jobs/gantry v1.3.0 (#452)
-
deps: Prettier 2.3 (#434)
This release may require reformatting of your code. If your lint step is failing in CI, run your format command locally then push the resulting changes.
yarn format
-
deps: TypeScript 4.3 (#434)
This major release includes breaking changes. See the announcement for more information.
skuba format
andskuba lint
will error on new TypeScript 4.3 syntax that are not yet supported by Prettier. -
deps: Jest 27 (#433)
This major release includes breaking changes. See the Jest 27 blog post and changelog for more information.
-
Jest.mergePreset: Type
snapshotSerializers
option (#436) -
template: Banish
typeof undefined
syntax (#429) -
template/lambda-sqs-worker-cdk: Always build before deploy (#428)
This prevents stale compiled code from being cached and deployed from ECR.
-
template/koa-rest-api: Log returned error responses (#430)
-
template: Prune
devDependencies
instead of installing twice in Docker (#435)The template-bundled Dockerfiles would previously run
yarn install
twice to build a separate stage for productiondependencies
only. These have been updated to correctly share the Yarn cache across stages and to useyarn install --production
to perform offline pruning. -
deps: fs-extra ^10.0.0 (#424)
-
template/*-npm-package: Add
yarn commit
script (#418) -
template/lambda-sqs-worker-cdk: Trim CDK deployment output (#423)
-
template: @types/node ^15.0.0 (#422)
-
deps: typescript 4.2.4 (#376)
See the announcement for features and breaking changes. Note that the currently bundled version of Prettier does not support
abstract
construct signatures. -
template/lambda-sqs-worker-cdk: Fix npm token in Buildkite pipeline (#423)
-
template/lambda-sqs-worker-cdk: Add new template (#395)
-
format, lint: Support
--debug
flag (#367) -
template: Upgrade to Node 14 (#347)
Node.js 14 is now supported on AWS Lambda. This lets us upgrade the Node.js requirement for skuba's templates.
This should only impact newly created projects. You can use the template changes in this PR as an example of how to upgrade an existing project. A future version of skuba may include a fixup command to automatically upgrade your project to the most recent LTS release.
-
template/lambda-sqs-worker: Use new
serverless.yml#/provider/iam
grouping (#357)The
provider.iamRoleStatements
property will be removed in Serverless v3. -
template/lambda-sqs-worker: serverless-plugin-canary-deployments ^0.5.0 (#394)
The plugin now patches in CodeDeploy permissions to your
iamRoleStatements
, so you can clean yourserverless.yml
:- - Action: codedeploy:PutLifecycleEventHookExecutionStatus - Effect: Allow - Resource: !Sub arn:aws:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:*/${WorkerLambdaFunctionDeploymentGroup}
-
template: runtypes-filter ^0.6.0 (#408)
-
template/koa-rest-api: Fix ineffectual smoke test (#361)
-
template: Drop region parameterisation (#363)
-
deps: semantic-release ^17.3.8 (#353)
Resolves SNYK-JS-MARKED-1070800.
-
template/*-rest-api: Fail Gantry build if ECR scanning reports vulnerabilities (#373)
-
template: runtypes ^6.0.0 (#404)
-
template/koa-rest-api: Remove awkward request body from GET test (#362)
-
deps: ejs ^3.1.6 (#354)
Resolves SNYK-JS-EJS-1049328.
-
init: Mention GitHub repo creation (#382)
skuba doesn't have access to GitHub credentials to create a repository on your behalf. The CLI now makes it clearer that you should create an empty GitHub repository.
-
template/lambda-sqs-worker: Remove custom Serverless variable syntax (#350)
[email protected]
bundled native support for CloudFormation pseudo parameters. This even works with arbitrary logical IDs like!Sub ${WorkerLambdaFunctionDeploymentGroup}
. -
deps: runtypes ^6.0.0 (#406)
-
deps: ts-node-dev 1.1.6 (#371)
-
Jest: Expose
testTimeout
inJest.mergePreset
options (#389) -
template/lambda-sqs-worker: Use new
serverless.yml#/package/patterns
property (#415)The
package.exclude
andpackage.include
properties will be removed in Serverless v3. -
deps: concurrently ^6.0.0 (#379)
-
deps: typescript 4.1.5 (#355)
-
configure: Rewrite
dist => lib
inserverless.yml
s (#387) -
template/*-rest-api: Move Gantry region config to plugin options (#374)
-
template: Add GitHub repository settings and Renovate to init checklist (#388)
- node: Fix
src
module alias registration (#344)
-
node, start: Propagate
process.argv
(#341)Passing command-line arguments into a script now works as expected:
yarn skuba node src/script.ts arg1 arg2 arg3
-
node: Support Node.js inspector options when running a script (#341)
Passing an inspector option for script debugging now works as expected:
yarn skuba node --inspect-brk src/script.ts
-
build-package, lint: Run serially on Buildkite (#343)
These commands now run their underlying processes serially when the
BUILDKITE
environment variable is set. This reduces the chance of resource exhaustion on smaller instance sizes but slows down builds. -
template/koa-rest-api: Tidy custom Koa types (#336)
-
test: Exclude Jest
config.ts
files from coverage (#340) -
template: seek-jobs/gantry v1.2.11 (#336)
-
node: Add command (#298)
skuba node
lets you run a TypeScript source file, or open a REPL if none is provided:skuba node src/some-cli-script.ts
skuba node
This automatically registers a
src
module alias for ease of local development. For example, you can run a prospectivesrc/someLocalCliScript.ts
without having to register a module alias resolver:// This `src` module alias just works under `skuba node` and `skuba start` import { rootLogger } from 'src/framework/logging';
yarn skuba node src/someLocalCliScript
If you use this alias in your production code, your entry point(s) will need to import a runtime module alias resolver like
skuba-dive/register
. For example, yoursrc/app.ts
may look like:// This must be imported directly within the `src` directory import 'skuba-dive/register'; // You can use the `src` module alias after registration import { rootLogger } 'src/framework/logging';
-
node, start: Support function entry points (#301)
You can now specify an entry point that targets an exported function:
skuba start --port 12345 src/app.ts#handler
This starts up a local HTTP server that you can POST arguments to:
curl --data '["event", {"awsRequestId": "123"}]' --include localhost:12345
You may find this useful to run Lambda function handlers locally.
-
configure, help, init: Check for newer skuba versions (#300)
skuba will now print an upgrade command if there is a newer version available. You can now use a global installation without worrying that you're setting up new repos using outdated templates.
-
template/lambda-sqs-worker: Simplify Buildkite pipeline (#314)
-
deps: typescript 4.1.3 (#297)
-
template/koa-rest-api: Type context (#299)
-
lint: Detect incomplete templating (#315)
-
template: Use
jest.config.ts
(#303) -
template/lambda-sqs-worker: Add smoke test (#328)
This brings back versioned functions along with
serverless-prune-plugin
to control Lambda storage consumption. By default we configureserverless-plugin-canary-deployments
for an instantaneous switch once the smoke test has passed, but this can be customised as necessary. -
configure: Add
test:watch
script (#303) -
configure: Migrate
jest.config.js
tojest.config.ts
(#303) -
template: Enable retry of successful deployment steps (#311)
This should be used with caution, but may be necessary if you need to rapidly roll back a broken deployment.
-
template/*-rest-api: Supply custom autoscaling policy (#322)
-
init: Pick random server port (#333)
-
template/lambda-sqs-worker: Add
start
script (#301) -
template/*-rest-api: Explicitly register
listen.ts
(#332) -
deps: Bump caret ranges (#309)
Resolves SNYK-JS-SEMVERREGEX-1047770.
-
template/koa-rest-api: Limit request logging to errors (#294)
-
start: Improve support for non-HTTP server entry points (#298)
You can now run arbitrary TypeScript files without them exiting on a
You must export callback or requestListener
error. -
configure, init: Improve error messaging in offline scenarios (#305)
-
template/*-rest-api: Clarify health checks and smoke tests (#332)
-
template/lambda-sqs-worker: Require deployment bucket (#330)
-
pkg: Remove ESM from skuba's bundle (#296)
This simplifies our bundle; Node.js and skuba's CLI have always defaulted to CommonJS anyway.
-
start: Support
src
module alias (#298) -
node, start: Support
--port
option (#301) -
configure: Remove
package-lock.json
(#324) -
test: Set
NODE_ENV=test
(#326)This is something that Jest itself does in its
bin/jest
. -
template: Bump caret ranges (#331)
-
start: Support source maps (#298)
-
template/lambda-sqs-worker: Lock Serverless
lambdaHashingVersion
(#329)This gets rid of the following warning when deploying:
Deprecation warning: Starting with next major version, default value of provider.lambdaHashingVersion will be equal to "20201221" More Info: https://www.serverless.com/framework/docs/deprecations/#LAMBDA_HASHING_VERSION_V2
-
deps: Bump minor and patch versions (#331)
-
configure: Ensure workspaced
package.json
is private (#306) -
template/*-rest-api: Use Distroless runtime images (#316)
-
template: Uplift READMEs (#334)
-
deps: TypeScript 4.1 (#269)
This includes formatting and linting support for new syntax features.
See the release notes for more information.
-
lint: Check for unused
eslint-disable
directives (#272)skuba lint
will now report on unnecessaryeslint-disable
directives that should be removed:- /* eslint-disable-next-line new-cap */ const camelCase = 'no problems here';
-
template: Check coverage on default
test
script (#290) -
deps: babel-plugin-macros ^3.0.0 (#277)
-
deps: ts-node-dev 1.1.1 (#288)
If you see the following error on
npm install
:npm ERR! enoent ENOENT: no such file or directory, chmod '.../node_modules/ts-node-dev/lib\bin.js'
Try updating npm:
npm -g install npm
-
template: Include
test:watch
script (#290) -
build: Fix
--out-dir requires filenames
error on experimental Babel builds (#291) -
deps: eslint-config-skuba 1.0.10 (#284)
-
deps: prettier 2.2.1 (#278)
-
start: Support default export of Express listener (#289)
-
template/express-rest-api: Fix server listener and port (#289)
-
template: Lock
.nvmrc
s to Node.js 12 (#281)
-
deps: typescript 4.0.5 (#241)
-
template: Add
.me
files (#248) -
deps: semantic-release ^17.2.3 (#263)
-
template/lambda-sqs-worker: Remove redundant
ecr
plugin (#259) -
template: seek-jobs/gantry v1.2.9 (#249)
-
template/koa-rest-api: seek-koala ^5.0.0 (#260)
-
template: supertest ^6.0.0 (#243)
-
template: runtypes-filter ^0.4.0 (#257)
-
template: @koa/router ^10.0.0 (#249)
-
template: Mount working directory in Docker Compose (#247)
-
template/lambda-sqs-worker: Default to unversioned Lambdas (#245)
Our baseline template does not do canary deployments, and this makes it less likely to hit code storage limits down the road.
-
template: seek-datadog-custom-metrics ^4.0.0 (#261)
-
deps: Pin ts-node-dev 1.0.0-pre.63 (#239)
This fixes errors on
npm install
on macOS and Linux. Yarn 1.x was unaffected by this issue. -
template: seek-jobs/gantry v1.2.8 (#238)
-
start: Support default exports (#90)
skuba start
now works with a Koa application exported withexport default
. This syntax is preferred overexport =
for compatibility with tooling such as Babel. -
start: Support Node.js debugging options (#230)
skuba start
now accepts--inspect
and--inspect-brk
options. This allows you to attach a debugger to the process. -
init: Redesign base prompt (#234)
The base prompt no longer mandates a team name and supports copy+paste.
-
template/lambda-sqs-worker: Remove region from subscription example snippet (#223)
-
template: supertest ^5.0.0 (#220)
-
template/koa-rest-api: hot-shots ^8.0.0 (#217)
-
deps: Bump caret ranges (#235)
-
template: Recommend
@seek/logger
(#225)This provides logging structure, trimming and redaction over plain Pino.
-
template: docker-compose v3.7.0 (#224)
-
template: Unset initial skuba version (#216)
-
template/greeter: Align Dockerfile stages (#219)
-
template/koa-rest-api: Avoid
export =
syntax (#90) -
deps: normalize-package-data ^3.0.0 (#231)
-
template: Skip pre-build in Docker Compose service (#222)
-
template: Add
start:debug
scripts (#230)
-
deps: prettier 2.1.2 (#207)
-
template: docker-compose v3.6.0 (#210)
-
template/lambda-sqs-worker: serverless ^2.0.0 (#203)
-
deps: eslint-config-skuba 1.0.8 (#214)
This patch should reduce
@typescript-eslint
noise across JS files. -
template/*-rest-api: seek-jobs/gantry v1.2.6 (#211)
-
deps: typescript 4.0.3 (#208)
-
template/koa-rest-api: Remove
koa-cluster
(#206)While Fargate environments with <= 1 vCPU appear to expose multiple threads, clustering does not improve performance and only serves to increase idle memory usage.
You may add
koa-cluster
yourself if you have a CPU-bound workload running on multiple vCPUs. Even in such cases, it may be better to run multiple tasks with one vCPU each rather than one task with multiple vCPUs. -
template: Bump dep ranges (#212)
-
deps: Bump minor ranges (#214)
-
start: Allow execution despite typechecking errors (#201)
-
template/lambda-sqs-worker: Include
aws-sdk
in bundle (#198) -
build: Support
tsc --build
flag (#200) -
configure: Remove direct
eslint-config-skuba
andsemantic-release
dependencies (#195) -
build-package, lint: Colour code subprocess output (#190)
-
build-package, lint: Clean up error output (#190)
-
configure: Clean up select
lint:xxx
scripts inpackage.json
(#196) -
test: Resolve
@typescript-eslint/typescript-estree
warnings with TypeScript 4.0: (#202)WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.
-
configure: Use TypeScript 4.0 node factory API (#193)
-
lint: eslint-plugin-jest ^24.0.0 (#202)
This enables a few additional linting rules by default.
-
deps: TypeScript 4.0 (#188)
This includes compatible versions of ESLint, Jest and Prettier. You may need to reformat your code with
yarn skuba format
.TypeScript 4.0 is largely backward compatible, but you may see errors if you
delete
a required property:const fn = (arg: { prop: string }) => { delete arg.prop; // ~~~~~~ // error! The operand of a 'delete' operator must be optional. };
-
lint: Allow incremental typechecking (#188)
- configure: Fix bad import (#187)
- template: Use unknown catch clause variables (#189)
- template/*-npm-package: Retain comments out of the box (#184)
- template/lambda-sqs-worker: Qualify
awsRequestId
log field (#186)
- template/express-rest-api: Add new template (#176)
- deps: ts-node ^9.0.0 (#180)
- configure, template/*-npm-package: Pack JSON files (#182)
- configure: Retain package comments on first run (#181)
- template: seek-jobs/gantry v1.2.5 (#174)
- template/*-npm-package: Avoid TSDoc linting errors on init (#171)
- template/koa-rest-api: Use per-Gantry environment concurrency group in dev (#165)
- template: seek-jobs/gantry v1.2.4 (#170)
- template/koa-rest-api: Simplify supertest-koa bootstrap (#163)
- template: Remove explicitly set NPM_READ_TOKEN from Dockerfile commands (#168)
- deps: Limit direct lodash usage to
lodash.mergewith
(#167)
- template: runtypes-filter ^0.3.0 (#160)
- template/koa-rest-api: Keep AWS SDK connections alive (#159)
- deps: runtypes ^5.0.0 (#155)
- template: seek-jobs/gantry v1.2.3 (#161)
- deps: typescript 3.9.7 (#158)
- template: docker-compose v3.5.0 (#153)
- template: runtypes ^5.0.0 (#156)
- deps: eslint-config-skuba 1.0.4 (#157)
-
template/lambda-sqs-worker: Default VERSION to local (#148)
-
template/koa-rest-api: Add intermediate Dockerfile stages (#147)
-
template: ecr v2.1.1 (#144)
-
template/koa-rest-api: Switch to Runtypes (#152)
Yup has overly permissive input coercion (see #151) and weaker type guarantees.
We already use Runtypes in the Lambda template; other options could be explored in future.
-
template/lambda-sqs-worker: Use better Runtypes syntax (#152)
-
template: docker-compose v3.4.0 (#144)
-
template: Add basic deployment documentation (#148)
- template/lambda-sqs-worker: Use connection reuse environment variable (#130)
- template: Redact
err.config.agent
path from logs (#140) - deps: typescript 3.9.6 (#139)
- deps: eslint-config-skuba 1.0.3 (#139)
- test: Fix
passWithNoTests
warning (#128)
- configure: Avoid stripping of
_
filename prefixes (#119) - configure: Remove duplicate
lib
exclusions fromtsconfig.json
(#124) - test: Add
Jest.mergePreset
helper function (#126) - format, lint: Include tsx files in ESLint linting (#123)
- deps: eslint ^7.3.1 + eslint-config-skuba 1.0.1 (#120)
- test: Collect coverage from TSX files (#125)
- configure: Use simple ESLint extends syntax (#122)
-
configure: Support migration from
seek-module-toolkit
(#66)seek-module-toolkit
users can now installskuba
and runskuba configure
to migrate their configuration.Care should be taken around the change in build directories.
-
eslint: skuba is now usable as a shareable config (#81)
// .eslintrc.js module.exports = { // This can be used in place of require.resolve('skuba/config/eslint') extends: ['skuba'], };
-
build, start: Support experimental Babel toolchain (#85)
You can now build your project with Babel instead of tsc. Experimentally.
See our Babel topic for details.
-
jest: skuba is now usable as a preset (#50)
// jest.config.js const { testPathIgnorePatterns } = require('skuba/config/jest'); module.exports = { // This can be used in place of ...require('skuba/config/jest') preset: 'skuba', // This is still necessary as Jest doesn't deep-merge presets testPathIgnorePatterns: [...testPathIgnorePatterns, '/test\\.ts'], };
-
configure: Replace relocated dependencies (#54)
skuba configure
now replaces the following dependencies and updates their import paths via naive find-and-replace:@seek/koala → seek-koala
@seek/node-datadog-custom-metrics → seek-datadog-custom-metrics
@seek/skuba → skuba
@seek/skuba-dive → skuba-dive
-
init: Commit initial template files and configure default remote (#51)
-
format, lint: Enforce TSDoc syntax (#75)
-
template/oss-npm-package: Add new template (#73)
This is intended for seek-oss projects.
- configure: Delete
test:build
andtest:jest
scripts (#95) - configure: List skuba upgrade upfront (#68)
- configure, init: Avoid unnecessary file writes during templating (#48)
- template/lambda-sqs-worker: Drop
hot-shots
dependency (#57) - configure, init: Sort dependencies (#52)
- template: Redact
Authorization
headers in logs (#59) - template/*-npm-package: Make prompt unskippable (#76)
- configure, init: Exclude
lib-
directories from compilation (#102) - template/private-npm-package: Fix ReferenceError on init (#60)
- help: Show
build-package
correctly (#55) - configure: Migrate
collectCoverageFrom
Jest option (#105) - configure: Tame newlines in ignore files (#89)
- configure: List filtered devDependencies upfront (#67)
- configure, init:
.dockerignore
the.gantry
folder. This should decrease build times. (#62) - template/koa-rest-api: Ensure lint passes on init (#70)
- configure: Sort more
package.json
props (#101) - init: Install matching skuba version (#83)
- init: Extend validation on initial GitHub fields (#49)
- template/*-npm-package: Drop module aliasing from
tsconfig.json
(#75) - template: Redact
err.config.sockets
from logs (#82) - template/koa-rest-api: Support improved Runtypes error messaging (#96)
- configure: Handle
skuba-dive
dependency upfront (#79) - configure: Migrate select Jest options (#100)
- configure: Reserve skuba-managed sections in ignore files (#58)
- configure, init:
.gitignore
archives created bynpm pack
(#78) - template/private-npm-package: Include a half-decent README (#74)
- configure, init: Make mentioned commands actually runnable (#104)
- configure: Clean up ignore files during migration (#94)
- configure, init:
.dockerignore
the.git
folder. This should decrease build times. (#61) - configure: Add notice for smt migrations (#77)
- cli: Suppress dependency deprecation warnings (#108)
- configure: Delete
.npmignore
(#93) - template: Drop duplicate team name prompt (#72)
- template/koa-rest-api: Use Koala's error handler (#44)
- configure, init: Reduce unintended stripping of
_
filename prefix (#106)
-
template/private-npm-package: Add new template (#40)
The
private-npm-package
template replacessmt init
.This change also defaults TypeScript's
moduleResolution
tonode
. This shouldn't break any existing consumers as it is the default resolution strategy for CommonJS.
-
template/koa-rest-api: Remove unused function (#35)
-
init: Redesign first prompt (#42)
-
cli: Tweak prompt spacing and wording (#39)
-
template/koa-rest-api: Pass through Gantry environment as ENVIRONMENT (#37)
-
deps: Bump bundled and template dependencies (#43)
This includes TypeScript 3.9.5.
- format, lint: Relax on Jest config files (#31)
-
format, lint: ESLint 7 +
typescript-eslint
3 (#19)This upgrade introduces stricter rules around
any
andobject
usage for type safety.Consider the following alternatives:
-
Use
unknown
for a value whose type is truly unknown. This is a type-safe alternative toany
that the TypeScript ecosystem is moving towards.- const data = JSON.parse(str); + const data = JSON.parse(str) as unknown;
-
Prove the value has a specific type using a type guard or runtime validation library.
- const safeData = inputData as any; + const safeData = RuntimeValidator.check(inputData);
-
Use
Record<PropertyKey, unknown>
to indicate an object with unknown properties.- const isObject = (data: unknown): data is object => { ... }; + const isObject = (data: unknown): data is Record<PropertyKey, unknown> => { ... };
-
Disable the specific ESLint rule for the problematic line.
/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */ const takeAnyBody = ctx.request.body;
-
-
build-package: Add opinionated command to replace
smt build
(#15)See the migration documentation for more information.
-
init: Restore
--silent
arg foryarn add
(#30) -
configure, init: Tweak ignore file patterns (#11)
Directory names like
/lib-es2015
are ignored based on prefix now, but certain patterns have been restricted to the root to allow for/src/lib
. -
configure: Use
latest-version
to check package versions (#24) -
configure, init: Switch to oss
skuba-dive
package (#21) -
template: Switch to
seek-datadog-custom-metrics
(#28) -
template/koa-rest-api: Switch to
seek-koala
(#28) -
configure: Keep name, readme and version fields in package.json (#18)
-
configure: Drop
--ignore-optional
fromyarn install
(#25) -
start: Remove support for a custom port logging function (#16)
-
init: Drop
--ignore-optional --silent
fromyarn add
(#25) -
template/koa-rest-api: Bump Gantry plugin to v1.2.2 (#8)
-
deps: Declare
@types/jest
as a peer dependency (#22) -
format, lint: Group
'src'
import along with'src/**'
(#7) -
configure, init: Exclude files from templating based on .gitignore (#20)
- pkg: Release on
seek-oss
(#4)