Skip to content

Commit

Permalink
POPS-3158 Tag images with default branch name or pr number
Browse files Browse the repository at this point in the history
In order to have a better control on image lifecycle
we need to tag them based on the build type: on master or pr.
This commit extends docker action to tag images as follows:
- on merge to master branch it will add a tag like master-<SHA>
- on push to PR or commenting on PR it will add a tag like pr-<number>-<SHA>
  • Loading branch information
arminioa committed Jan 17, 2024
1 parent 4f26e9c commit 88f5bbd
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 8 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ jobs:
eu.gcr.io/tradeshift-base/my-repo:latest
```

### Image tracability with labels
### Image traceability with labels

If you want to be able to lookup the repository for your image, or add more medata
If you want to be able to lookup the repository for your image, or add more metadata
you can add labels.

```yaml
Expand Down Expand Up @@ -134,7 +134,7 @@ jobs:
repo-cache: true
```

We currently dont support docker registry caching but that should be
We currently don't support docker registry caching but that should be
implemented in the future.

### Platform
Expand Down
7 changes: 7 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ inputs:
description: >
This flag can be used to disable automatically tagging the image with the SHA.
Skipping default tag requires specifying alternative tags.
skip-tag-with-prefix:
required: false
description: >
This flag can be used to disable automatically tagging images with prefixes
based on the type of build: on master or on pull rquest.
An image built from a pull request is tagged with pr-<number>-<SHA>.
An image built on merge to master branch is tagged with master-<SHA>.
useqemu:
required: false
description: >
Expand Down
55 changes: 53 additions & 2 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

53 changes: 51 additions & 2 deletions src/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as state from './state';
import {buildxCachePath, buildxNewCachePath} from './cache';
import {debug, endGroup, info, startGroup, warning} from '@actions/core';
import {Inputs} from './inputs';
import * as fs from 'fs';

export async function build(inputs: Inputs): Promise<string> {
startGroup('🏃 Starting build');
Expand Down Expand Up @@ -43,6 +44,10 @@ async function getBuildArgs(
if (!inputs.skipDefaultTag) {
args.push('--tag', defaultTag);
}
const shaTagWithPrefix = await getSHATagWithPrefix(inputs.repository);
if (!inputs.skipTagWithPrefix && !inputs.skipDefaultTag) {
args.push('--tag', shaTagWithPrefix);
}
if (inputs.platform) {
args.push('--platform', inputs.platform);
}
Expand Down Expand Up @@ -78,14 +83,58 @@ export function isDockerhubRepository(repository: string): boolean {
return registry === '';
}

async function getSHATag(repository: string): Promise<string> {
async function getSHA(): Promise<string> {
const res = await exec.getExecOutput('git', ['rev-parse', 'HEAD'], {
silent: true
});
if (res.stderr !== '' && res.exitCode) {
throw new Error(`git rev-parse HEAD failed: ${res.stderr.trim()}`);
}
return `${repository}:${res.stdout.trim()}`;
return res.stdout.trim();
}

async function getSHATag(repository: string): Promise<string> {
const sha = await getSHA();
return `${repository}:${sha}`;
}

async function getSHATagWithPrefix(repository: string): Promise<string> {
const sha = await getSHA();
const eventPath = process.env.GITHUB_EVENT_PATH;
if (!eventPath) {
throw new Error('GITHUB_EVENT_PATH env variable not found');
}
const eventContent = await fs.promises.readFile(eventPath, {
encoding: 'utf8'
});
const event = JSON.parse(eventContent);
const default_branch = event?.repository?.default_branch;
if (typeof default_branch != 'string') {
throw new Error(
`Unable to extract repository.default_branch from ${eventPath}`
);
}

let shaWithPrefix: string;
const ref = event?.ref || '';
if (ref !== '' && ref === `refs/heads/${default_branch}`) {
// on merge to default branch
shaWithPrefix = `${default_branch}-${sha}`;
} else {
// on pull request
const number = event?.number;
const issueNumber = event?.issue?.number;
if (typeof number == 'number') {
shaWithPrefix = `pr-${number}-${sha}`;
} else if (typeof issueNumber == 'number') {
shaWithPrefix = `pr-${issueNumber}-${sha}`;
} else {
throw new Error(
"Unable to establish if it's a merge on master or a push on a pull request or a comment on pull request!"
);
}
}
return `${repository}:${shaWithPrefix}`;
}

export async function version(): Promise<void> {
Expand Down
2 changes: 2 additions & 0 deletions src/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface Inputs {
repository: string;
registries: string[];
skipDefaultTag: boolean;
skipTagWithPrefix: boolean;
tags: string[];
username: string;
authOnly: boolean;
Expand Down Expand Up @@ -47,6 +48,7 @@ export async function getInputs(): Promise<Inputs> {
repository: getInput('repository') || defaultRepository(),
registries: getMultilineInput('registries'),
skipDefaultTag: getInput('skip-default-tag') === 'true',
skipTagWithPrefix: getInput('skip-tag-with-prefix') === 'true',
tags: await getInputList('tags'),
username: getInput('username'),
authOnly: getInput('auth-only') === 'true',
Expand Down

0 comments on commit 88f5bbd

Please sign in to comment.