Merge pull request #569 from crazy-max/imageid-digest

add imageid output and use metadata to set digest output
This commit is contained in:
CrazyMax 2022-03-14 20:03:35 +01:00 committed by GitHub
commit e115266953
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 153 additions and 87 deletions

@ -26,10 +26,6 @@ jobs:
uses: ./action uses: ./action
with: with:
file: ./test/Dockerfile file: ./test/Dockerfile
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
git-context: git-context:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -77,10 +73,6 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
git-context-secret: git-context-secret:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -137,10 +129,6 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
path-context: path-context:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -192,10 +180,6 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
error: error:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -223,10 +207,6 @@ jobs:
echo "::error::Should have failed" echo "::error::Should have failed"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
error-buildx: error-buildx:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -259,10 +239,6 @@ jobs:
echo "::error::Should have failed" echo "::error::Should have failed"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
docker-driver: docker-driver:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -284,10 +260,6 @@ jobs:
file: ./test/Dockerfile file: ./test/Dockerfile
push: true push: true
tags: localhost:5000/name/app:latest tags: localhost:5000/name/app:latest
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
export-docker: export-docker:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -307,10 +279,6 @@ jobs:
name: Inspect name: Inspect
run: | run: |
docker image inspect myimage:latest docker image inspect myimage:latest
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
network: network:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -331,10 +299,6 @@ jobs:
context: ./test context: ./test
tags: name/app:latest tags: name/app:latest
network: host network: host
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
shm-size: shm-size:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -357,10 +321,6 @@ jobs:
file: ./test/shmsize.Dockerfile file: ./test/shmsize.Dockerfile
tags: name/app:latest tags: name/app:latest
shm-size: 2g shm-size: 2g
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
ulimit: ulimit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -385,10 +345,6 @@ jobs:
ulimit: | ulimit: |
nofile=1024:1024 nofile=1024:1024
nproc=3 nproc=3
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
cgroup-parent: cgroup-parent:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -411,10 +367,6 @@ jobs:
file: ./test/cgroup.Dockerfile file: ./test/cgroup.Dockerfile
tags: name/app:latest tags: name/app:latest
cgroup-parent: foo cgroup-parent: foo
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
add-hosts: add-hosts:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -435,10 +387,6 @@ jobs:
add-hosts: | add-hosts: |
docker:10.180.0.1 docker:10.180.0.1
foo:10.0.0.1 foo:10.0.0.1
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
multi: multi:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -494,10 +442,94 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
digest:
runs-on: ubuntu-latest
env:
DOCKER_IMAGE: localhost:5000/name/app
strategy:
fail-fast: false
matrix:
driver:
- docker
- docker-container
load:
- true
- false
push:
- true
- false
exclude:
- driver: docker
load: true
push: true
- driver: docker-container
load: true
push: true
- driver: docker
load: false
push: false
- driver: docker-container
load: false
push: false
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- -
name: Dump context name: Checkout
if: always() uses: actions/checkout@v2
uses: crazy-max/ghaction-dump-context@v1 -
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
version: v0.8.0
driver: ${{ matrix.driver }}
driver-opts: |
network=host
-
name: Build
id: docker_build
uses: ./
with:
context: ./test
load: ${{ matrix.load }}
push: ${{ matrix.push }}
tags: ${{ env.DOCKER_IMAGE }}:latest
platforms: ${{ matrix.platforms }}
-
name: Docker images
run: |
docker image ls --no-trunc
-
name: Check digest
if: ${{ matrix.push }}
run: |
if [ -z "${{ steps.docker_build.outputs.digest }}" ]; then
echo "::error::Digest should not be empty"
exit 1
fi
-
name: Check manifest
if: ${{ matrix.push }}
run: |
set -x
docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}@${{ steps.docker_build.outputs.digest }} --format '{{json .}}'
-
name: Check image ID
run: |
if [ -z "${{ steps.docker_build.outputs.imageid }}" ]; then
echo "::error::Image ID should not be empty"
exit 1
fi
-
name: Inspect image
if: ${{ matrix.load }}
run: |
set -x
docker image inspect ${{ steps.docker_build.outputs.imageid }}
registry-cache: registry-cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -584,10 +616,6 @@ jobs:
echo "::error::Digests should be identical" echo "::error::Digests should be identical"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
local-cache-first: local-cache-first:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -650,10 +678,6 @@ jobs:
echo "::error::Digest should not be empty" echo "::error::Digest should not be empty"
exit 1 exit 1
fi fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
local-cache-hit: local-cache-hit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -723,10 +747,6 @@ jobs:
- -
name: Cache hit name: Cache hit
run: echo ${{ steps.cache.outputs.cache-hit }} run: echo ${{ steps.cache.outputs.cache-hit }}
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
github-cache: github-cache:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -773,7 +793,3 @@ jobs:
name: Inspect name: Inspect
run: | run: |
docker buildx imagetools inspect localhost:5000/name/app:1.0.0 docker buildx imagetools inspect localhost:5000/name/app:1.0.0
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1

@ -241,7 +241,8 @@ Following outputs are available
| Name | Type | Description | | Name | Type | Description |
|-------------------|---------|---------------------------------------| |-------------------|---------|---------------------------------------|
| `digest` | String | Image content-addressable identifier also called a digest | | `imageid` | String | Image ID |
| `digest` | String | Image digest |
| `metadata` | JSON | Build result metadata | | `metadata` | JSON | Build result metadata |
## Troubleshooting ## Troubleshooting

