Add metadata output
				
					
				
			Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									ad1d2e93be
								
							
						
					
					
						commit
						c0b121fe44
					
				
							
								
								
									
										24
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@ -70,9 +70,6 @@ jobs:
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -133,9 +130,6 @@ jobs:
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -191,9 +185,6 @@ jobs:
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -392,9 +383,6 @@ jobs:
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -447,9 +435,6 @@ jobs:
 | 
			
		||||
        name: Inspect (1)
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:latest
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest (1)
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest (1)
 | 
			
		||||
        run: |
 | 
			
		||||
@ -480,9 +465,6 @@ jobs:
 | 
			
		||||
        name: Inspect (2)
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:latest
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest (2)
 | 
			
		||||
        run: echo ${{ steps.docker_build2.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest (2)
 | 
			
		||||
        run: |
 | 
			
		||||
@ -557,9 +539,6 @@ jobs:
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -622,9 +601,6 @@ jobs:
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@ -100,9 +100,6 @@ jobs:
 | 
			
		||||
        with:
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: user/app:latest
 | 
			
		||||
      -
 | 
			
		||||
        name: Image digest
 | 
			
		||||
        run: echo ${{ steps.docker_build.outputs.digest }}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Building from the current repository automatically uses the [GitHub Token](https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token)
 | 
			
		||||
@ -223,9 +220,10 @@ Following inputs can be used as `step.with` keys
 | 
			
		||||
 | 
			
		||||
Following outputs are available
 | 
			
		||||
 | 
			
		||||
| Name          | Type    | Description                           |
 | 
			
		||||
|---------------|---------|---------------------------------------|
 | 
			
		||||
| `digest`      | String  | Image content-addressable identifier also called a digest |
 | 
			
		||||
| Name              | Type    | Description                           |
 | 
			
		||||
|-------------------|---------|---------------------------------------|
 | 
			
		||||
| `digest`          | String  | Image content-addressable identifier also called a digest |
 | 
			
		||||
| `metadata`        | JSON    | Build result metadata |
 | 
			
		||||
 | 
			
		||||
## Troubleshooting
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,10 @@ 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 metadata = `{
 | 
			
		||||
  "containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd",
 | 
			
		||||
  "containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
 | 
			
		||||
}`;
 | 
			
		||||
 | 
			
		||||
jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
 | 
			
		||||
  const tmpDir = path.join('/tmp/.docker-build-push-jest').split(path.sep).join(path.posix.sep);
 | 
			
		||||
@ -32,6 +36,17 @@ describe('getImageID', () => {
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('getMetadata', () => {
 | 
			
		||||
  it('matches', async () => {
 | 
			
		||||
    const metadataFile = await buildx.getMetadataFile();
 | 
			
		||||
    console.log(`metadataFile: ${metadataFile}`);
 | 
			
		||||
    await fs.writeFileSync(metadataFile, metadata);
 | 
			
		||||
    const expected = await buildx.getMetadata();
 | 
			
		||||
    console.log(`metadata: ${expected}`);
 | 
			
		||||
    expect(expected).toEqual(metadata);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('isLocalOrTarExporter', () => {
 | 
			
		||||
  // prettier-ignore
 | 
			
		||||
  test.each([
 | 
			
		||||
 | 
			
		||||
@ -425,7 +425,30 @@ ccc`],
 | 
			
		||||
        '--output', 'type=local,dest=./release-out',
 | 
			
		||||
        '.'
 | 
			
		||||
      ]
 | 
			
		||||
    ]
 | 
			
		||||
    ],
 | 
			
		||||
    [
 | 
			
		||||
      '0.6.0',
 | 
			
		||||
      new Map<string, string>([
 | 
			
		||||
        ['context', '.'],
 | 
			
		||||
        ['tag', 'localhost:5000/name/app:latest'],
 | 
			
		||||
        ['file', './test/Dockerfile'],
 | 
			
		||||
        ['network', 'host'],
 | 
			
		||||
        ['load', 'false'],
 | 
			
		||||
        ['no-cache', 'false'],
 | 
			
		||||
        ['push', 'true'],
 | 
			
		||||
        ['pull', 'false']
 | 
			
		||||
      ]),
 | 
			
		||||
      [
 | 
			
		||||
        'buildx',
 | 
			
		||||
        'build',
 | 
			
		||||
        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
			
		||||
        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
			
		||||
        '--file', './test/Dockerfile',
 | 
			
		||||
        '--network', 'host',
 | 
			
		||||
        '--push',
 | 
			
		||||
        '.'
 | 
			
		||||
      ]
 | 
			
		||||
    ],
 | 
			
		||||
  ])(
 | 
			
		||||
    'given %p with %p as inputs, returns %p',
 | 
			
		||||
    async (buildxVersion: string, inputs: Map<string, any>, expected: Array<string>) => {
 | 
			
		||||
 | 
			
		||||
@ -79,6 +79,8 @@ inputs:
 | 
			
		||||
outputs:
 | 
			
		||||
  digest:
 | 
			
		||||
    description: 'Image content-addressable identifier also called a digest'
 | 
			
		||||
  metadata:
 | 
			
		||||
    description: 'Build result metadata'
 | 
			
		||||
 | 
			
		||||
runs:
 | 
			
		||||
  using: 'node12'
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								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.getImageID = exports.getImageIDFile = void 0;
 | 
			
		||||
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;
 | 
			
		||||
const sync_1 = __importDefault(__nccwpck_require__(8750));
 | 
			
		||||
const fs_1 = __importDefault(__nccwpck_require__(5747));
 | 
			
		||||
const path_1 = __importDefault(__nccwpck_require__(5622));
 | 
			
		||||
@ -61,6 +61,22 @@ function getImageID() {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
exports.getImageID = getImageID;
 | 
			
		||||
function getMetadataFile() {
 | 
			
		||||
    return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
        return path_1.default.join(context.tmpDir(), 'metadata-file').split(path_1.default.sep).join(path_1.default.posix.sep);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
exports.getMetadataFile = getMetadataFile;
 | 
			
		||||
function getMetadata() {
 | 
			
		||||
    return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
        const metadataFile = yield getMetadataFile();
 | 
			
		||||
        if (!fs_1.default.existsSync(metadataFile)) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
        return fs_1.default.readFileSync(metadataFile, { encoding: 'utf-8' });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
exports.getMetadata = getMetadata;
 | 
			
		||||
function getSecretString(kvp) {
 | 
			
		||||
    return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
        return getSecret(kvp, false);
 | 
			
		||||
@ -311,6 +327,9 @@ function getBuildArgs(inputs, defaultContext, buildxVersion) {
 | 
			
		||||
        if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) {
 | 
			
		||||
            args.push('--iidfile', yield buildx.getImageIDFile());
 | 
			
		||||
        }
 | 
			
		||||
        if (buildx.satisfies(buildxVersion, '>=0.6.0')) {
 | 
			
		||||
            args.push('--metadata-file', yield buildx.getMetadataFile());
 | 
			
		||||
        }
 | 
			
		||||
        yield exports.asyncForEach(inputs.cacheFrom, (cacheFrom) => __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
            args.push('--cache-from', cacheFrom);
 | 
			
		||||
        }));
 | 
			
		||||
@ -476,13 +495,18 @@ function run() {
 | 
			
		||||
                    throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)[0].trim()}`);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            const imageID = yield buildx.getImageID();
 | 
			
		||||
            if (imageID) {
 | 
			
		||||
                core.startGroup(`Extracting digest`);
 | 
			
		||||
                core.info(`${imageID}`);
 | 
			
		||||
                context.setOutput('digest', imageID);
 | 
			
		||||
                core.endGroup();
 | 
			
		||||
            }
 | 
			
		||||
            yield core.group(`Setting outputs`, () => __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
                const imageID = yield buildx.getImageID();
 | 
			
		||||
                const metadata = yield buildx.getMetadata();
 | 
			
		||||
                if (imageID) {
 | 
			
		||||
                    core.info(`digest=${imageID}`);
 | 
			
		||||
                    context.setOutput('digest', imageID);
 | 
			
		||||
                }
 | 
			
		||||
                if (metadata) {
 | 
			
		||||
                    core.info(`metadata=${metadata}`);
 | 
			
		||||
                    context.setOutput('metadata', metadata);
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
        catch (error) {
 | 
			
		||||
            core.setFailed(error.message);
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,18 @@ export async function getImageID(): Promise<string | undefined> {
 | 
			
		||||
  return fs.readFileSync(iidFile, {encoding: 'utf-8'});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getMetadataFile(): Promise<string> {
 | 
			
		||||
  return path.join(context.tmpDir(), 'metadata-file').split(path.sep).join(path.posix.sep);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getMetadata(): Promise<string | undefined> {
 | 
			
		||||
  const metadataFile = await getMetadataFile();
 | 
			
		||||
  if (!fs.existsSync(metadataFile)) {
 | 
			
		||||
    return undefined;
 | 
			
		||||
  }
 | 
			
		||||
  return fs.readFileSync(metadataFile, {encoding: 'utf-8'});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getSecretString(kvp: string): Promise<string> {
 | 
			
		||||
  return getSecret(kvp, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,6 @@ import csvparse from 'csv-parse/lib/sync';
 | 
			
		||||
import * as fs from 'fs';
 | 
			
		||||
import * as os from 'os';
 | 
			
		||||
import * as path from 'path';
 | 
			
		||||
import * as semver from 'semver';
 | 
			
		||||
import * as tmp from 'tmp';
 | 
			
		||||
 | 
			
		||||
import * as core from '@actions/core';
 | 
			
		||||
@ -122,6 +121,9 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
 | 
			
		||||
  if (!buildx.isLocalOrTarExporter(inputs.outputs) && (inputs.platforms.length == 0 || buildx.satisfies(buildxVersion, '>=0.4.2'))) {
 | 
			
		||||
    args.push('--iidfile', await buildx.getImageIDFile());
 | 
			
		||||
  }
 | 
			
		||||
  if (buildx.satisfies(buildxVersion, '>=0.6.0')) {
 | 
			
		||||
    args.push('--metadata-file', await buildx.getMetadataFile());
 | 
			
		||||
  }
 | 
			
		||||
  await asyncForEach(inputs.cacheFrom, async cacheFrom => {
 | 
			
		||||
    args.push('--cache-from', cacheFrom);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.ts
									
									
									
									
									
								
							@ -33,13 +33,18 @@ async function run(): Promise<void> {
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    const imageID = await buildx.getImageID();
 | 
			
		||||
    if (imageID) {
 | 
			
		||||
      core.startGroup(`Extracting digest`);
 | 
			
		||||
      core.info(`${imageID}`);
 | 
			
		||||
      context.setOutput('digest', imageID);
 | 
			
		||||
      core.endGroup();
 | 
			
		||||
    }
 | 
			
		||||
    await core.group(`Setting outputs`, async () => {
 | 
			
		||||
      const imageID = await buildx.getImageID();
 | 
			
		||||
      const metadata = await buildx.getMetadata();
 | 
			
		||||
      if (imageID) {
 | 
			
		||||
        core.info(`digest=${imageID}`);
 | 
			
		||||
        context.setOutput('digest', imageID);
 | 
			
		||||
      }
 | 
			
		||||
      if (metadata) {
 | 
			
		||||
        core.info(`metadata=${metadata}`);
 | 
			
		||||
        context.setOutput('metadata', metadata);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    core.setFailed(error.message);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user