Skip to content

Commit

Permalink
Add optional pushImage input (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
mr-smithers-excellent authored Oct 6, 2022
1 parent 3cedd44 commit 6387d35
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 14 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ jobs:
- name: Check out code
uses: actions/checkout@v2

- uses: actions/setup-node@v3
with:
node-version: 16

- name: Build
run: npm ci

Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ jobs:
- name: Check out code
uses: actions/checkout@v2

- uses: actions/setup-node@v3
with:
node-version: 16

- name: Build
run: npm ci

- name: Run unit tests
- name: Run unit tests
run: npm run test
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ steps:
| password | Docker registry password or token | No | String |
| githubOrg | GitHub organization to push image to (if not current) | No | String |
| enableBuildKit | Enables Docker BuildKit support | No | Boolean |
| pushImage | Flag for disabling the login & push steps, set to `true` by default | No | Boolean |

## Outputs

Expand Down
6 changes: 5 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ inputs:
description: "Enables Docker BuildKit support"
required: false
default: "false"
pushImage:
description: "Flag for disabling the login & push steps, set to true by default"
required: false
default: "true"
outputs:
imageFullName:
description: "Full name of the Docker image with registry prefix and tag suffix"
Expand All @@ -59,7 +63,7 @@ outputs:
tags:
description: "Tags for the Docker image"
runs:
using: "node12"
using: "node16"
main: "dist/index.js"
branding:
icon: "anchor"
Expand Down
24 changes: 19 additions & 5 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10050,7 +10050,8 @@ const buildOpts = {
target: undefined,
buildDir: undefined,
enableBuildKit: false,
platform: undefined
platform: undefined,
skipPush: false
};

const run = () => {
Expand All @@ -10071,15 +10072,16 @@ const run = () => {
buildOpts.buildDir = core.getInput('directory') || '.';
buildOpts.enableBuildKit = core.getInput('enableBuildKit') === 'true';
buildOpts.platform = core.getInput('platform');
buildOpts.skipPush = core.getInput('pushImage') === 'false';

// Create the Docker image name
const imageFullName = docker.createFullImageName(registry, image, githubOwner);
core.info(`Docker image name used for this build: ${imageFullName}`);

// Log in, build & push the Docker image
docker.login(username, password, registry);
docker.login(username, password, registry, buildOpts.skipPush);
docker.build(imageFullName, dockerfile, buildOpts);
docker.push(imageFullName, buildOpts.tags);
docker.push(imageFullName, buildOpts.tags, buildOpts.skipPush);

// Capture outputs
core.setOutput('imageFullName', imageFullName);
Expand Down Expand Up @@ -10197,7 +10199,12 @@ const isEcr = registry => registry && registry.includes('amazonaws');
const getRegion = registry => registry.substring(registry.indexOf('ecr.') + 4, registry.indexOf('.amazonaws'));

// Log in to provided Docker registry
const login = (username, password, registry) => {
const login = (username, password, registry, skipPush) => {
if (skipPush) {
core.info('Input skipPush is set to true, skipping Docker log in step...');
return;
}

// If using ECR, use the AWS CLI login command in favor of docker login
if (isEcr(registry)) {
const region = getRegion(registry);
Expand All @@ -10210,11 +10217,18 @@ const login = (username, password, registry) => {
cp.execSync(`docker login -u ${username} --password-stdin ${registry}`, {
input: password
});
} else {
core.setFailed('Must supply Docker registry credentials to push image!');
}
};

// Push Docker image & all tags
const push = (imageName, tags) => {
const push = (imageName, tags, skipPush) => {
if (skipPush) {
core.info('Input skipPush is set to true, skipping Docker push step...');
return;
}

core.info(`Pushing tags ${tags} for Docker image ${imageName}...`);
cp.execSync(`docker push ${imageName} --all-tags`, cpOptions);
};
Expand Down
8 changes: 5 additions & 3 deletions src/docker-build-push.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const buildOpts = {
target: undefined,
buildDir: undefined,
enableBuildKit: false,
platform: undefined
platform: undefined,
skipPush: false
};

const run = () => {
Expand All @@ -31,15 +32,16 @@ const run = () => {
buildOpts.buildDir = core.getInput('directory') || '.';
buildOpts.enableBuildKit = core.getInput('enableBuildKit') === 'true';
buildOpts.platform = core.getInput('platform');
buildOpts.skipPush = core.getInput('pushImage') === 'false';

// Create the Docker image name
const imageFullName = docker.createFullImageName(registry, image, githubOwner);
core.info(`Docker image name used for this build: ${imageFullName}`);

// Log in, build & push the Docker image
docker.login(username, password, registry);
docker.login(username, password, registry, buildOpts.skipPush);
docker.build(imageFullName, dockerfile, buildOpts);
docker.push(imageFullName, buildOpts.tags);
docker.push(imageFullName, buildOpts.tags, buildOpts.skipPush);

// Capture outputs
core.setOutput('imageFullName', imageFullName);
Expand Down
16 changes: 14 additions & 2 deletions src/docker.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ const isEcr = registry => registry && registry.includes('amazonaws');
const getRegion = registry => registry.substring(registry.indexOf('ecr.') + 4, registry.indexOf('.amazonaws'));

// Log in to provided Docker registry
const login = (username, password, registry) => {
const login = (username, password, registry, skipPush) => {
if (skipPush) {
core.info('Input skipPush is set to true, skipping Docker log in step...');
return;
}

// If using ECR, use the AWS CLI login command in favor of docker login
if (isEcr(registry)) {
const region = getRegion(registry);
Expand All @@ -110,11 +115,18 @@ const login = (username, password, registry) => {
cp.execSync(`docker login -u ${username} --password-stdin ${registry}`, {
input: password
});
} else {
core.setFailed('Must supply Docker registry credentials to push image!');
}
};

// Push Docker image & all tags
const push = (imageName, tags) => {
const push = (imageName, tags, skipPush) => {
if (skipPush) {
core.info('Input skipPush is set to true, skipping Docker push step...');
return;
}

core.info(`Pushing tags ${tags} for Docker image ${imageName}...`);
cp.execSync(`docker push ${imageName} --all-tags`, cpOptions);
};
Expand Down
2 changes: 1 addition & 1 deletion tests/docker-build-push.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const mockRepoName = 'some-repo';

const runAssertions = (imageFullName, inputs, tagOverrides) => {
// Inputs
expect(core.getInput).toHaveBeenCalledTimes(15);
expect(core.getInput).toHaveBeenCalledTimes(16);

// Outputs
const tags = tagOverrides || parseArray(inputs.tags);
Expand Down
23 changes: 22 additions & 1 deletion tests/docker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,21 @@ describe('Docker build, login & push commands', () => {
);
});

test("returns undefined if empty login and doesn't execute command", () => {
test('Skip login command if skipPush is set to true', () => {
const skipPush = true;
docker.login(username, password, registry, skipPush);

expect(cp.execSync.mock.calls.length).toEqual(0);
});

test('Missing username or password should throw an error', () => {
docker.login(undefined, undefined, registry);

expect(cp.execSync.mock.calls.length).toEqual(0);
expect(core.setFailed).toHaveBeenCalled();
});

test('returns undefined if empty login and does not execute command', () => {
docker.login(username, password, registry);

expect(cp.execSync.mock.calls.length).toEqual(0);
Expand All @@ -312,5 +326,12 @@ describe('Docker build, login & push commands', () => {

expect(cp.execSync).toHaveBeenCalledWith(`docker push ${imageName} --all-tags`, cpOptions);
});

test('Skip push command if skipPush is set to true', () => {
const skipPush = true;
docker.push('my-org/my-image', 'latest', skipPush);

expect(cp.execSync.mock.calls.length).toEqual(0);
});
});
});

0 comments on commit 6387d35

Please sign in to comment.