Merge pull request #481 from crazy-max/esm

switch to ESM and update config/test wiring
This commit is contained in:
CrazyMax
2026-03-03 13:49:55 +01:00
committed by GitHub
17 changed files with 1288 additions and 3629 deletions

View File

@@ -6,6 +6,5 @@
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid",
"parser": "typescript"
"arrowParens": "avoid"
}

View File

@@ -1,38 +1,40 @@
import {beforeEach, describe, expect, jest, test} from '@jest/globals';
import {beforeEach, describe, expect, test, vi} from 'vitest';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
import {Context} from '@docker/actions-toolkit/lib/context';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Node} from '@docker/actions-toolkit/lib/types/buildx/builder';
import * as context from '../src/context';
const fixturesDir = path.join(__dirname, 'fixtures');
// prettier-ignore
const tmpDir = path.join(process.env.TEMP || '/tmp', 'setup-buildx-jest');
const tmpName = path.join(tmpDir, '.tmpname-jest');
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'context-'));
const tmpName = path.join(tmpDir, '.tmpname-vi');
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
vi.spyOn(Context, 'tmpDir').mockImplementation((): string => {
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir, {recursive: true});
}
return tmpDir;
});
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
vi.spyOn(Context, 'tmpName').mockImplementation((): string => {
return tmpName;
});
jest.mock('crypto', () => {
vi.mock('crypto', async () => {
return {
...(jest.requireActual('crypto') as object),
randomUUID: jest.fn(() => '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d')
...(await vi.importActual('crypto')),
randomUUID: vi.fn(() => '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d')
};
});
jest.spyOn(Docker, 'context').mockImplementation((): Promise<string> => {
vi.spyOn(Docker, 'context').mockImplementation((): Promise<string> => {
return Promise.resolve('default');
});
@@ -298,13 +300,13 @@ describe('getCreateArgs', () => {
]
],
])(
'[%d] given buildx %s and %p as inputs, returns %p',
'[%d] given buildx %o and %o as inputs, returns %o',
async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
inputs.forEach((value: string, name: string) => {
setInput(name, value);
});
const toolkit = new Toolkit();
jest.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => {
vi.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => {
return buildxVersion;
});
const inp = await context.getInputs();
@@ -357,13 +359,13 @@ describe('getAppendArgs', () => {
]
]
])(
'[%d] given buildx %s and %p as inputs, returns %p',
'[%d] given buildx %o and %o as inputs, returns %o',
async (num: number, buildxVersion: string, inputs: Map<string, string>, node: Node, expected: Array<string>) => {
inputs.forEach((value: string, name: string) => {
setInput(name, value);
});
const toolkit = new Toolkit();
jest.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => {
vi.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => {
return buildxVersion;
});
const inp = await context.getInputs();
@@ -505,7 +507,7 @@ describe('getVersion', () => {
'cloud:v0.11.2-desktop.2'
],
])(
'[%d] given %p as inputs, returns version %p',
'[%d] given %o as inputs, returns version %o',
async (num: number, inputs: Map<string, string>, expected: string) => {
inputs.forEach((value: string, name: string) => {
setInput(name, value);

12
__tests__/setup.unit.ts Normal file
View File

@@ -0,0 +1,12 @@
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-action-'));
process.env = Object.assign({}, process.env, {
TEMP: tmpDir,
GITHUB_REPOSITORY: 'docker/setup-buildx-action',
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
});

View File

@@ -3,10 +3,11 @@
ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
RUN apk add --no-cache cpio findutils git rsync
WORKDIR /src
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache <<EOT
set -e
corepack enable
yarn --version
yarn config set --home enableTelemetry 0
@@ -34,18 +35,27 @@ RUN --mount=type=bind,target=.,rw <<EOT
EOT
FROM deps AS build
RUN --mount=type=bind,target=.,rw \
RUN --mount=target=/context \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn run build && mkdir /out && cp -Rf dist /out/
--mount=type=cache,target=/src/node_modules <<EOT
set -e
rsync -a /context/. .
rm -rf dist
yarn run build
mkdir /out
cp -r dist /out
EOT
FROM scratch AS build-update
COPY --from=build /out /
FROM build AS build-validate
RUN --mount=type=bind,target=.,rw <<EOT
RUN --mount=target=/context \
--mount=target=.,type=tmpfs <<EOT
set -e
rsync -a /context/. .
git add -A
rm -rf dist
cp -rf /out/* .
if [ -n "$(git status --porcelain -- dist)" ]; then
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
@@ -58,8 +68,7 @@ FROM deps AS format
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn run format \
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out
yarn run format && mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out
FROM scratch AS format-update
COPY --from=format /out /
@@ -74,7 +83,7 @@ FROM deps AS test
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/.yarn/cache \
--mount=type=cache,target=/src/node_modules \
yarn run test --coverage --coverageDirectory=/tmp/coverage
yarn run test --coverage --coverage.reportsDirectory=/tmp/coverage
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage /

32
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

3
dist/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@@ -1,58 +0,0 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const {defineConfig, globalIgnores} = require('eslint/config');
const {fixupConfigRules, fixupPluginRules} = require('@eslint/compat');
const typescriptEslint = require('@typescript-eslint/eslint-plugin');
const jestPlugin = require('eslint-plugin-jest');
const prettier = require('eslint-plugin-prettier');
const globals = require('globals');
const tsParser = require('@typescript-eslint/parser');
const js = require('@eslint/js');
const {FlatCompat} = require('@eslint/eslintrc');
// __dirname and __filename exist natively in CommonJS
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});
module.exports = defineConfig([
globalIgnores(['dist/**/*', 'coverage/**/*', 'node_modules/**/*']),
{
// prettier-ignore
extends: fixupConfigRules(
compat.extends(
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:jest/recommended',
'plugin:prettier/recommended'
)
),
plugins: {
'@typescript-eslint': fixupPluginRules(typescriptEslint),
jest: fixupPluginRules(jestPlugin),
prettier: fixupPluginRules(prettier)
},
languageOptions: {
globals: {
...globals.node,
...globals.jest
},
parser: tsParser,
ecmaVersion: 'latest',
sourceType: 'module'
},
rules: {
'@typescript-eslint/no-require-imports': [
'error',
{
allowAsImport: true
}
]
}
}
]);

52
eslint.config.mjs Normal file
View File

@@ -0,0 +1,52 @@
import {defineConfig} from 'eslint/config';
import js from '@eslint/js';
import tseslint from '@typescript-eslint/eslint-plugin';
import vitest from '@vitest/eslint-plugin';
import globals from 'globals';
import eslintConfigPrettier from 'eslint-config-prettier/flat';
import eslintPluginPrettier from 'eslint-plugin-prettier';
export default defineConfig([
{
ignores: ['.yarn/**/*', 'coverage/**/*', 'dist/**/*']
},
js.configs.recommended,
...tseslint.configs['flat/recommended'],
eslintConfigPrettier,
{
languageOptions: {
globals: {
...globals.node
}
}
},
{
files: ['__tests__/**'],
...vitest.configs.recommended,
languageOptions: {
globals: {
...globals.node,
...vitest.environments.env.globals
}
},
rules: {
...vitest.configs.recommended.rules,
'vitest/no-conditional-expect': 'error',
'vitest/no-disabled-tests': 0
}
},
{
plugins: {
prettier: eslintPluginPrettier
},
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/no-require-imports': [
'error',
{
allowAsImport: true
}
]
}
}
]);

View File

@@ -1,29 +0,0 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs');
const os = require('os');
const path = require('path');
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-buildx-action-'));
process.env = Object.assign({}, process.env, {
TEMP: tmpDir,
GITHUB_REPOSITORY: 'docker/setup-buildx-action',
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
});
module.exports = {
clearMocks: true,
testEnvironment: 'node',
moduleFileExtensions: ['js', 'ts'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
},
moduleNameMapper: {
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
},
collectCoverageFrom: ['src/**/{!(main.ts),}.ts'],
coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__mocks__/', '__tests__/'],
verbose: true
};

View File

@@ -1,16 +1,13 @@
{
"name": "docker-setup-buildx",
"description": "Set up Docker Buildx",
"type": "module",
"main": "src/main.ts",
"scripts": {
"build": "ncc build --source-map --minify --license licenses.txt",
"lint": "yarn run prettier && yarn run eslint",
"format": "yarn run prettier:fix && yarn run eslint:fix",
"eslint": "eslint --max-warnings=0 .",
"eslint:fix": "eslint --fix .",
"prettier": "prettier --check \"./**/*.ts\"",
"prettier:fix": "prettier --write \"./**/*.ts\"",
"test": "jest"
"lint": "eslint --max-warnings=0 .",
"format": "eslint --fix .",
"test": "vitest run"
},
"repository": {
"type": "git",
@@ -30,22 +27,20 @@
"js-yaml": "^4.1.0"
},
"devDependencies": {
"@eslint/compat": "^2.0.0",
"@eslint/eslintrc": "^3.3.3",
"@eslint/js": "^9.39.2",
"@eslint/js": "^9.39.3",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.19.27",
"@typescript-eslint/eslint-plugin": "^8.50.0",
"@typescript-eslint/parser": "^8.50.0",
"@types/node": "^20.19.35",
"@typescript-eslint/eslint-plugin": "^8.56.1",
"@typescript-eslint/parser": "^8.56.1",
"@vercel/ncc": "^0.38.4",
"eslint": "^9.39.2",
"@vitest/coverage-v8": "^4.0.18",
"@vitest/eslint-plugin": "^1.6.9",
"eslint": "^9.39.3",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jest": "^29.5.0",
"eslint-plugin-prettier": "^5.5.4",
"jest": "^30.2.0",
"prettier": "^3.7.4",
"ts-jest": "^29.4.6",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
"eslint-plugin-prettier": "^5.5.5",
"globals": "^17.3.0",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"vitest": "^4.0.18"
}
}

View File

@@ -1,11 +1,11 @@
import * as crypto from 'crypto';
import * as core from '@actions/core';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Util} from '@docker/actions-toolkit/lib/util';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker.js';
import {Util} from '@docker/actions-toolkit/lib/util.js';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit.js';
import {Node} from '@docker/actions-toolkit/lib/types/buildx/builder';
import {Node} from '@docker/actions-toolkit/lib/types/buildx/builder.js';
export const builderNodeEnvPrefix = 'BUILDER_NODE';
const defaultBuildkitdFlags = '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host';

View File

@@ -4,18 +4,18 @@ import * as yaml from 'js-yaml';
import * as core from '@actions/core';
import * as actionsToolkit from '@docker/actions-toolkit';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
import {Builder} from '@docker/actions-toolkit/lib/buildx/builder';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Exec} from '@docker/actions-toolkit/lib/exec';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {Util} from '@docker/actions-toolkit/lib/util';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js';
import {Builder} from '@docker/actions-toolkit/lib/buildx/builder.js';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker.js';
import {Exec} from '@docker/actions-toolkit/lib/exec.js';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit.js';
import {Util} from '@docker/actions-toolkit/lib/util.js';
import {Node} from '@docker/actions-toolkit/lib/types/buildx/builder';
import {ContextInfo} from '@docker/actions-toolkit/lib/types/docker/docker';
import {Node} from '@docker/actions-toolkit/lib/types/buildx/builder.js';
import {ContextInfo} from '@docker/actions-toolkit/lib/types/docker/docker.js';
import * as context from './context';
import * as stateHelper from './state-helper';
import * as context from './context.js';
import * as stateHelper from './state-helper.js';
actionsToolkit.run(
// main

View File

@@ -1,9 +1,8 @@
{
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "nodenext",
"esModuleInterop": true,
"target": "es6",
"module": "commonjs",
"strict": true,
"newLine": "lf",
"outDir": "./lib",
"rootDir": "./src",
@@ -12,10 +11,7 @@
"resolveJsonModule": true,
"useUnknownInCatchVariables": false,
},
"exclude": [
"./__tests__/**/*",
"./lib/**/*",
"node_modules",
"jest.config.ts"
"include": [
"src/**/*.ts"
]
}

16
vitest.config.ts Normal file
View File

@@ -0,0 +1,16 @@
import {defineConfig} from 'vitest/config';
export default defineConfig({
test: {
clearMocks: true,
environment: 'node',
setupFiles: ['./__tests__/setup.unit.ts'],
include: ['**/*.test.ts'],
coverage: {
provider: 'v8',
reporter: ['clover'],
include: ['src/**/*.ts'],
exclude: ['src/**/main.ts']
}
}
});

4576
yarn.lock

File diff suppressed because it is too large Load Diff