Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions .eslintrc.js

This file was deleted.

9 changes: 5 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ yarn build && ./dist/craft
## Code Style

- **TypeScript** is used throughout the codebase.
- **Prettier** with single quotes and no arrow parens (configured in `.prettierrc.yml`).
- **ESLint** extends `@typescript-eslint/recommended`.
- **Prettier** 3.x with single quotes and no arrow parens (configured in `.prettierrc.yml`).
- **ESLint** 9.x with flat config (`eslint.config.mjs`) using `typescript-eslint`.
- Unused variables prefixed with `_` are allowed (e.g., `_unusedParam`).

## Project Structure
Expand All @@ -38,7 +38,7 @@ src/
├── __tests__/ # Test files (*.test.ts)
├── artifact_providers/ # Artifact provider implementations
├── commands/ # CLI command implementations
├── schemas/ # JSON schema and TypeScript types for config
├── schemas/ # Zod schemas and TypeScript types for config
├── status_providers/ # Status provider implementations
├── targets/ # Release target implementations
├── types/ # Shared TypeScript types
Expand All @@ -52,9 +52,10 @@ dist/

## Testing

- Tests use **Jest** with `ts-jest`.
- Tests use **Vitest**.
- Test files are located in `src/__tests__/` and follow the `*.test.ts` naming pattern.
- Run tests with `yarn test`.
- Use `vi.fn()`, `vi.mock()`, `vi.spyOn()` for mocking (Vitest's mock API).

## CI/CD

Expand Down
32 changes: 32 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';

export default tseslint.config(
{
ignores: ['docs/**', 'dist/**', 'node_modules/**', 'coverage/**', '*.mjs', '**/*.js'],
},
eslint.configs.recommended,
...tseslint.configs.recommended,
prettier,
{
languageOptions: {
ecmaVersion: 2022,
sourceType: 'module',
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'no-constant-condition': ['error', { checkLoops: false }],
// Make sure variables marked with _ are ignored (ex. _varName)
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-ignore': 'allow-with-description',
},
],
'@typescript-eslint/no-require-imports': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
},
}
);
16 changes: 0 additions & 16 deletions jest.config.js

This file was deleted.

