mirror of
https://github.com/docker/build-push-action.git
synced 2024-08-26 22:47:13 -04:00
add imageid output and use metadata to set digest output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
parent
fe02965b48
commit
50fa0058d9
7 changed files with 153 additions and 87 deletions
158
.github/workflows/ci.yml
vendored
158
.github/workflows/ci.yml
vendored
|
@ -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
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);
|
||||
}
|
||||
|
|
17
src/main.ts
17
src/main.ts
|
@ -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);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue