69 changes: 69 additions & 0 deletions dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# syntax=docker/dockerfile:1

ARG NODE_VERSION=16

FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
WORKDIR /src

FROM base AS deps
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn install && mkdir /vendor && cp yarn.lock /vendor

FROM scratch AS vendor-update
COPY --from=deps /vendor /

FROM deps AS vendor-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /vendor/* .
if [ -n "$(git status --porcelain -- yarn.lock)" ]; then
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor-update"'
git status --porcelain -- yarn.lock
exit 1
fi
EOT

FROM deps AS build
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run build && mkdir /out && cp -Rf dist /out/

FROM scratch AS build-update
COPY --from=build /out /

FROM build AS build-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /out/* .
if [ -n "$(git status --porcelain -- dist)" ]; then
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
git status --porcelain -- dist
exit 1
fi
EOT

FROM deps AS format
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run format \
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out

FROM scratch AS format-update
COPY --from=format /out /

FROM deps AS lint
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run lint

FROM deps AS test
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
yarn run test --coverageDirectory=/tmp/coverage

FROM scratch AS test-coverage
COPY --from=test /tmp/coverage /
1,864 changes: 2 additions & 1,862 deletions dist/index.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/index.js.map

Large diffs are not rendered by default.

317 changes: 317 additions & 0 deletions dist/licenses.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/sourcemap-register.js

Large diffs are not rendered by default.

47 changes: 20 additions & 27 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
variable "NODE_VERSION" {
default = "12"
}

target "node-version" {
args = {
NODE_VERSION = NODE_VERSION
}
}

group "default" {
targets = ["build"]
}
Expand All @@ -17,44 +7,47 @@ group "pre-checkin" {
}

group "validate" {
targets = ["format-validate", "build-validate", "vendor-validate"]
targets = ["lint", "build-validate", "vendor-validate"]
}

target "build" {
inherits = ["node-version"]
dockerfile = "./hack/build.Dockerfile"
dockerfile = "dev.Dockerfile"
target = "build-update"
output = ["."]
}

target "build-validate" {
inherits = ["node-version"]
dockerfile = "./hack/build.Dockerfile"
dockerfile = "dev.Dockerfile"
target = "build-validate"
output = ["type=cacheonly"]
}

target "format" {
inherits = ["node-version"]
dockerfile = "./hack/build.Dockerfile"
dockerfile = "dev.Dockerfile"
target = "format-update"
output = ["."]
}

target "format-validate" {
inherits = ["node-version"]
dockerfile = "./hack/build.Dockerfile"
target = "format-validate"
target "lint" {
dockerfile = "dev.Dockerfile"
target = "lint"
output = ["type=cacheonly"]
}

target "vendor-update" {
inherits = ["node-version"]
dockerfile = "./hack/vendor.Dockerfile"
target = "update"
dockerfile = "dev.Dockerfile"
target = "vendor-update"
output = ["."]
}

target "vendor-validate" {
inherits = ["node-version"]
dockerfile = "./hack/vendor.Dockerfile"
target = "validate"
dockerfile = "dev.Dockerfile"
target = "vendor-validate"
output = ["type=cacheonly"]
}

target "test" {
dockerfile = "dev.Dockerfile"
target = "test-coverage"
output = ["./coverage"]
}
42 changes: 0 additions & 42 deletions hack/build.Dockerfile

This file was deleted.

23 changes: 0 additions & 23 deletions hack/vendor.Dockerfile

This file was deleted.

29 changes: 29 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import fs from 'fs';
import os from 'os';
import path from 'path';

const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-setup-qemu-action-'));

process.env = Object.assign({}, process.env, {
TEMP: tmpDir,
GITHUB_REPOSITORY: 'docker/setup-qemu-action',
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
}) as {
[key: string]: string;
};

module.exports = {
clearMocks: true,
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
};
31 changes: 20 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
"description": "Install QEMU static binaries",
"main": "lib/main.js",
"scripts": {
"build": "tsc && ncc build",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"pre-checkin": "yarn run format && yarn run build"
"build": "ncc build src/main.ts --source-map --minify --license licenses.txt",
"lint": "eslint src/**/*.ts __tests__/**/*.ts",
"format": "eslint --fix src/**/*.ts __tests__/**/*.ts",
"test": "jest --coverage",
"all": "yarn run build && yarn run format && yarn test"
},
"repository": {
"type": "git",
Expand All @@ -26,14 +27,22 @@
],
"license": "Apache-2.0",
"dependencies": {
"@actions/core": "^1.3.0",
"@actions/exec": "^1.0.4"
"@actions/core": "^1.10.0",
"@docker/actions-toolkit": "^0.3.0"
},
"devDependencies": {
"@types/node": "^14.0.14",
"@vercel/ncc": "^0.23.0",
"prettier": "^2.0.5",
"typescript": "^3.9.5",
"typescript-formatter": "^7.2.2"
"@types/node": "^16.18.21",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"@vercel/ncc": "^0.36.1",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.5.0",
"prettier": "^2.8.7",
"ts-jest": "^29.0.5",
"ts-node": "^10.9.1",
"typescript": "^4.9.5"
}
}
14 changes: 14 additions & 0 deletions src/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as core from '@actions/core';
import {Util} from '@docker/actions-toolkit/lib/util';