52 changes: 18 additions & 34 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,12 @@
"craft": "dist/craft",
"sentry-craft": "dist/craft"
},
"resolutions": {
"**/set-value": ">=2.0.1",
"**/https-proxy-agent": ">=2.2.3",
"**/node-forge": ">=0.10.0",
"**/dot-prop": "^5.3.0",
"**/kind-of": ">=6.0.3",
"**/node-fetch": "^2.6.7",
"**/yargs-parser": ">=18.1.3",
"**/parse-url": ">=5.0.3",
"**/ansi-regex": ">=5.0.1 < 6.0.0",
"@jest/reporters/**/strip-ansi": "^6.0.1"
},
"devDependencies": {
"@aws-sdk/client-lambda": "^3.2.0",
"@google-cloud/storage": "^5.7.0",
"@octokit/plugin-retry": "^3.0.9",
"@aws-sdk/client-lambda": "^3.723.0",
"@google-cloud/storage": "^7.14.0",
"@octokit/plugin-retry": "^7.1.2",
"@octokit/request-error": "^7.0.0",
"@octokit/rest": "^18.10.0",
"@octokit/rest": "^21.0.2",
"@sentry/node": "^10.27.0",
"@sentry/typescript": "^5.20.1",
"@types/async": "^3.0.1",
Expand All @@ -36,7 +24,6 @@
"@types/extract-zip": "^2.0.1",
"@types/git-url-parse": "^9.0.0",
"@types/is-ci": "^2.0.0",
"@types/jest": "^29.5.2",
"@types/js-yaml": "^4.0.5",
"@types/mkdirp": "^1.0.0",
"@types/node": "^22.10.1",
Expand All @@ -48,33 +35,32 @@
"@types/tar": "^4.0.0",
"@types/tmp": "^0.0.33",
"@types/yargs": "^17",
"@typescript-eslint/eslint-plugin": "^5.19.0",
"@typescript-eslint/parser": "^5.19.0",
"ajv": "6.12.6",
"@eslint/js": "^9.17.0",
"typescript-eslint": "^8.18.2",
"zod": "^3.24.1",
"async": "3.2.2",
"aws4": "^1.11.0",
"chalk": "4.1.1",
"cli-table": "0.3.1",
"consola": "2.15.3",
"esbuild": "^0.25.0",
"eslint": "^7.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0",
"eslint-formatter-github-annotations": "^0.1.0",
"extract-zip": "^2.0.1",
"fast-xml-parser": "^4.2.4",
"git-url-parse": "^16.1.0",
"glob": "^11.0.0",
"is-ci": "^2.0.0",
"jest": "^29.7.0",
"vitest": "^3.0.2",
"js-yaml": "4.1.1",
"json-schema-to-typescript": "5.7.0",
"mkdirp": "^1.0.4",
"mustache": "3.0.1",
"nock": "^13.2.4",
"node-fetch": "^2.6.1",
"nvar": "1.3.1",
"ora": "5.4.0",
"prettier": "^2.2.1",
"prettier": "^3.4.2",
"prompts": "2.4.1",
"rimraf": "2.7.1",
"shell-quote": "1.7.3",
Expand All @@ -84,22 +70,20 @@
"string-length": "3.1.0",
"tar": "6.2.1",
"tmp": "0.2.4",
"ts-jest": "^29.1.1",
"typescript": "^5.1.6",
"typescript": "^5.7.2",
"yargs": "^18"
},
"scripts": {
"build:fat": "yarn run compile-config-schema && tsc -p tsconfig.build.json",
"build:watch": "yarn run compile-config-schema && tsc -p tsconfig.build.json --watch",
"build": "yarn compile-config-schema && esbuild src/index.ts --sourcemap --bundle --platform=node --target=node22 --inject:./src/utils/import-meta-url.js --define:import.meta.url=import_meta_url --outfile=dist/craft",
"build:fat": "tsc -p tsconfig.build.json",
"build:watch": "tsc -p tsconfig.build.json --watch",
"build": "esbuild src/index.ts --sourcemap --bundle --platform=node --target=node22 --inject:./src/utils/import-meta-url.js --define:import.meta.url=import_meta_url --outfile=dist/craft",
"precli": "yarn build",
"cli": "node -r source-map-support/register dist/craft",
"clean": "rimraf dist coverage",
"lint": "eslint . --ext .ts,.tsx,.js --cache --cache-strategy content",
"lint": "eslint --cache --cache-strategy content",
"fix": "yarn lint --fix",
"test": "jest",
"test:watch": "jest --watch --notify",
"compile-config-schema": "node ./scripts/config-json-schema-to-ts.js",
"test": "vitest run",
"test:watch": "vitest",
"docs:dev": "cd docs && yarn dev",
"docs:build": "cd docs && yarn build"
},
Expand Down
20 changes: 0 additions & 20 deletions scripts/config-json-schema-to-ts.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/__mocks__/@aws-sdk/client-lambda.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */

const PUBLISHED_LAYER_TEST = {
Version: 1,
Expand Down
109 changes: 104 additions & 5 deletions src/__mocks__/fs.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,107 @@
const actualFs = jest.requireActual('fs');
import { vi } from 'vitest';

module.exports = {
// Import the actual fs module using require to avoid circular mock issues
// eslint-disable-next-line @typescript-eslint/no-require-imports
const actualFs = require('fs') as typeof import('fs');

// Mock existsSync to return true by default
export const existsSync = vi.fn((path: string) => {
return actualFs.existsSync(path);
});

// Re-export everything from the actual fs module
export const accessSync = actualFs.accessSync;
export const appendFileSync = actualFs.appendFileSync;
export const chmodSync = actualFs.chmodSync;
export const chownSync = actualFs.chownSync;
export const closeSync = actualFs.closeSync;
export const copyFileSync = actualFs.copyFileSync;
export const cpSync = actualFs.cpSync;
export const createReadStream = actualFs.createReadStream;
export const createWriteStream = actualFs.createWriteStream;
export const fchmodSync = actualFs.fchmodSync;
export const fchownSync = actualFs.fchownSync;
export const fdatasyncSync = actualFs.fdatasyncSync;
export const fstatSync = actualFs.fstatSync;
export const fsyncSync = actualFs.fsyncSync;
export const ftruncateSync = actualFs.ftruncateSync;
export const futimesSync = actualFs.futimesSync;
export const lchmodSync = actualFs.lchmodSync;
export const lchownSync = actualFs.lchownSync;
export const linkSync = actualFs.linkSync;
export const lstatSync = actualFs.lstatSync;
export const lutimesSync = actualFs.lutimesSync;
export const mkdirSync = actualFs.mkdirSync;
export const mkdtempSync = actualFs.mkdtempSync;
export const openSync = actualFs.openSync;
export const opendirSync = actualFs.opendirSync;
export const readFileSync = actualFs.readFileSync;
export const readSync = actualFs.readSync;
export const readdirSync = actualFs.readdirSync;
export const readlinkSync = actualFs.readlinkSync;
export const realpathSync = actualFs.realpathSync;
export const renameSync = actualFs.renameSync;
export const rmdirSync = actualFs.rmdirSync;
export const rmSync = actualFs.rmSync;
export const statSync = actualFs.statSync;
export const symlinkSync = actualFs.symlinkSync;
export const truncateSync = actualFs.truncateSync;
export const unlinkSync = actualFs.unlinkSync;
export const utimesSync = actualFs.utimesSync;
export const writeFileSync = actualFs.writeFileSync;
export const writeSync = actualFs.writeSync;
export const watch = actualFs.watch;
export const watchFile = actualFs.watchFile;
export const unwatchFile = actualFs.unwatchFile;
export const promises = actualFs.promises;
export const constants = actualFs.constants;
export const Stats = actualFs.Stats;
export const Dirent = actualFs.Dirent;
export const ReadStream = actualFs.ReadStream;
export const WriteStream = actualFs.WriteStream;
export const Dir = actualFs.Dir;
export const access = actualFs.access;
export const appendFile = actualFs.appendFile;
export const chmod = actualFs.chmod;
export const chown = actualFs.chown;
export const close = actualFs.close;
export const copyFile = actualFs.copyFile;
export const cp = actualFs.cp;
export const fchmod = actualFs.fchmod;
export const fchown = actualFs.fchown;
export const fdatasync = actualFs.fdatasync;
export const fstat = actualFs.fstat;
export const fsync = actualFs.fsync;
export const ftruncate = actualFs.ftruncate;
export const futimes = actualFs.futimes;
export const lchmod = actualFs.lchmod;
export const lchown = actualFs.lchown;
export const link = actualFs.link;
export const lstat = actualFs.lstat;
export const lutimes = actualFs.lutimes;
export const mkdir = actualFs.mkdir;
export const mkdtemp = actualFs.mkdtemp;
export const open = actualFs.open;
export const opendir = actualFs.opendir;
export const read = actualFs.read;
export const readdir = actualFs.readdir;
export const readFile = actualFs.readFile;
export const readlink = actualFs.readlink;
export const realpath = actualFs.realpath;
export const rename = actualFs.rename;
export const rm = actualFs.rm;
export const rmdir = actualFs.rmdir;
export const stat = actualFs.stat;
export const symlink = actualFs.symlink;
export const truncate = actualFs.truncate;
export const unlink = actualFs.unlink;
export const utimes = actualFs.utimes;
export const write = actualFs.write;
export const writev = actualFs.writev;
export const readv = actualFs.readv;

// Override existsSync with our mock
export default {
...actualFs,
// Don't mock readFileSync - let it use the real implementation
// Tests that need to mock it can do so explicitly
existsSync: jest.fn(() => true),
existsSync,
};
31 changes: 25 additions & 6 deletions src/__mocks__/logger.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const consola = require('consola');
import { vi } from 'vitest';

const loggerModule: typeof consola = jest.genMockFromModule('../logger');
export const logger = {
trace: vi.fn(),
debug: vi.fn(),
info: vi.fn(),
log: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
success: vi.fn(),
withScope: vi.fn().mockReturnThis(),
pause: vi.fn(),
resume: vi.fn(),
};

loggerModule.logger.withScope = function (): any {
return this;
export const LogLevel = {
Fatal: 0,
Error: 0,
Warn: 1,
Log: 2,
Info: 3,
Success: 3,
Debug: 4,
Trace: 5,
Silent: -Infinity,
Verbose: Infinity,
};

module.exports = loggerModule;
export const setLevel = vi.fn();
Loading
Loading