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
with:
file: ./test/Dockerfile
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
git-context:
runs-on: ubuntu-latest
@ -77,10 +73,6 @@ jobs:
echo "::error::Digest should not be empty"
exit 1
fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
git-context-secret:
runs-on: ubuntu-latest
@ -137,10 +129,6 @@ jobs:
echo "::error::Digest should not be empty"
exit 1
fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
path-context:
runs-on: ubuntu-latest
@ -192,10 +180,6 @@ jobs:
echo "::error::Digest should not be empty"
exit 1
fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
error:
runs-on: ubuntu-latest
@ -223,10 +207,6 @@ jobs:
echo "::error::Should have failed"
exit 1
fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
error-buildx:
runs-on: ubuntu-latest
@ -259,10 +239,6 @@ jobs:
echo "::error::Should have failed"
exit 1
fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
docker-driver:
runs-on: ubuntu-latest
@ -284,10 +260,6 @@ jobs:
file: ./test/Dockerfile
push: true
tags: localhost:5000/name/app:latest
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
export-docker:
runs-on: ubuntu-latest
@ -307,10 +279,6 @@ jobs:
name: Inspect
run: |
docker image inspect myimage:latest
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
network:
runs-on: ubuntu-latest
@ -331,10 +299,6 @@ jobs:
context: ./test
tags: name/app:latest
network: host
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
shm-size:
runs-on: ubuntu-latest
@ -357,10 +321,6 @@ jobs:
file: ./test/shmsize.Dockerfile
tags: name/app:latest
shm-size: 2g
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
ulimit:
runs-on: ubuntu-latest
@ -385,10 +345,6 @@ jobs:
ulimit: |
nofile=1024:1024
nproc=3
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
cgroup-parent:
runs-on: ubuntu-latest
@ -411,10 +367,6 @@ jobs:
file: ./test/cgroup.Dockerfile
tags: name/app:latest
cgroup-parent: foo
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
add-hosts:
runs-on: ubuntu-latest
@ -435,10 +387,6 @@ jobs:
add-hosts: |
docker:10.180.0.1
foo:10.0.0.1
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
multi:
runs-on: ubuntu-latest
@ -494,10 +442,94 @@ jobs:
echo "::error::Digest should not be empty"
exit 1
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
if: always()
uses: crazy-max/ghaction-dump-context@v1
name: Checkout
uses: actions/checkout@v2
-
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:
runs-on: ubuntu-latest
@ -584,10 +616,6 @@ jobs:
echo "::error::Digests should be identical"
exit 1
fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
local-cache-first:
runs-on: ubuntu-latest
@ -650,10 +678,6 @@ jobs:
echo "::error::Digest should not be empty"
exit 1
fi
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
local-cache-hit:
runs-on: ubuntu-latest
@ -723,10 +747,6 @@ jobs:
-
name: Cache hit
run: echo ${{ steps.cache.outputs.cache-hit }}
-
name: Dump context
if: always()
uses: crazy-max/ghaction-dump-context@v1
github-cache:
runs-on: ubuntu-latest
@ -773,7 +793,3 @@ jobs:
name: Inspect
run: |
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 |
|-------------------|---------|---------------------------------------|
| `digest` | String | Image content-addressable identifier also called a digest |
| `imageid` | String | Image ID |
| `digest` | String | Image digest |
| `metadata` | JSON | Build result metadata |
## Troubleshooting

@ -7,7 +7,7 @@ import * as buildx from '../src/buildx';
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 digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
const metadata = `{
"containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd",
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
@ -28,9 +28,9 @@ jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
describe('getImageID', () => {
it('matches', async () => {
const imageIDFile = await buildx.getImageIDFile();
await fs.writeFileSync(imageIDFile, digest);
const imageID = await buildx.getImageID();
expect(imageID).toEqual(digest);
await fs.writeFileSync(imageIDFile, imageID);
const expected = await buildx.getImageID();
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', () => {
// prettier-ignore
test.each([

@ -89,8 +89,10 @@ inputs:
required: false
outputs:
imageid:
description: 'Image ID'
digest:
description: 'Image content-addressable identifier also called a digest'
description: 'Image digest'
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 };
};
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 fs_1 = __importDefault(__nccwpck_require__(5747));
const path_1 = __importDefault(__nccwpck_require__(5622));
@ -81,6 +81,19 @@ function 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) {
return __awaiter(this, void 0, void 0, function* () {
return getSecret(kvp, false);
@ -517,15 +530,22 @@ function run() {
}
});
const imageID = yield buildx.getImageID();
const metadata = yield buildx.getMetadata();
const digest = yield buildx.getDigest(metadata);
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);
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) {
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);
context.setOutput('metadata', metadata);
}));

@ -34,6 +34,17 @@ export async function getMetadata(): Promise<string | undefined> {
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> {
return getSecret(kvp, false);
}

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