export interface Inputs {
image: string;
platforms: string;
}

export function getInputs(): Inputs {
return {
image: core.getInput('image') || 'tonistiigi/binfmt:latest',
platforms: Util.getInputList('platforms').join(',') || 'all'
};
}
34 changes: 0 additions & 34 deletions src/exec.ts

This file was deleted.

73 changes: 34 additions & 39 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,48 @@
import * as mexec from './exec';
import * as context from './context';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import {issueCommand} from '@actions/core/lib/command';
import * as actionsToolkit from '@docker/actions-toolkit';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import {Exec} from '@docker/actions-toolkit/lib/exec';

interface Platforms {
supported: string[];
available: string[];
}

async function run(): Promise<void> {
try {
core.startGroup(`Docker info`);
await exec.exec('docker', ['version']);
await exec.exec('docker', ['info']);
core.endGroup();
actionsToolkit.run(
// main
async () => {
const input: context.Inputs = context.getInputs();

const image: string = core.getInput('image') || 'tonistiigi/binfmt:latest';
const platforms: string = core.getInput('platforms') || 'all';
await core.group(`Docker info`, async () => {
await Docker.printVersion();
await Docker.printInfo();
});

core.startGroup(`Pulling binfmt Docker image`);
await exec.exec('docker', ['pull', image]);
core.endGroup();
await core.group(`Pulling binfmt Docker image`, async () => {
await Exec.exec('docker', ['pull', input.image]);
});

core.startGroup(`Image info`);
await exec.exec('docker', ['image', 'inspect', image]);
core.endGroup();
await core.group(`Image info`, async () => {
await Exec.exec('docker', ['image', 'inspect', input.image]);
});

core.startGroup(`Installing QEMU static binaries`);
await exec.exec('docker', ['run', '--rm', '--privileged', image, '--install', platforms]);
core.endGroup();
await core.group(`Installing QEMU static binaries`, async () => {
await Exec.exec('docker', ['run', '--rm', '--privileged', input.image, '--install', input.platforms]);
});

core.startGroup(`Extracting available platforms`);
await mexec.exec(`docker`, ['run', '--rm', '--privileged', image], true).then(res => {
if (res.stderr != '' && !res.success) {
throw new Error(res.stderr);
}
const platforms: Platforms = JSON.parse(res.stdout.trim());
core.info(`${platforms.supported.join(',')}`);
setOutput('platforms', platforms.supported.join(','));
await core.group(`Extracting available platforms`, async () => {
await Exec.getExecOutput('docker', ['run', '--rm', '--privileged', input.image], {
ignoreReturnCode: true,
silent: true
}).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim());
}
const platforms: Platforms = JSON.parse(res.stdout.trim());
core.info(`${platforms.supported.join(',')}`);
core.setOutput('platforms', platforms.supported.join(','));
});
});
core.endGroup();
} catch (error) {
core.setFailed(error.message);
}
}

// FIXME: Temp fix https://github.com/actions/toolkit/issues/777
function setOutput(name: string, value: any): void {
issueCommand('set-output', {name}, value);
}

run();
);
19 changes: 11 additions & 8 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
{
"compilerOptions": {
"esModuleInterop": true,
"target": "es6",
"module": "commonjs",
"lib": [
"es6",
"dom"
],
"strict": true,
"newLine": "lf",
"outDir": "./lib",
"rootDir": "./src",
"strict": true,
"forceConsistentCasingInFileNames": true,
"noImplicitAny": false,
"esModuleInterop": true,
"sourceMap": true
"resolveJsonModule": true,
"useUnknownInCatchVariables": false,
},
"exclude": ["node_modules", "**/*.test.ts"]
"exclude": [
"./__tests__/**/*",
"./lib/**/*",
"node_modules",
"jest.config.ts"
]
}
3,465 changes: 3,395 additions & 70 deletions yarn.lock

Large diffs are not rendered by default.