@ -7,7 +7,7 @@ import * as buildx from '../src/buildx';
import * as context from '../src/context'; import * as context from '../src/context';
const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
const digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9'; const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
const metadata = `{ const metadata = `{
"containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd", "containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd",
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c" "containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
@ -28,9 +28,9 @@ jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
describe('getImageID', () => { describe('getImageID', () => {
it('matches', async () => { it('matches', async () => {
const imageIDFile = await buildx.getImageIDFile(); const imageIDFile = await buildx.getImageIDFile();
await fs.writeFileSync(imageIDFile, digest); await fs.writeFileSync(imageIDFile, imageID);
const imageID = await buildx.getImageID(); const expected = await buildx.getImageID();
expect(imageID).toEqual(digest); expect(expected).toEqual(imageID);
}); });
}); });
@ -43,6 +43,15 @@ describe('getMetadata', () => {
}); });
}); });
describe('getDigest', () => {
it('matches', async () => {
const metadataFile = await buildx.getMetadataFile();
await fs.writeFileSync(metadataFile, metadata);
const expected = await buildx.getDigest(metadata);
expect(expected).toEqual('sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c');
});
});
describe('isLocalOrTarExporter', () => { describe('isLocalOrTarExporter', () => {
// prettier-ignore // prettier-ignore
test.each([ test.each([

@ -89,8 +89,10 @@ inputs:
required: false required: false
outputs: outputs:
imageid:
description: 'Image ID'
digest: digest:
description: 'Image content-addressable identifier also called a digest' description: 'Image digest'
metadata: metadata:
description: 'Build result metadata' description: 'Build result metadata'

30
dist/index.js generated vendored

@ -38,7 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.satisfies = exports.parseVersion = exports.getVersion = exports.isAvailable = exports.hasGitAuthToken = exports.isLocalOrTarExporter = exports.getSecret = exports.getSecretFile = exports.getSecretString = exports.getMetadata = exports.getMetadataFile = exports.getImageID = exports.getImageIDFile = void 0; exports.satisfies = exports.parseVersion = exports.getVersion = exports.isAvailable = exports.hasGitAuthToken = exports.isLocalOrTarExporter = exports.getSecret = exports.getSecretFile = exports.getSecretString = exports.getDigest = exports.getMetadata = exports.getMetadataFile = exports.getImageID = exports.getImageIDFile = void 0;
const sync_1 = __importDefault(__nccwpck_require__(8750)); const sync_1 = __importDefault(__nccwpck_require__(8750));
const fs_1 = __importDefault(__nccwpck_require__(5747)); const fs_1 = __importDefault(__nccwpck_require__(5747));
const path_1 = __importDefault(__nccwpck_require__(5622)); const path_1 = __importDefault(__nccwpck_require__(5622));
@ -81,6 +81,19 @@ function getMetadata() {
}); });
} }
exports.getMetadata = getMetadata; exports.getMetadata = getMetadata;
function getDigest(metadata) {
return __awaiter(this, void 0, void 0, function* () {
if (metadata === undefined) {
return undefined;
}
const metadataJSON = JSON.parse(metadata);
if (metadataJSON['containerimage.digest']) {
return metadataJSON['containerimage.digest'];
}
return undefined;
});
}
exports.getDigest = getDigest;
function getSecretString(kvp) { function getSecretString(kvp) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return getSecret(kvp, false); return getSecret(kvp, false);
@ -517,15 +530,22 @@ function run() {
} }
}); });
const imageID = yield buildx.getImageID(); const imageID = yield buildx.getImageID();
const metadata = yield buildx.getMetadata();
const digest = yield buildx.getDigest(metadata);
if (imageID) { if (imageID) {
yield core.group(`Digest output`, () => __awaiter(this, void 0, void 0, function* () { yield core.group(`ImageID`, () => __awaiter(this, void 0, void 0, function* () {
core.info(imageID); core.info(imageID);
context.setOutput('digest', imageID); context.setOutput('imageid', imageID);
}));
}
if (digest) {
yield core.group(`Digest`, () => __awaiter(this, void 0, void 0, function* () {
core.info(digest);
context.setOutput('digest', digest);
})); }));
} }
const metadata = yield buildx.getMetadata();
if (metadata) { if (metadata) {
yield core.group(`Metadata output`, () => __awaiter(this, void 0, void 0, function* () { yield core.group(`Metadata`, () => __awaiter(this, void 0, void 0, function* () {
core.info(metadata); core.info(metadata);
context.setOutput('metadata', metadata); context.setOutput('metadata', metadata);
})); }));

@ -34,6 +34,17 @@ export async function getMetadata(): Promise<string | undefined> {
return content; return content;
} }
export async function getDigest(metadata: string | undefined): Promise<string | undefined> {
if (metadata === undefined) {
return undefined;
}
const metadataJSON = JSON.parse(metadata);
if (metadataJSON['containerimage.digest']) {
return metadataJSON['containerimage.digest'];
}
return undefined;
}
export async function getSecretString(kvp: string): Promise<string> { export async function getSecretString(kvp: string): Promise<string> {
return getSecret(kvp, false); return getSecret(kvp, false);
} }

@ -34,16 +34,23 @@ async function run(): Promise<void> {
}); });
const imageID = await buildx.getImageID(); const imageID = await buildx.getImageID();
const metadata = await buildx.getMetadata();
const digest = await buildx.getDigest(metadata);
if (imageID) { if (imageID) {
await core.group(`Digest output`, async () => { await core.group(`ImageID`, async () => {
core.info(imageID); core.info(imageID);
context.setOutput('digest', imageID); context.setOutput('imageid', imageID);
});
}
if (digest) {
await core.group(`Digest`, async () => {
core.info(digest);
context.setOutput('digest', digest);
}); });
} }
const metadata = await buildx.getMetadata();
if (metadata) { if (metadata) {
await core.group(`Metadata output`, async () => { await core.group(`Metadata`, async () => {
core.info(metadata); core.info(metadata);
context.setOutput('metadata', metadata); context.setOutput('metadata', metadata);
}); });