Skip to content

Releases: seek-oss/skuba

skuba@8.0.1

17 Apr 06:36
b5d5a58
Compare
Choose a tag to compare

Patch Changes

  • 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 in package.json, which could cause a subsequent pnpm install --offline to run Corepack online or otherwise hang on stdin:

    FROM --platform=arm64 node:20-alpine
    
    RUN corepack enable pnpm
    {
      "packageManager": "pnpm@8.15.4",
      "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 in package.json, and (2) Dockerfiles to mount package.json and run corepack 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)

skuba@8.0.0

25 Mar 06:29
4049ce9
Compare
Choose a tag to compare

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.

Major Changes

  • 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.

Minor Changes

  • 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.

Patch Changes

  • 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
    1. 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 under amd64.
    2. Fall back to arm64 if the build platform is not available. This maintains compatibility with toolchains like Gantry that lack support for the BUILDPLATFORM argument.

    This approach allowed you to quickly build images and run containers in a local environment without emulation. For example, you could docker build an arm64 image on an Apple Silicon laptop for local troubleshooting, while your CI/CD solution employed amd64 hardware across its build and runtime environments. The catch is that your local arm64 image may exhibit different behaviour, and is unsuitable for use in your amd64 runtime environment without cross-compilation.

    The built-in templates now hardcode --platform as we have largely converged on arm64 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.

  • Jest.mergePreset: Fudge Node16 and NodeNext module resolutions (#1481)

    This works around a ts-jest issue where test cases fail to run if your moduleResolution 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.

eslint-config-skuba@4.0.0

25 Mar 06:29
4049ce9
Compare
Choose a tag to compare

Major Changes

  • deps: eslint-config-seek 13 + typescript-eslint ^7.2.0 (#1487)

    These major upgrades bump our minimum requirements:

    • Node.js >=18.18.0
    • ESLint >=8.56.0
    • TypeScript >=4.7.5

    See the typescript-eslint v7 announcement for more information.

v7.5.1

13 Mar 09:05
37e39c0
Compare
Choose a tag to compare

Patch Changes

  • 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 as jest --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)

v7.5.0

21 Feb 06:00
2416190
Compare
Choose a tag to compare

Minor Changes

  • 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 a SKUBA_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 in infra/ 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.

Patch Changes

  • lint: Remove Dockerfile-incunabulum rule (#1441)

    Previously, skuba lint would search for and delete a file named Dockerfile-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)

v7.4.1

07 Feb 22:42
5d14b25
Compare
Choose a tag to compare

Patch Changes

  • lint: Fix issue where skuba lint would fail in gutenberg projects due to the existence of Dockerfile-incunabulum files (#1439)

v7.4.0

07 Feb 06:16
966c397
Compare
Choose a tag to compare

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. If you'd like to migrate before then, check out the pnpm deep dive.

Continue reading for more details on these changes and other improvements in this release.

Minor Changes

  • 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 running skuba format or skuba 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 forgotten skuba 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 to nodejs-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 uses pnpm 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 and main 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 or format commands following a skuba update. If your build pipeline is utilising autofixes, these changes will be pushed up automatically.

Patch Changes

  • 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 the declaration 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 for jest.setup.ts and jest.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 introduces deploy:hotswap and deploy:watch scripts to the package.json manifest and a Deploy Dev (Hotswap) step to the Buildkite pipeline. Read more about watch and ...

Read more

v7.3.1

21 Nov 00:17
eb9a35c
Compare
Choose a tag to compare

Patch Changes

  • 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.

v7.3.0

02 Nov 04:49
7c8fa64
Compare
Choose a tag to compare

Minor Changes

  • Jest.mergePreset: Propagate root-level configuration options to projects (#1294)

    Jest.mergePreset now propagates the moduleNameMapper and transform options from root-level configuration to the projects 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 as docker-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.

Patch Changes

  • 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 on Warm/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 in SEEK-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.

v7.2.0

07 Sep 05:26
6f5677f
Compare
Choose a tag to compare

Minor Changes

  • deps: TypeScript 5.2 (#1247)

    This major release includes breaking changes. See the TypeScript 5.2 announcement for more information.

Patch Changes

  • 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'.