mirror of
https://github.com/docker/login-action.git
synced 2025-08-14 12:33:59 +08:00
Compare commits
71 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
465a07811f | ||
|
360b4b5fef | ||
|
c156700b23 | ||
|
f605cf145e | ||
|
2a93a3eddb | ||
|
422e90f610 | ||
|
bc8c4d08b4 | ||
|
052c2c4268 | ||
|
beabccd65a | ||
|
b56ed1c88d | ||
|
a13e198944 | ||
|
1b469c82ee | ||
|
83e260592e | ||
|
6ba7f31490 | ||
|
5447726540 | ||
|
40891eba8c | ||
|
dcd1f1fe0a | ||
|
713d7298f6 | ||
|
a7ae18608a | ||
|
65b78e6e13 | ||
|
219c305e1c | ||
|
eb81c74b31 | ||
|
eb7654ec33 | ||
|
ec9cdf07d5 | ||
|
d01f5a4fd6 | ||
|
af023e8f62 | ||
|
3da7dc6e2b | ||
|
07119058a1 | ||
|
bc135a1993 | ||
|
f8374000f2 | ||
|
9d3e51f876 | ||
|
9ec69b27e2 | ||
|
7f58925139 | ||
|
980c90b31a | ||
|
add9f8d32e | ||
|
f75d088332 | ||
|
b161681273 | ||
|
f4ef78c080 | ||
|
9ad4ce3929 | ||
|
884eadd4f8 | ||
|
a266232f5c | ||
|
f97efcfbf9 | ||
|
5ae789beac | ||
|
71c23b5b34 | ||
|
6401d70aab | ||
|
67e8909cc6 | ||
|
21f251affc | ||
|
07cad18854 | ||
|
be010b4293 | ||
|
f719196635 | ||
|
9607a71381 | ||
|
d398f07826 | ||
|
31aab9fb7e | ||
|
49ed152c8e | ||
|
b61a9ce7bd | ||
|
3a136a8631 | ||
|
b312880b69 | ||
|
795794e081 | ||
|
1edf6180e0 | ||
|
8e66ad4089 | ||
|
7c79b598ea | ||
|
24a38e0d6d | ||
|
70e1ff84cb | ||
|
0828e0e718 | ||
|
56f72fcef0 | ||
|
f169e16aaa | ||
|
fa178e4710 | ||
|
a4bf4e934e | ||
|
2bbd6e81e1 | ||
|
f6d32ad023 | ||
|
b4595c8bf9 |
23
.eslintrc.json
Normal file
23
.eslintrc.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"es2021": true,
|
||||
"jest": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:jest/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"jest",
|
||||
"prettier"
|
||||
]
|
||||
}
|
30
.github/workflows/ci.yml
vendored
30
.github/workflows/ci.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Stop docker
|
||||
run: |
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: ./
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: ./
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to ACR
|
||||
uses: ./
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
uses: ./
|
||||
@@ -120,7 +120,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to ECR
|
||||
uses: ./
|
||||
@@ -140,10 +140,10 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to Public ECR
|
||||
uses: ./
|
||||
@@ -187,10 +187,10 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -212,7 +212,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: ./
|
||||
@@ -232,7 +232,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to GitLab
|
||||
uses: ./
|
||||
@@ -252,7 +252,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to Google Artifact Registry
|
||||
uses: ./
|
||||
@@ -272,7 +272,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Login to Google Container Registry
|
||||
uses: ./
|
||||
|
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
@@ -6,9 +6,6 @@ on:
|
||||
- 'master'
|
||||
- 'releases/v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'releases/v*'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@@ -16,19 +13,14 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Validate
|
||||
uses: docker/bake-action@v1
|
||||
with:
|
||||
targets: validate
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Test
|
||||
uses: docker/bake-action@v1
|
||||
uses: docker/bake-action@v3
|
||||
with:
|
||||
targets: test
|
||||
-
|
||||
name: Upload coverage
|
||||
uses: codecov/codecov-action@v2
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: ./coverage/clover.xml
|
||||
|
41
.github/workflows/validate.yml
vendored
Normal file
41
.github/workflows/validate.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: validate
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'releases/v*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
targets: ${{ steps.targets.outputs.matrix }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Targets matrix
|
||||
id: targets
|
||||
run: |
|
||||
echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT
|
||||
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- prepare
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target: ${{ fromJson(needs.prepare.outputs.targets) }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: Validate
|
||||
uses: docker/bake-action@v3
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,11 +1,6 @@
|
||||
/.dev
|
||||
node_modules/
|
||||
lib
|
||||
|
||||
# Jetbrains
|
||||
/.idea
|
||||
/*.iml
|
||||
|
||||
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||
# Logs
|
||||
logs
|
||||
|
34
README.md
34
README.md
@@ -1,7 +1,7 @@
|
||||
[](https://github.com/docker/login-action/releases/latest)
|
||||
[](https://github.com/marketplace/actions/docker-login)
|
||||
[](https://github.com/docker/login-action/actions?workflow=ci)
|
||||
[](https://github.com/docker/login-action/actions?workflow=test)
|
||||
[](https://github.com/docker/login-action/actions?workflow=ci)
|
||||
[](https://github.com/docker/login-action/actions?workflow=test)
|
||||
[](https://codecov.io/gh/docker/login-action)
|
||||
|
||||
## About
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -100,13 +100,15 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to GitLab
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: registry.gitlab.com
|
||||
username: ${{ secrets.GITLAB_USERNAME }}
|
||||
password: ${{ secrets.GITLAB_PASSWORD }}
|
||||
```
|
||||
|
||||
If you have [Two-Factor Authentication](https://gitlab.com/help/user/profile/account/two_factor_authentication) enabled, use a [Personal Access Token](https://gitlab.com/help/user/profile/personal_access_tokens) instead of a password.
|
||||
|
||||
### Azure Container Registry (ACR)
|
||||
|
||||
[Create a service principal](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-service-principal#create-a-service-principal)
|
||||
@@ -126,7 +128,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to ACR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: <registry-name>.azurecr.io
|
||||
username: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
@@ -168,7 +170,7 @@ jobs:
|
||||
service_account: '<service_account>'
|
||||
|
||||
- name: Login to GCR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: gcr.io
|
||||
username: oauth2accesstoken
|
||||
@@ -200,7 +202,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to GCR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: gcr.io
|
||||
username: _json_key
|
||||
@@ -235,7 +237,7 @@ jobs:
|
||||
service_account: '<service_account>'
|
||||
|
||||
- name: Login to GAR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: <location>-docker.pkg.dev
|
||||
username: oauth2accesstoken
|
||||
@@ -269,7 +271,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to GAR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: <location>-docker.pkg.dev
|
||||
username: _json_key
|
||||
@@ -298,7 +300,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to ECR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
||||
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
@@ -321,7 +323,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to ECR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
||||
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
@@ -355,7 +357,7 @@ jobs:
|
||||
aws-region: <region>
|
||||
-
|
||||
name: Login to ECR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
||||
```
|
||||
@@ -381,7 +383,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to Public ECR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: public.ecr.aws
|
||||
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
@@ -415,7 +417,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to OCIR
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: <region>.ocir.io
|
||||
username: ${{ secrets.OCI_USERNAME }}
|
||||
@@ -441,7 +443,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Login to Quay.io
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: quay.io
|
||||
username: ${{ secrets.QUAY_USERNAME }}
|
||||
|
@@ -7,5 +7,5 @@ test('with password and username getInputs does not throw error', async () => {
|
||||
process.env['INPUT_LOGOUT'] = 'true';
|
||||
expect(() => {
|
||||
getInputs();
|
||||
}).not.toThrowError();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
@@ -6,6 +6,7 @@ import * as exec from '@actions/exec';
|
||||
process.env['RUNNER_TEMP'] = path.join(__dirname, 'runner');
|
||||
|
||||
test('loginStandard calls exec', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const execSpy = jest.spyOn(exec, 'getExecOutput').mockImplementation(async () => {
|
||||
return {
|
||||
@@ -15,9 +16,9 @@ test('loginStandard calls exec', async () => {
|
||||
};
|
||||
});
|
||||
|
||||
const username: string = 'dbowie';
|
||||
const password: string = 'groundcontrol';
|
||||
const registry: string = 'https://ghcr.io';
|
||||
const username = 'dbowie';
|
||||
const password = 'groundcontrol';
|
||||
const registry = 'https://ghcr.io';
|
||||
|
||||
await loginStandard(registry, username, password);
|
||||
|
||||
@@ -29,6 +30,7 @@ test('loginStandard calls exec', async () => {
|
||||
});
|
||||
|
||||
test('logout calls exec', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const execSpy = jest.spyOn(exec, 'getExecOutput').mockImplementation(async () => {
|
||||
return {
|
||||
@@ -38,7 +40,7 @@ test('logout calls exec', async () => {
|
||||
};
|
||||
});
|
||||
|
||||
const registry: string = 'https://ghcr.io';
|
||||
const registry = 'https://ghcr.io';
|
||||
|
||||
await logout(registry);
|
||||
|
||||
|
@@ -1,41 +1,35 @@
|
||||
import {expect, jest, test} from '@jest/globals';
|
||||
import osm = require('os');
|
||||
|
||||
import {run} from '../src/main';
|
||||
import {main} from '../src/main';
|
||||
import * as docker from '../src/docker';
|
||||
import * as stateHelper from '../src/state-helper';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
|
||||
test('errors without username and password', async () => {
|
||||
const platSpy = jest.spyOn(osm, 'platform').mockImplementation(() => 'linux');
|
||||
|
||||
jest.spyOn(osm, 'platform').mockImplementation(() => 'linux');
|
||||
process.env['INPUT_LOGOUT'] = 'true'; // default value
|
||||
const coreSpy = jest.spyOn(core, 'setFailed');
|
||||
|
||||
await run();
|
||||
expect(coreSpy).toHaveBeenCalledWith('Username and password required');
|
||||
await expect(main()).rejects.toThrow(new Error('Username and password required'));
|
||||
});
|
||||
|
||||
test('successful with username and password', async () => {
|
||||
const platSpy = jest.spyOn(osm, 'platform').mockImplementation(() => 'linux');
|
||||
jest.spyOn(osm, 'platform').mockImplementation(() => 'linux');
|
||||
const setRegistrySpy = jest.spyOn(stateHelper, 'setRegistry');
|
||||
const setLogoutSpy = jest.spyOn(stateHelper, 'setLogout');
|
||||
const dockerSpy = jest.spyOn(docker, 'login').mockImplementation(jest.fn());
|
||||
const dockerSpy = jest.spyOn(docker, 'login').mockImplementation(() => Promise.resolve());
|
||||
|
||||
const username: string = 'dbowie';
|
||||
const username = 'dbowie';
|
||||
process.env[`INPUT_USERNAME`] = username;
|
||||
|
||||
const password: string = 'groundcontrol';
|
||||
const password = 'groundcontrol';
|
||||
process.env[`INPUT_PASSWORD`] = password;
|
||||
|
||||
const ecr: string = 'auto';
|
||||
const ecr = 'auto';
|
||||
process.env['INPUT_ECR'] = ecr;
|
||||
|
||||
const logout: boolean = false;
|
||||
const logout = false;
|
||||
process.env['INPUT_LOGOUT'] = String(logout);
|
||||
|
||||
await run();
|
||||
await main();
|
||||
|
||||
expect(setRegistrySpy).toHaveBeenCalledWith('');
|
||||
expect(setLogoutSpy).toHaveBeenCalledWith(logout);
|
||||
@@ -43,28 +37,27 @@ test('successful with username and password', async () => {
|
||||
});
|
||||
|
||||
test('calls docker login', async () => {
|
||||
const platSpy = jest.spyOn(osm, 'platform').mockImplementation(() => 'linux');
|
||||
jest.spyOn(osm, 'platform').mockImplementation(() => 'linux');
|
||||
const setRegistrySpy = jest.spyOn(stateHelper, 'setRegistry');
|
||||
const setLogoutSpy = jest.spyOn(stateHelper, 'setLogout');
|
||||
const dockerSpy = jest.spyOn(docker, 'login');
|
||||
dockerSpy.mockImplementation(jest.fn());
|
||||
const dockerSpy = jest.spyOn(docker, 'login').mockImplementation(() => Promise.resolve());
|
||||
|
||||
const username: string = 'dbowie';
|
||||
const username = 'dbowie';
|
||||
process.env[`INPUT_USERNAME`] = username;
|
||||
|
||||
const password: string = 'groundcontrol';
|
||||
const password = 'groundcontrol';
|
||||
process.env[`INPUT_PASSWORD`] = password;
|
||||
|
||||
const registry: string = 'ghcr.io';
|
||||
const registry = 'ghcr.io';
|
||||
process.env[`INPUT_REGISTRY`] = registry;
|
||||
|
||||
const ecr: string = 'auto';
|
||||
const ecr = 'auto';
|
||||
process.env['INPUT_ECR'] = ecr;
|
||||
|
||||
const logout: boolean = true;
|
||||
const logout = true;
|
||||
process.env['INPUT_LOGOUT'] = String(logout);
|
||||
|
||||
await run();
|
||||
await main();
|
||||
|
||||
expect(setRegistrySpy).toHaveBeenCalledWith(registry);
|
||||
expect(setLogoutSpy).toHaveBeenCalledWith(logout);
|
||||
|
@@ -26,6 +26,6 @@ inputs:
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: 'node12'
|
||||
using: 'node16'
|
||||
main: 'dist/index.js'
|
||||
post: 'dist/index.js'
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# syntax=docker/dockerfile:1.3-labs
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG NODE_VERSION=12
|
||||
ARG DOCKER_VERSION=20.10.10
|
||||
ARG BUILDX_VERSION=0.7.0
|
||||
ARG NODE_VERSION=16
|
||||
ARG DOCKER_VERSION=20.10.13
|
||||
ARG BUILDX_VERSION=0.8.1
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine AS base
|
||||
RUN apk add --no-cache cpio findutils git
|
||||
@@ -57,10 +57,10 @@ RUN --mount=type=bind,target=.,rw \
|
||||
FROM scratch AS format-update
|
||||
COPY --from=format /out /
|
||||
|
||||
FROM deps AS format-validate
|
||||
FROM deps AS lint
|
||||
RUN --mount=type=bind,target=.,rw \
|
||||
--mount=type=cache,target=/src/node_modules \
|
||||
yarn run format-check
|
||||
yarn run lint
|
||||
|
||||
FROM docker:${DOCKER_VERSION} as docker
|
||||
FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
|
||||
|
32412
dist/index.js
generated
vendored
32412
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
1
dist/index.js.map
generated
vendored
Normal file
1
dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
12128
dist/licenses.txt
generated
vendored
Normal file
12128
dist/licenses.txt
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
dist/sourcemap-register.js
generated
vendored
Normal file
1
dist/sourcemap-register.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@ group "pre-checkin" {
|
||||
}
|
||||
|
||||
group "validate" {
|
||||
targets = ["format-validate", "build-validate", "vendor-validate"]
|
||||
targets = ["lint", "build-validate", "vendor-validate"]
|
||||
}
|
||||
|
||||
target "build" {
|
||||
@@ -28,9 +28,9 @@ target "format" {
|
||||
output = ["."]
|
||||
}
|
||||
|
||||
target "format-validate" {
|
||||
target "lint" {
|
||||
dockerfile = "dev.Dockerfile"
|
||||
target = "format-validate"
|
||||
target = "lint"
|
||||
output = ["type=cacheonly"]
|
||||
}
|
||||
|
||||
|
@@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
setupFiles: ["dotenv/config"],
|
||||
testMatch: ['**/*.test.ts'],
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: false
|
||||
}
|
29
jest.config.ts
Normal file
29
jest.config.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-login-action-')).split(path.sep).join(path.posix.sep);
|
||||
|
||||
process.env = Object.assign({}, process.env, {
|
||||
TEMP: tmpDir,
|
||||
GITHUB_REPOSITORY: 'docker/login-action',
|
||||
RUNNER_TEMP: path.join(tmpDir, 'runner-temp').split(path.sep).join(path.posix.sep),
|
||||
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache').split(path.sep).join(path.posix.sep)
|
||||
}) as {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
testMatch: ['**/*.test.ts'],
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
|
||||
},
|
||||
collectCoverageFrom: ['src/**/{!(main.ts),}.ts'],
|
||||
coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__tests__/'],
|
||||
verbose: true
|
||||
};
|
41
package.json
41
package.json
@@ -3,11 +3,11 @@
|
||||
"description": "GitHub Action to login against a Docker registry",
|
||||
"main": "lib/main.js",
|
||||
"scripts": {
|
||||
"build": "tsc && ncc build",
|
||||
"format": "prettier --write '**/*.ts'",
|
||||
"format-check": "prettier --check '**/*.ts'",
|
||||
"build": "ncc build src/main.ts --source-map --minify --license licenses.txt",
|
||||
"lint": "eslint src/**/*.ts __tests__/**/*.ts",
|
||||
"format": "eslint --fix src/**/*.ts __tests__/**/*.ts",
|
||||
"test": "jest --coverage",
|
||||
"pre-checkin": "yarn run format && yarn run build"
|
||||
"all": "yarn run build && yarn run format && yarn test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,21 +27,26 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.6.0",
|
||||
"@actions/exec": "^1.1.0",
|
||||
"@actions/io": "^1.1.1",
|
||||
"@aws-sdk/client-ecr": "^3.53.0",
|
||||
"@aws-sdk/client-ecr-public": "^3.53.0",
|
||||
"http-proxy-agent": "^5.0.0",
|
||||
"https-proxy-agent": "^5.0.0"
|
||||
"@actions/core": "^1.10.0",
|
||||
"@aws-sdk/client-ecr": "^3.347.1",
|
||||
"@aws-sdk/client-ecr-public": "^3.347.1",
|
||||
"@docker/actions-toolkit": "^0.2.0",
|
||||
"http-proxy-agent": "^7.0.0",
|
||||
"https-proxy-agent": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.26",
|
||||
"@vercel/ncc": "^0.33.3",
|
||||
"dotenv": "^16.0.0",
|
||||
"jest": "^27.2.5",
|
||||
"prettier": "^2.5.1",
|
||||
"ts-jest": "^27.1.2",
|
||||
"typescript": "^4.4.4"
|
||||
"@types/node": "^16.18.21",
|
||||
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
||||
"@typescript-eslint/parser": "^5.56.0",
|
||||
"@vercel/ncc": "^0.36.1",
|
||||
"eslint": "^8.36.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-jest": "^27.2.1",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"jest": "^29.5.0",
|
||||
"prettier": "^2.8.7",
|
||||
"ts-jest": "^29.0.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
||||
|
10
src/aws.ts
10
src/aws.ts
@@ -34,7 +34,7 @@ export const getAccountIDs = (registry: string): string[] => {
|
||||
if (!matches) {
|
||||
return [];
|
||||
}
|
||||
let accountIDs: Array<string> = [matches[2]];
|
||||
const accountIDs: Array<string> = [matches[2]];
|
||||
if (process.env.AWS_ACCOUNT_IDS) {
|
||||
accountIDs.push(...process.env.AWS_ACCOUNT_IDS.split(','));
|
||||
}
|
||||
@@ -57,14 +57,14 @@ export const getRegistriesData = async (registry: string, username?: string, pas
|
||||
authTokenRequest['registryIds'] = accountIDs;
|
||||
}
|
||||
|
||||
let httpProxyAgent: any = null;
|
||||
let httpProxyAgent;
|
||||
const httpProxy = process.env.http_proxy || process.env.HTTP_PROXY || '';
|
||||
if (httpProxy) {
|
||||
core.debug(`Using http proxy ${httpProxy}`);
|
||||
httpProxyAgent = new HttpProxyAgent(httpProxy);
|
||||
}
|
||||
|
||||
let httpsProxyAgent: any = null;
|
||||
let httpsProxyAgent;
|
||||
const httpsProxy = process.env.https_proxy || process.env.HTTPS_PROXY || '';
|
||||
if (httpsProxy) {
|
||||
core.debug(`Using https proxy ${httpsProxy}`);
|
||||
@@ -96,6 +96,8 @@ export const getRegistriesData = async (registry: string, username?: string, pas
|
||||
}
|
||||
const authToken = Buffer.from(authTokenResponse.authorizationData.authorizationToken, 'base64').toString('utf-8');
|
||||
const creds = authToken.split(':', 2);
|
||||
core.setSecret(creds[0]); // redacted in workflow logs
|
||||
core.setSecret(creds[1]); // redacted in workflow logs
|
||||
return [
|
||||
{
|
||||
registry: 'public.ecr.aws',
|
||||
@@ -122,6 +124,8 @@ export const getRegistriesData = async (registry: string, username?: string, pas
|
||||
for (const authData of authTokenResponse.authorizationData) {
|
||||
const authToken = Buffer.from(authData.authorizationToken || '', 'base64').toString('utf-8');
|
||||
const creds = authToken.split(':', 2);
|
||||
core.setSecret(creds[0]); // redacted in workflow logs
|
||||
core.setSecret(creds[1]); // redacted in workflow logs
|
||||
regDatas.push({
|
||||
registry: authData.proxyEndpoint || '',
|
||||
username: creds[0],
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as aws from './aws';
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import {Exec} from '@docker/actions-toolkit/lib/exec';
|
||||
|
||||
export async function login(registry: string, username: string, password: string, ecr: string): Promise<void> {
|
||||
if (/true/i.test(ecr) || (ecr == 'auto' && aws.isECR(registry))) {
|
||||
@@ -11,15 +11,13 @@ export async function login(registry: string, username: string, password: string
|
||||
}
|
||||
|
||||
export async function logout(registry: string): Promise<void> {
|
||||
await exec
|
||||
.getExecOutput('docker', ['logout', registry], {
|
||||
ignoreReturnCode: true
|
||||
})
|
||||
.then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
core.warning(res.stderr.trim());
|
||||
}
|
||||
});
|
||||
await Exec.getExecOutput('docker', ['logout', registry], {
|
||||
ignoreReturnCode: true
|
||||
}).then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
core.warning(res.stderr.trim());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function loginStandard(registry: string, username: string, password: string): Promise<void> {
|
||||
@@ -27,7 +25,7 @@ export async function loginStandard(registry: string, username: string, password
|
||||
throw new Error('Username and password required');
|
||||
}
|
||||
|
||||
let loginArgs: Array<string> = ['login', '--password-stdin'];
|
||||
const loginArgs: Array<string> = ['login', '--password-stdin'];
|
||||
loginArgs.push('--username', username);
|
||||
loginArgs.push(registry);
|
||||
|
||||
@@ -36,18 +34,16 @@ export async function loginStandard(registry: string, username: string, password
|
||||
} else {
|
||||
core.info(`Logging into Docker Hub...`);
|
||||
}
|
||||
await exec
|
||||
.getExecOutput('docker', loginArgs, {
|
||||
ignoreReturnCode: true,
|
||||
silent: true,
|
||||
input: Buffer.from(password)
|
||||
})
|
||||
.then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
throw new Error(res.stderr.trim());
|
||||
}
|
||||
core.info(`Login Succeeded!`);
|
||||
});
|
||||
await Exec.getExecOutput('docker', loginArgs, {
|
||||
ignoreReturnCode: true,
|
||||
silent: true,
|
||||
input: Buffer.from(password)
|
||||
}).then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
throw new Error(res.stderr.trim());
|
||||
}
|
||||
core.info(`Login Succeeded!`);
|
||||
});
|
||||
}
|
||||
|
||||
export async function loginECR(registry: string, username: string, password: string): Promise<void> {
|
||||
@@ -55,17 +51,15 @@ export async function loginECR(registry: string, username: string, password: str
|
||||
const regDatas = await aws.getRegistriesData(registry, username, password);
|
||||
for (const regData of regDatas) {
|
||||
core.info(`Logging into ${regData.registry}...`);
|
||||
await exec
|
||||
.getExecOutput('docker', ['login', '--password-stdin', '--username', regData.username, regData.registry], {
|
||||
ignoreReturnCode: true,
|
||||
silent: true,
|
||||
input: Buffer.from(regData.password)
|
||||
})
|
||||
.then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
throw new Error(res.stderr.trim());
|
||||
}
|
||||
core.info('Login Succeeded!');
|
||||
});
|
||||
await Exec.getExecOutput('docker', ['login', '--password-stdin', '--username', regData.username, regData.registry], {
|
||||
ignoreReturnCode: true,
|
||||
silent: true,
|
||||
input: Buffer.from(regData.password)
|
||||
}).then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
throw new Error(res.stderr.trim());
|
||||
}
|
||||
core.info('Login Succeeded!');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
25
src/main.ts
25
src/main.ts
@@ -1,28 +1,21 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as actionsToolkit from '@docker/actions-toolkit';
|
||||
|
||||
import * as context from './context';
|
||||
import * as docker from './docker';
|
||||
import * as stateHelper from './state-helper';
|
||||
|
||||
export async function run(): Promise<void> {
|
||||
try {
|
||||
const input: context.Inputs = context.getInputs();
|
||||
stateHelper.setRegistry(input.registry);
|
||||
stateHelper.setLogout(input.logout);
|
||||
await docker.login(input.registry, input.username, input.password, input.ecr);
|
||||
} catch (error: any) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
export async function main(): Promise<void> {
|
||||
const input: context.Inputs = context.getInputs();
|
||||
stateHelper.setRegistry(input.registry);
|
||||
stateHelper.setLogout(input.logout);
|
||||
await docker.login(input.registry, input.username, input.password, input.ecr);
|
||||
}
|
||||
|
||||
async function logout(): Promise<void> {
|
||||
async function post(): Promise<void> {
|
||||
if (!stateHelper.logout) {
|
||||
return;
|
||||
}
|
||||
await docker.logout(stateHelper.registry);
|
||||
}
|
||||
|
||||
if (!stateHelper.IsPost) {
|
||||
run();
|
||||
} else {
|
||||
logout();
|
||||
}
|
||||
actionsToolkit.run(main, post);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import * as core from '@actions/core';
|
||||
|
||||
export const IsPost = !!process.env['STATE_isPost'];
|
||||
export const registry = process.env['STATE_registry'] || '';
|
||||
export const logout = /true/i.test(process.env['STATE_logout'] || '');
|
||||
|
||||
@@ -11,7 +10,3 @@ export function setRegistry(registry: string) {
|
||||
export function setLogout(logout: boolean) {
|
||||
core.saveState('logout', logout);
|
||||
}
|
||||
|
||||
if (!IsPost) {
|
||||
core.saveState('isPost', 'true');
|
||||
}
|
||||
|
@@ -1,14 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"esModuleInterop": true,
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"newLine": "lf",
|
||||
"outDir": "./lib",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitAny": false,
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true
|
||||
"resolveJsonModule": true,
|
||||
"useUnknownInCatchVariables": false,
|
||||
},
|
||||
"exclude": ["node_modules", "**/*.test.ts"]
|
||||
"exclude": [
|
||||
"./__tests__/**/*",
|
||||
"./lib/**/*",
|
||||
"node_modules",
|
||||
"jest.config.ts"
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user