mirror of
https://github.com/docker/login-action.git
synced 2026-04-25 17:08:22 +08:00
Compare commits
127 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6986616b80 | ||
|
|
e33c55ff04 | ||
|
|
c318662ea5 | ||
|
|
ae469901b0 | ||
|
|
a1b00d1f67 | ||
|
|
60b37403f5 | ||
|
|
1307053441 | ||
|
|
1ed1634702 | ||
|
|
5565f3ba0d | ||
|
|
4a8376e001 | ||
|
|
d0fa2cf570 | ||
|
|
d43e1c853e | ||
|
|
2f6998335c | ||
|
|
d65286840f | ||
|
|
36864503dc | ||
|
|
ada68c7d01 | ||
|
|
55e1ea5a9a | ||
|
|
ba754150c9 | ||
|
|
d8fcc4b9cc | ||
|
|
149496aaf3 | ||
|
|
4907a6ddec | ||
|
|
1e233e691a | ||
|
|
6c24ead680 | ||
|
|
ee034d7094 | ||
|
|
1527209db9 | ||
|
|
d39362aba4 | ||
|
|
a6f092b568 | ||
|
|
60953f0bed | ||
|
|
62c688590f | ||
|
|
102c0e6729 | ||
|
|
72e5ceb81f | ||
|
|
e7e12d441a | ||
|
|
20103df299 | ||
|
|
5be8034354 | ||
|
|
4fddf4fef5 | ||
|
|
eb50903c80 | ||
|
|
b434872b94 | ||
|
|
2d420a4f14 | ||
|
|
ccb26d9283 | ||
|
|
e48e882fee | ||
|
|
b0186b9cf5 | ||
|
|
034c220d94 | ||
|
|
3fdf3f727d | ||
|
|
6f14fdf8a4 | ||
|
|
6290052128 | ||
|
|
bb555fc48d | ||
|
|
6de6c60d10 | ||
|
|
de05a6d3a2 | ||
|
|
5ac140e711 | ||
|
|
bb9683dca2 | ||
|
|
abb6787042 | ||
|
|
a40c6a7122 | ||
|
|
5c42dd293b | ||
|
|
1615afe9d3 | ||
|
|
c376ab6818 | ||
|
|
ed2fd52341 | ||
|
|
8ff08ec562 | ||
|
|
b24684bb3c | ||
|
|
a0d57b8e43 | ||
|
|
6eab1c84d2 | ||
|
|
292fe2d7ee | ||
|
|
717e062c09 | ||
|
|
b9381571b7 | ||
|
|
7277d4d442 | ||
|
|
955b3c705f | ||
|
|
da5b89b92c | ||
|
|
b78dc2c156 | ||
|
|
c144859092 | ||
|
|
cf45a603d2 | ||
|
|
9fe7774c8f | ||
|
|
2b784c0f37 | ||
|
|
89452f99ba | ||
|
|
db14339dbc | ||
|
|
e46b7e3300 | ||
|
|
126accdd0b | ||
|
|
5c5e504cc6 | ||
|
|
bb0e4e1bb1 | ||
|
|
b45d80f862 | ||
|
|
176cb9c12a | ||
|
|
cad8984310 | ||
|
|
92cbcb231e | ||
|
|
5a2d6a71bd | ||
|
|
44512b6b2e | ||
|
|
28737a5e46 | ||
|
|
dac079354a | ||
|
|
62029f315d | ||
|
|
08c8f064bf | ||
|
|
30619c31e4 | ||
|
|
c4a8904a93 | ||
|
|
7e7b532c5e | ||
|
|
5dae9a6c13 | ||
|
|
4109968190 | ||
|
|
a93df38ecb | ||
|
|
305d099b3c | ||
|
|
4693242509 | ||
|
|
14fe2ea9e2 | ||
|
|
23e908783e | ||
|
|
fdfb31da7c | ||
|
|
6585fe535d | ||
|
|
c859298dc3 | ||
|
|
c3e61d16d7 | ||
|
|
21f7481f00 | ||
|
|
c38ec43af1 | ||
|
|
a68c413f92 | ||
|
|
3227f5311c | ||
|
|
1e0f9435cc | ||
|
|
0d33dcdeed | ||
|
|
8e2a0b642a | ||
|
|
da755dd47d | ||
|
|
3b958849f4 | ||
|
|
2e1345c05f | ||
|
|
82f62b3035 | ||
|
|
c94ce9fb46 | ||
|
|
8339c958ce | ||
|
|
c83e9320c8 | ||
|
|
b268aa57e3 | ||
|
|
a603229278 | ||
|
|
7567f92a74 | ||
|
|
0567fa5ae8 | ||
|
|
f6ef577545 | ||
|
|
916386b000 | ||
|
|
5b3f94a294 | ||
|
|
f9cc43b63d | ||
|
|
6862ffc5ab | ||
|
|
4349d75975 | ||
|
|
28fdb31ff3 | ||
|
|
2064b45545 |
@@ -1,3 +0,0 @@
|
|||||||
/dist/**
|
|
||||||
/coverage/**
|
|
||||||
/node_modules/**
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
"es6": true,
|
|
||||||
"jest": true
|
|
||||||
},
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:@typescript-eslint/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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -4,6 +4,12 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
|
cooldown:
|
||||||
|
default-days: 2
|
||||||
|
groups:
|
||||||
|
crazy-max-dot-github:
|
||||||
|
patterns:
|
||||||
|
- "crazy-max/.github/*"
|
||||||
labels:
|
labels:
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
- "bot"
|
- "bot"
|
||||||
@@ -11,6 +17,10 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
|
cooldown:
|
||||||
|
default-days: 2
|
||||||
|
exclude:
|
||||||
|
- "@docker/actions-toolkit"
|
||||||
versioning-strategy: "increase"
|
versioning-strategy: "increase"
|
||||||
groups:
|
groups:
|
||||||
aws-sdk-dependencies:
|
aws-sdk-dependencies:
|
||||||
|
|||||||
165
.github/workflows/ci.yml
vendored
165
.github/workflows/ci.yml
vendored
@@ -1,5 +1,8 @@
|
|||||||
name: ci
|
name: ci
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
@@ -19,7 +22,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Stop docker
|
name: Stop docker
|
||||||
run: |
|
run: |
|
||||||
@@ -43,7 +46,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to GitHub Container Registry
|
name: Login to GitHub Container Registry
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -60,7 +63,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to GitHub Container Registry
|
name: Login to GitHub Container Registry
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -70,7 +73,7 @@ jobs:
|
|||||||
password: ${{ secrets.GHCR_PAT }}
|
password: ${{ secrets.GHCR_PAT }}
|
||||||
-
|
-
|
||||||
name: DinD
|
name: DinD
|
||||||
uses: docker://docker
|
uses: docker://docker:29.3@sha256:4d90f1f6c400315c2dba96d3ec93c01e64198395cbba04f79d12adce4f737029
|
||||||
with:
|
with:
|
||||||
entrypoint: docker
|
entrypoint: docker
|
||||||
args: pull ghcr.io/docker-ghactiontest/test
|
args: pull ghcr.io/docker-ghactiontest/test
|
||||||
@@ -85,7 +88,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to ACR
|
name: Login to ACR
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -105,7 +108,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to Docker Hub
|
name: Login to Docker Hub
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -124,7 +127,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to ECR
|
name: Login to ECR
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -144,10 +147,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Configure AWS Credentials
|
name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5
|
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
@@ -169,7 +172,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to Public ECR
|
name: Login to Public ECR
|
||||||
continue-on-error: ${{ matrix.os == 'windows-latest' }}
|
continue-on-error: ${{ matrix.os == 'windows-latest' }}
|
||||||
@@ -192,10 +195,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Configure AWS Credentials
|
name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5
|
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
@@ -207,7 +210,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
registry: public.ecr.aws
|
registry: public.ecr.aws
|
||||||
|
|
||||||
github-container:
|
ghcr:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -218,7 +221,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to GitHub Container Registry
|
name: Login to GitHub Container Registry
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -238,7 +241,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to GitLab
|
name: Login to GitLab
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -258,7 +261,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to Google Artifact Registry
|
name: Login to Google Artifact Registry
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -278,7 +281,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to Google Container Registry
|
name: Login to Google Container Registry
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -292,7 +295,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to registries
|
name: Login to registries
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -315,7 +318,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to registries
|
name: Login to registries
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -336,7 +339,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Login to registries
|
name: Login to registries
|
||||||
id: login
|
id: login
|
||||||
@@ -356,3 +359,125 @@ jobs:
|
|||||||
echo "::error::Should have failed"
|
echo "::error::Should have failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
scope-dockerhub:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
scope: '@push'
|
||||||
|
-
|
||||||
|
name: Print config.json files
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
shopt -s globstar nullglob
|
||||||
|
for file in ~/.docker/**/config.json; do
|
||||||
|
echo "## ${file}"
|
||||||
|
jq '(.auths[]?.auth) |= "REDACTED"' "$file"
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
scope-dockerhub-repo:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
scope: 'docker/buildx-bin@push'
|
||||||
|
-
|
||||||
|
name: Print config.json files
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
shopt -s globstar nullglob
|
||||||
|
for file in ~/.docker/**/config.json; do
|
||||||
|
echo "## ${file}"
|
||||||
|
jq '(.auths[]?.auth) |= "REDACTED"' "$file"
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
scope-ghcr:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
-
|
||||||
|
name: Login to GitHub Container Registry
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
scope: '@push'
|
||||||
|
-
|
||||||
|
name: Print config.json files
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
shopt -s globstar nullglob
|
||||||
|
for file in ~/.docker/**/config.json; do
|
||||||
|
echo "## ${file}"
|
||||||
|
jq '(.auths[]?.auth) |= "REDACTED"' "$file"
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
scope-ghcr-repo:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
-
|
||||||
|
name: Login to GitHub Container Registry
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
scope: 'docker/login-action@push'
|
||||||
|
-
|
||||||
|
name: Print config.json files
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
shopt -s globstar nullglob
|
||||||
|
for file in ~/.docker/**/config.json; do
|
||||||
|
echo "## ${file}"
|
||||||
|
jq '(.auths[]?.auth) |= "REDACTED"' "$file"
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|||||||
52
.github/workflows/codeql.yml
vendored
52
.github/workflows/codeql.yml
vendored
@@ -1,50 +1,46 @@
|
|||||||
name: codeql
|
name: codeql
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'master'
|
- 'master'
|
||||||
- 'releases/v*'
|
- 'releases/v*'
|
||||||
paths:
|
|
||||||
- '.github/workflows/codeql.yml'
|
|
||||||
- 'dist/**'
|
|
||||||
- 'src/**'
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
|
||||||
- '.github/workflows/codeql.yml'
|
|
||||||
- 'dist/**'
|
|
||||||
- 'src/**'
|
|
||||||
|
|
||||||
permissions:
|
env:
|
||||||
actions: read
|
NODE_VERSION: "24"
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
permissions:
|
||||||
fail-fast: false
|
contents: read
|
||||||
matrix:
|
security-events: write
|
||||||
language:
|
|
||||||
- javascript-typescript
|
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
-
|
||||||
|
name: Enable corepack
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
yarn --version
|
||||||
|
-
|
||||||
|
name: Set up Node
|
||||||
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
-
|
-
|
||||||
name: Initialize CodeQL
|
name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: javascript-typescript
|
||||||
config: |
|
build-mode: none
|
||||||
paths:
|
|
||||||
- src
|
|
||||||
-
|
|
||||||
name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v3
|
|
||||||
-
|
-
|
||||||
name: Perform CodeQL Analysis
|
name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3
|
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
|
||||||
with:
|
with:
|
||||||
category: "/language:${{matrix.language}}"
|
category: "/language:javascript-typescript"
|
||||||
|
|||||||
4
.github/workflows/pr-assign-author.yml
vendored
4
.github/workflows/pr-assign-author.yml
vendored
@@ -4,14 +4,14 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
pull_request_target: # zizmor: ignore[dangerous-triggers] safe to use without checkout
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
- reopened
|
- reopened
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run:
|
run:
|
||||||
uses: crazy-max/.github/.github/workflows/pr-assign-author.yml@1b673f36fad86812f538c1df9794904038a23cbf
|
uses: crazy-max/.github/.github/workflows/pr-assign-author.yml@4a17dbaa9ce13920fc5bb8824eb89c16301e5ab2 # v1.7.0
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|||||||
11
.github/workflows/publish.yml
vendored
11
.github/workflows/publish.yml
vendored
@@ -1,5 +1,12 @@
|
|||||||
name: publish
|
name: publish
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
@@ -15,7 +22,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Publish
|
name: Publish
|
||||||
uses: actions/publish-immutable-action@v0.0.4
|
uses: actions/publish-immutable-action@4bc8754ffc40f27910afb20287dbbbb675a4e978 # v0.0.4
|
||||||
|
|||||||
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
@@ -1,5 +1,8 @@
|
|||||||
name: test
|
name: test
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
@@ -17,16 +20,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: Test
|
name: Test
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0
|
||||||
with:
|
with:
|
||||||
source: .
|
source: .
|
||||||
targets: test
|
targets: test
|
||||||
-
|
-
|
||||||
name: Upload coverage
|
name: Upload coverage
|
||||||
uses: codecov/codecov-action@v5
|
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
|
||||||
with:
|
with:
|
||||||
files: ./coverage/clover.xml
|
files: ./coverage/clover.xml
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|||||||
56
.github/workflows/update-dist.yml
vendored
Normal file
56
.github/workflows/update-dist.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
name: update-dist
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-dist:
|
||||||
|
if: github.actor == 'dependabot[bot]' && github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == github.event.pull_request.head.repo.full_name
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: GitHub auth token from GitHub App
|
||||||
|
id: docker-read-app
|
||||||
|
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.GHACTIONS_REPO_WRITE_APP_ID }}
|
||||||
|
private-key: ${{ secrets.GHACTIONS_REPO_WRITE_APP_PRIVATE_KEY }}
|
||||||
|
owner: docker
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.ref }}
|
||||||
|
fetch-depth: 0
|
||||||
|
token: ${{ steps.docker-read-app.outputs.token }}
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: docker/bake-action@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0
|
||||||
|
with:
|
||||||
|
source: .
|
||||||
|
targets: build
|
||||||
|
-
|
||||||
|
name: Commit and push dist
|
||||||
|
run: |
|
||||||
|
if [ -n "$(git status --porcelain -- dist)" ]; then
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
|
git add dist
|
||||||
|
git commit -m "chore: update generated content"
|
||||||
|
git push
|
||||||
|
)
|
||||||
|
else
|
||||||
|
echo "No changes in dist"
|
||||||
|
fi
|
||||||
15
.github/workflows/validate.yml
vendored
15
.github/workflows/validate.yml
vendored
@@ -1,5 +1,8 @@
|
|||||||
name: validate
|
name: validate
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
@@ -15,15 +18,15 @@ jobs:
|
|||||||
prepare:
|
prepare:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
targets: ${{ steps.generate.outputs.targets }}
|
matrix: ${{ steps.generate.outputs.matrix }}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
-
|
-
|
||||||
name: List targets
|
name: Generate matrix
|
||||||
id: generate
|
id: generate
|
||||||
uses: docker/bake-action/subaction/list-targets@v6
|
uses: docker/bake-action/subaction/matrix@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0
|
||||||
with:
|
with:
|
||||||
target: validate
|
target: validate
|
||||||
|
|
||||||
@@ -34,10 +37,10 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
target: ${{ fromJson(needs.prepare.outputs.targets) }}
|
include: ${{ fromJson(needs.prepare.outputs.matrix) }}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Validate
|
name: Validate
|
||||||
uses: docker/bake-action@v6
|
uses: docker/bake-action@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0
|
||||||
with:
|
with:
|
||||||
targets: ${{ matrix.target }}
|
targets: ${{ matrix.target }}
|
||||||
|
|||||||
29
.github/workflows/zizmor.yml
vendored
Normal file
29
.github/workflows/zizmor.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: zizmor
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
- 'releases/v*'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
zizmor:
|
||||||
|
uses: crazy-max/.github/.github/workflows/zizmor.yml@4a17dbaa9ce13920fc5bb8824eb89c16301e5ab2 # v1.7.0
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
with:
|
||||||
|
min-severity: medium
|
||||||
|
min-confidence: medium
|
||||||
|
persona: pedantic
|
||||||
@@ -6,6 +6,5 @@
|
|||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "none",
|
"trailingComma": "none",
|
||||||
"bracketSpacing": false,
|
"bracketSpacing": false,
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid"
|
||||||
"parser": "typescript"
|
|
||||||
}
|
}
|
||||||
|
|||||||
99
README.md
99
README.md
@@ -25,6 +25,7 @@ ___
|
|||||||
* [Quay.io](#quayio)
|
* [Quay.io](#quayio)
|
||||||
* [DigitalOcean](#digitalocean-container-registry)
|
* [DigitalOcean](#digitalocean-container-registry)
|
||||||
* [Authenticate to multiple registries](#authenticate-to-multiple-registries)
|
* [Authenticate to multiple registries](#authenticate-to-multiple-registries)
|
||||||
|
* [Set scopes for the authentication token](#set-scopes-for-the-authentication-token)
|
||||||
* [Customizing](#customizing)
|
* [Customizing](#customizing)
|
||||||
* [inputs](#inputs)
|
* [inputs](#inputs)
|
||||||
* [Contributing](#contributing)
|
* [Contributing](#contributing)
|
||||||
@@ -50,7 +51,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to Docker Hub
|
name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
username: ${{ vars.DOCKERHUB_USERNAME }}
|
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
@@ -75,7 +76,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to GitHub Container Registry
|
name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -103,7 +104,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to GitLab
|
name: Login to GitLab
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: registry.gitlab.com
|
registry: registry.gitlab.com
|
||||||
username: ${{ vars.GITLAB_USERNAME }}
|
username: ${{ vars.GITLAB_USERNAME }}
|
||||||
@@ -134,7 +135,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to ACR
|
name: Login to ACR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: <registry-name>.azurecr.io
|
registry: <registry-name>.azurecr.io
|
||||||
username: ${{ vars.AZURE_CLIENT_ID }}
|
username: ${{ vars.AZURE_CLIENT_ID }}
|
||||||
@@ -182,7 +183,7 @@ jobs:
|
|||||||
service_account: <service_account>
|
service_account: <service_account>
|
||||||
-
|
-
|
||||||
name: Login to GCR
|
name: Login to GCR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: gcr.io
|
registry: gcr.io
|
||||||
username: oauth2accesstoken
|
username: oauth2accesstoken
|
||||||
@@ -215,7 +216,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to GCR
|
name: Login to GCR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: gcr.io
|
registry: gcr.io
|
||||||
username: _json_key
|
username: _json_key
|
||||||
@@ -253,7 +254,7 @@ jobs:
|
|||||||
service_account: <service_account>
|
service_account: <service_account>
|
||||||
-
|
-
|
||||||
name: Login to GAR
|
name: Login to GAR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: <location>-docker.pkg.dev
|
registry: <location>-docker.pkg.dev
|
||||||
username: oauth2accesstoken
|
username: oauth2accesstoken
|
||||||
@@ -290,7 +291,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to GAR
|
name: Login to GAR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: <location>-docker.pkg.dev
|
registry: <location>-docker.pkg.dev
|
||||||
username: _json_key
|
username: _json_key
|
||||||
@@ -319,7 +320,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to ECR
|
name: Login to ECR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
||||||
username: ${{ vars.AWS_ACCESS_KEY_ID }}
|
username: ${{ vars.AWS_ACCESS_KEY_ID }}
|
||||||
@@ -342,7 +343,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to ECR
|
name: Login to ECR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
||||||
username: ${{ vars.AWS_ACCESS_KEY_ID }}
|
username: ${{ vars.AWS_ACCESS_KEY_ID }}
|
||||||
@@ -376,7 +377,7 @@ jobs:
|
|||||||
aws-region: <region>
|
aws-region: <region>
|
||||||
-
|
-
|
||||||
name: Login to ECR
|
name: Login to ECR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
|
||||||
```
|
```
|
||||||
@@ -403,7 +404,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to Public ECR
|
name: Login to Public ECR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: public.ecr.aws
|
registry: public.ecr.aws
|
||||||
username: ${{ vars.AWS_ACCESS_KEY_ID }}
|
username: ${{ vars.AWS_ACCESS_KEY_ID }}
|
||||||
@@ -437,7 +438,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to OCIR
|
name: Login to OCIR
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: <region>.ocir.io
|
registry: <region>.ocir.io
|
||||||
username: ${{ vars.OCI_USERNAME }}
|
username: ${{ vars.OCI_USERNAME }}
|
||||||
@@ -464,7 +465,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to Quay.io
|
name: Login to Quay.io
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: quay.io
|
registry: quay.io
|
||||||
username: ${{ vars.QUAY_USERNAME }}
|
username: ${{ vars.QUAY_USERNAME }}
|
||||||
@@ -488,7 +489,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to DigitalOcean Container Registry
|
name: Login to DigitalOcean Container Registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: registry.digitalocean.com
|
registry: registry.digitalocean.com
|
||||||
username: ${{ vars.DIGITALOCEAN_USERNAME }}
|
username: ${{ vars.DIGITALOCEAN_USERNAME }}
|
||||||
@@ -513,13 +514,13 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to Docker Hub
|
name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
username: ${{ vars.DOCKERHUB_USERNAME }}
|
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
-
|
-
|
||||||
name: Login to GitHub Container Registry
|
name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -527,8 +528,8 @@ jobs:
|
|||||||
```
|
```
|
||||||
|
|
||||||
You can also use the `registry-auth` input for raw authentication to
|
You can also use the `registry-auth` input for raw authentication to
|
||||||
registries, defined as YAML objects. Each object can contain `registry`,
|
registries, defined as YAML objects. Each object have the same attributes as
|
||||||
`username`, `password` and `ecr` keys similar to current inputs:
|
current inputs (except `logout`):
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> We don't recommend using this method, it's better to use the action multiple
|
> We don't recommend using this method, it's better to use the action multiple
|
||||||
@@ -547,7 +548,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Login to registries
|
name: Login to registries
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
registry-auth: |
|
registry-auth: |
|
||||||
- username: ${{ vars.DOCKERHUB_USERNAME }}
|
- username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||||
@@ -557,6 +558,60 @@ jobs:
|
|||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Set scopes for the authentication token
|
||||||
|
|
||||||
|
The `scope` input allows limiting registry credentials to a specific repository
|
||||||
|
or namespace scope when building images with Buildx.
|
||||||
|
|
||||||
|
This is useful in GitHub Actions to avoid overriding the Docker Hub
|
||||||
|
authentication token embedded in GitHub-hosted runners, which is used for
|
||||||
|
pulling images without rate limits. By scoping credentials, you can
|
||||||
|
authenticate only where needed (typically for pushing), while keeping
|
||||||
|
unauthenticated pulls for base images.
|
||||||
|
|
||||||
|
When `scope` is set, credentials are written to the Buildx configuration
|
||||||
|
instead of the global Docker configuration. This means:
|
||||||
|
* Authentication applies only to the specified scope
|
||||||
|
* The default Docker Hub credentials remain available for pulls
|
||||||
|
* Credentials are used only by Buildx during the build
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> Credentials written to the Buildx configuration are only accessible by Buildx.
|
||||||
|
> They are not available to `docker pull`, `docker push`, or any other Docker
|
||||||
|
> CLI commands outside Buildx.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This feature requires Buildx version 0.31.0 or later.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
login:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub (scoped)
|
||||||
|
uses: docker/login-action@v4
|
||||||
|
with:
|
||||||
|
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
scope: 'myorg/myimage@push'
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: myorg/myimage:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, base images are pulled using the embedded GitHub-hosted runner
|
||||||
|
credentials, while authenticated access is used only to push `myorg/myimage`.
|
||||||
|
|
||||||
## Customizing
|
## Customizing
|
||||||
|
|
||||||
### inputs
|
### inputs
|
||||||
@@ -568,13 +623,13 @@ The following inputs can be used as `step.with` keys:
|
|||||||
| `registry` | String | `docker.io` | Server address of Docker registry. If not set then will default to Docker Hub |
|
| `registry` | String | `docker.io` | Server address of Docker registry. If not set then will default to Docker Hub |
|
||||||
| `username` | String | | Username for authenticating to the Docker registry |
|
| `username` | String | | Username for authenticating to the Docker registry |
|
||||||
| `password` | String | | Password or personal access token for authenticating the Docker registry |
|
| `password` | String | | Password or personal access token for authenticating the Docker registry |
|
||||||
|
| `scope` | String | | Scope for the authentication token |
|
||||||
| `ecr` | String | `auto` | Specifies whether the given registry is ECR (`auto`, `true` or `false`) |
|
| `ecr` | String | `auto` | Specifies whether the given registry is ECR (`auto`, `true` or `false`) |
|
||||||
| `logout` | Bool | `true` | Log out from the Docker registry at the end of a job |
|
| `logout` | Bool | `true` | Log out from the Docker registry at the end of a job |
|
||||||
| `registry-auth` | YAML | | Raw authentication to registries, defined as YAML objects |
|
| `registry-auth` | YAML | | Raw authentication to registries, defined as YAML objects |
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> The `registry-auth` input is mutually exclusive with `registry`, `username`,
|
> The `registry-auth` input cannot be used with other inputs except `logout`.
|
||||||
> `password` and `ecr` inputs.
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {beforeEach, describe, expect, jest, test} from '@jest/globals';
|
import {beforeEach, describe, expect, test, vi} from 'vitest';
|
||||||
import {AuthorizationData} from '@aws-sdk/client-ecr';
|
import {AuthorizationData} from '@aws-sdk/client-ecr';
|
||||||
|
|
||||||
import * as aws from '../src/aws';
|
import * as aws from '../src/aws.js';
|
||||||
|
|
||||||
describe('isECR', () => {
|
describe('isECR', () => {
|
||||||
test.each([
|
test.each([
|
||||||
@@ -11,6 +11,7 @@ describe('isECR', () => {
|
|||||||
['876820548815.dkr.ecr.cn-north-1.amazonaws.com.cn', true],
|
['876820548815.dkr.ecr.cn-north-1.amazonaws.com.cn', true],
|
||||||
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', true],
|
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', true],
|
||||||
['012345678901.dkr-ecr.eu-north-1.on.aws', true],
|
['012345678901.dkr-ecr.eu-north-1.on.aws', true],
|
||||||
|
['012345678901.dkr.ecr.eusc-de-east-1.amazonaws.eu', true],
|
||||||
['public.ecr.aws', true],
|
['public.ecr.aws', true],
|
||||||
['ecr-public.aws.com', true]
|
['ecr-public.aws.com', true]
|
||||||
])('given registry %p', async (registry, expected) => {
|
])('given registry %p', async (registry, expected) => {
|
||||||
@@ -26,6 +27,7 @@ describe('isPubECR', () => {
|
|||||||
['876820548815.dkr.ecr.cn-north-1.amazonaws.com.cn', false],
|
['876820548815.dkr.ecr.cn-north-1.amazonaws.com.cn', false],
|
||||||
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', false],
|
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', false],
|
||||||
['012345678901.dkr-ecr.eu-north-1.on.aws', false],
|
['012345678901.dkr-ecr.eu-north-1.on.aws', false],
|
||||||
|
['012345678901.dkr.ecr.eusc-de-east-1.amazonaws.eu', false],
|
||||||
['public.ecr.aws', true],
|
['public.ecr.aws', true],
|
||||||
['ecr-public.aws.com', true]
|
['ecr-public.aws.com', true]
|
||||||
])('given registry %p', async (registry, expected) => {
|
])('given registry %p', async (registry, expected) => {
|
||||||
@@ -39,6 +41,7 @@ describe('getRegion', () => {
|
|||||||
['876820548815.dkr.ecr.cn-north-1.amazonaws.com.cn', 'cn-north-1'],
|
['876820548815.dkr.ecr.cn-north-1.amazonaws.com.cn', 'cn-north-1'],
|
||||||
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', 'cn-northwest-1'],
|
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', 'cn-northwest-1'],
|
||||||
['012345678901.dkr-ecr.eu-north-1.on.aws', 'eu-north-1'],
|
['012345678901.dkr-ecr.eu-north-1.on.aws', 'eu-north-1'],
|
||||||
|
['012345678901.dkr.ecr.eusc-de-east-1.amazonaws.eu', 'eusc-de-east-1'],
|
||||||
['public.ecr.aws', 'us-east-1']
|
['public.ecr.aws', 'us-east-1']
|
||||||
])('given registry %p', async (registry, expected) => {
|
])('given registry %p', async (registry, expected) => {
|
||||||
expect(aws.getRegion(registry)).toEqual(expected);
|
expect(aws.getRegion(registry)).toEqual(expected);
|
||||||
@@ -52,6 +55,7 @@ describe('getAccountIDs', () => {
|
|||||||
['012345678901.dkr.ecr.eu-west-3.amazonaws.com', '012345678901,012345678910,023456789012', ['012345678901', '012345678910', '023456789012']],
|
['012345678901.dkr.ecr.eu-west-3.amazonaws.com', '012345678901,012345678910,023456789012', ['012345678901', '012345678910', '023456789012']],
|
||||||
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', '012345678910,023456789012', ['390948362332', '012345678910', '023456789012']],
|
['390948362332.dkr.ecr.cn-northwest-1.amazonaws.com.cn', '012345678910,023456789012', ['390948362332', '012345678910', '023456789012']],
|
||||||
['876820548815.dkr-ecr.eu-north-1.on.aws', '012345678910,023456789012', ['876820548815', '012345678910', '023456789012']],
|
['876820548815.dkr-ecr.eu-north-1.on.aws', '012345678910,023456789012', ['876820548815', '012345678910', '023456789012']],
|
||||||
|
['012345678901.dkr.ecr.eusc-de-east-1.amazonaws.eu', '012345678910,023456789012', ['012345678901', '012345678910', '023456789012']],
|
||||||
['public.ecr.aws', undefined, []]
|
['public.ecr.aws', undefined, []]
|
||||||
])('given registry %p', async (registry, accountIDsEnv, expected) => {
|
])('given registry %p', async (registry, accountIDsEnv, expected) => {
|
||||||
if (accountIDsEnv) {
|
if (accountIDsEnv) {
|
||||||
@@ -61,26 +65,28 @@ describe('getAccountIDs', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockEcrGetAuthToken = jest.fn();
|
const mockEcrGetAuthToken = vi.fn();
|
||||||
const mockEcrPublicGetAuthToken = jest.fn();
|
const mockEcrPublicGetAuthToken = vi.fn();
|
||||||
jest.mock('@aws-sdk/client-ecr', () => {
|
vi.mock('@aws-sdk/client-ecr', () => {
|
||||||
|
class ECR {
|
||||||
|
getAuthorizationToken = mockEcrGetAuthToken;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
ECR: jest.fn(() => ({
|
ECR
|
||||||
getAuthorizationToken: mockEcrGetAuthToken
|
|
||||||
}))
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
jest.mock('@aws-sdk/client-ecr-public', () => {
|
vi.mock('@aws-sdk/client-ecr-public', () => {
|
||||||
|
class ECRPUBLIC {
|
||||||
|
getAuthorizationToken = mockEcrPublicGetAuthToken;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
ECRPUBLIC: jest.fn(() => ({
|
ECRPUBLIC
|
||||||
getAuthorizationToken: mockEcrPublicGetAuthToken
|
|
||||||
}))
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getRegistriesData', () => {
|
describe('getRegistriesData', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
delete process.env.AWS_ACCOUNT_IDS;
|
delete process.env.AWS_ACCOUNT_IDS;
|
||||||
});
|
});
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
import {expect, test} from '@jest/globals';
|
import {afterEach, expect, test} from 'vitest';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
import {getInputs} from '../src/context';
|
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js';
|
||||||
|
|
||||||
|
import {getAuthList, getInputs} from '../src/context.js';
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
for (const key of Object.keys(process.env)) {
|
||||||
|
if (key.startsWith('INPUT_')) {
|
||||||
|
delete process.env[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('with password and username getInputs does not throw error', async () => {
|
test('with password and username getInputs does not throw error', async () => {
|
||||||
process.env['INPUT_USERNAME'] = 'dbowie';
|
process.env['INPUT_USERNAME'] = 'dbowie';
|
||||||
@@ -10,3 +21,15 @@ test('with password and username getInputs does not throw error', async () => {
|
|||||||
getInputs();
|
getInputs();
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getAuthList uses the default Docker Hub registry when computing scoped config dir', async () => {
|
||||||
|
process.env['INPUT_USERNAME'] = 'dbowie';
|
||||||
|
process.env['INPUT_PASSWORD'] = 'groundcontrol';
|
||||||
|
process.env['INPUT_SCOPE'] = 'myscope';
|
||||||
|
process.env['INPUT_LOGOUT'] = 'false';
|
||||||
|
const [auth] = getAuthList(getInputs());
|
||||||
|
expect(auth).toMatchObject({
|
||||||
|
registry: 'docker.io',
|
||||||
|
configDir: path.join(Buildx.configDir, 'config', 'registry-1.docker.io', 'myscope')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
import {expect, jest, test} from '@jest/globals';
|
import {expect, test, vi} from 'vitest';
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
import {loginStandard, logout} from '../src/docker';
|
import {Docker} from '@docker/actions-toolkit/lib/docker/docker.js';
|
||||||
|
|
||||||
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
|
import {loginStandard, logout} from '../src/docker.js';
|
||||||
|
|
||||||
process.env['RUNNER_TEMP'] = path.join(__dirname, 'runner');
|
|
||||||
|
|
||||||
test('loginStandard calls exec', async () => {
|
test('loginStandard calls exec', async () => {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
const execSpy = vi.spyOn(Docker, 'getExecOutput').mockImplementation(async () => {
|
||||||
// @ts-ignore
|
|
||||||
const execSpy = jest.spyOn(Docker, 'getExecOutput').mockImplementation(async () => {
|
|
||||||
return {
|
return {
|
||||||
exitCode: expect.any(Number),
|
exitCode: expect.any(Number),
|
||||||
stdout: expect.any(Function),
|
stdout: expect.any(Function),
|
||||||
@@ -38,9 +33,7 @@ test('loginStandard calls exec', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('logout calls exec', async () => {
|
test('logout calls exec', async () => {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
const execSpy = vi.spyOn(Docker, 'getExecOutput').mockImplementation(async () => {
|
||||||
// @ts-ignore
|
|
||||||
const execSpy = jest.spyOn(Docker, 'getExecOutput').mockImplementation(async () => {
|
|
||||||
return {
|
return {
|
||||||
exitCode: expect.any(Number),
|
exitCode: expect.any(Number),
|
||||||
stdout: expect.any(Function),
|
stdout: expect.any(Function),
|
||||||
@@ -50,7 +43,7 @@ test('logout calls exec', async () => {
|
|||||||
|
|
||||||
const registry = 'https://ghcr.io';
|
const registry = 'https://ghcr.io';
|
||||||
|
|
||||||
await logout(registry);
|
await logout(registry, '');
|
||||||
|
|
||||||
expect(execSpy).toHaveBeenCalledTimes(1);
|
expect(execSpy).toHaveBeenCalledTimes(1);
|
||||||
const callfunc = execSpy.mock.calls[0];
|
const callfunc = execSpy.mock.calls[0];
|
||||||
|
|||||||
12
__tests__/setup.unit.ts
Normal file
12
__tests__/setup.unit.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import fs from 'node:fs';
|
||||||
|
import os from 'node:os';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-login-action-'));
|
||||||
|
|
||||||
|
process.env = Object.assign({}, process.env, {
|
||||||
|
TEMP: tmpDir,
|
||||||
|
GITHUB_REPOSITORY: 'docker/login-action',
|
||||||
|
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
|
||||||
|
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
|
||||||
|
});
|
||||||
@@ -19,6 +19,9 @@ inputs:
|
|||||||
ecr:
|
ecr:
|
||||||
description: 'Specifies whether the given registry is ECR (auto, true or false)'
|
description: 'Specifies whether the given registry is ECR (auto, true or false)'
|
||||||
required: false
|
required: false
|
||||||
|
scope:
|
||||||
|
description: 'Scope for the authentication token'
|
||||||
|
required: false
|
||||||
logout:
|
logout:
|
||||||
description: 'Log out from the Docker registry at the end of a job'
|
description: 'Log out from the Docker registry at the end of a job'
|
||||||
default: 'true'
|
default: 'true'
|
||||||
@@ -28,6 +31,6 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: 'node20'
|
using: 'node24'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.cjs'
|
||||||
post: 'dist/index.js'
|
post: 'dist/index.cjs'
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG NODE_VERSION=20
|
ARG NODE_VERSION=24
|
||||||
|
|
||||||
FROM node:${NODE_VERSION}-alpine AS base
|
FROM node:${NODE_VERSION}-alpine AS base
|
||||||
RUN apk add --no-cache cpio findutils git
|
RUN apk add --no-cache cpio findutils git rsync
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache <<EOT
|
--mount=type=cache,target=/src/.yarn/cache <<EOT
|
||||||
|
set -e
|
||||||
corepack enable
|
corepack enable
|
||||||
yarn --version
|
yarn --version
|
||||||
yarn config set --home enableTelemetry 0
|
yarn config set --home enableTelemetry 0
|
||||||
@@ -34,18 +35,27 @@ RUN --mount=type=bind,target=.,rw <<EOT
|
|||||||
EOT
|
EOT
|
||||||
|
|
||||||
FROM deps AS build
|
FROM deps AS build
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=target=/context \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
--mount=type=cache,target=/src/.yarn/cache \
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules <<EOT
|
||||||
yarn run build && mkdir /out && cp -Rf dist /out/
|
set -e
|
||||||
|
rsync -a /context/. .
|
||||||
|
rm -rf dist
|
||||||
|
yarn run build
|
||||||
|
mkdir /out
|
||||||
|
cp -r dist /out
|
||||||
|
EOT
|
||||||
|
|
||||||
FROM scratch AS build-update
|
FROM scratch AS build-update
|
||||||
COPY --from=build /out /
|
COPY --from=build /out /
|
||||||
|
|
||||||
FROM build AS build-validate
|
FROM build AS build-validate
|
||||||
RUN --mount=type=bind,target=.,rw <<EOT
|
RUN --mount=target=/context \
|
||||||
|
--mount=target=.,type=tmpfs <<EOT
|
||||||
set -e
|
set -e
|
||||||
|
rsync -a /context/. .
|
||||||
git add -A
|
git add -A
|
||||||
|
rm -rf dist
|
||||||
cp -rf /out/* .
|
cp -rf /out/* .
|
||||||
if [ -n "$(git status --porcelain -- dist)" ]; then
|
if [ -n "$(git status --porcelain -- dist)" ]; then
|
||||||
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
|
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
|
||||||
@@ -58,8 +68,7 @@ FROM deps AS format
|
|||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
--mount=type=cache,target=/src/.yarn/cache \
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn run format \
|
yarn run format && mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out
|
||||||
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out
|
|
||||||
|
|
||||||
FROM scratch AS format-update
|
FROM scratch AS format-update
|
||||||
COPY --from=format /out /
|
COPY --from=format /out /
|
||||||
@@ -76,7 +85,7 @@ ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
|
|||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/.yarn/cache \
|
--mount=type=cache,target=/src/.yarn/cache \
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
yarn run test --coverage --coverageDirectory=/tmp/coverage
|
yarn run test --coverage --coverage.reportsDirectory=/tmp/coverage
|
||||||
|
|
||||||
FROM scratch AS test-coverage
|
FROM scratch AS test-coverage
|
||||||
COPY --from=test /tmp/coverage /
|
COPY --from=test /tmp/coverage /
|
||||||
|
|||||||
236
dist/index.cjs
generated
vendored
Normal file
236
dist/index.cjs
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
7
dist/index.cjs.map
generated
vendored
Normal file
7
dist/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
103
dist/index.js
generated
vendored
103
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
1
dist/index.js.map
generated
vendored
1
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
20400
dist/licenses.txt
generated
vendored
20400
dist/licenses.txt
generated
vendored
File diff suppressed because it is too large
Load Diff
1
dist/sourcemap-register.js
generated
vendored
1
dist/sourcemap-register.js
generated
vendored
File diff suppressed because one or more lines are too long
52
eslint.config.mjs
Normal file
52
eslint.config.mjs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import {defineConfig} from 'eslint/config';
|
||||||
|
import js from '@eslint/js';
|
||||||
|
import tseslint from '@typescript-eslint/eslint-plugin';
|
||||||
|
import vitest from '@vitest/eslint-plugin';
|
||||||
|
import globals from 'globals';
|
||||||
|
import eslintConfigPrettier from 'eslint-config-prettier/flat';
|
||||||
|
import eslintPluginPrettier from 'eslint-plugin-prettier';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
ignores: ['.yarn/**/*', 'coverage/**/*', 'dist/**/*']
|
||||||
|
},
|
||||||
|
js.configs.recommended,
|
||||||
|
...tseslint.configs['flat/recommended'],
|
||||||
|
eslintConfigPrettier,
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['__tests__/**'],
|
||||||
|
...vitest.configs.recommended,
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
...vitest.environments.env.globals
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...vitest.configs.recommended.rules,
|
||||||
|
'vitest/no-conditional-expect': 'error',
|
||||||
|
'vitest/no-disabled-tests': 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
prettier: eslintPluginPrettier
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'prettier/prettier': 'error',
|
||||||
|
'@typescript-eslint/no-require-imports': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
allowAsImport: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
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,
|
|
||||||
testEnvironment: 'node',
|
|
||||||
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
|
|
||||||
};
|
|
||||||
56
package.json
56
package.json
@@ -1,16 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "docker-login",
|
"name": "docker-login",
|
||||||
"description": "GitHub Action to login against a Docker registry",
|
"description": "GitHub Action to login against a Docker registry",
|
||||||
|
"type": "module",
|
||||||
"main": "src/main.ts",
|
"main": "src/main.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "ncc build --source-map --minify --license licenses.txt",
|
"build": "esbuild src/main.ts --bundle --platform=node --target=node24 --format=cjs --outfile=dist/index.cjs --sourcemap --minify && yarn run license",
|
||||||
"lint": "yarn run prettier && yarn run eslint",
|
"lint": "eslint --max-warnings=0 .",
|
||||||
"format": "yarn run prettier:fix && yarn run eslint:fix",
|
"format": "eslint --fix .",
|
||||||
"eslint": "eslint --max-warnings=0 .",
|
"test": "vitest run",
|
||||||
"eslint:fix": "eslint --fix .",
|
"license": "generate-license-file --input package.json --output dist/licenses.txt --overwrite --ci --no-spinner --eol lf"
|
||||||
"prettier": "prettier --check \"./**/*.ts\"",
|
|
||||||
"prettier:fix": "prettier --write \"./**/*.ts\"",
|
|
||||||
"test": "jest"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -25,28 +23,30 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"packageManager": "yarn@4.9.2",
|
"packageManager": "yarn@4.9.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^3.0.0",
|
||||||
"@aws-sdk/client-ecr": "^3.890.0",
|
"@aws-sdk/client-ecr": "^3.1020.0",
|
||||||
"@aws-sdk/client-ecr-public": "^3.890.0",
|
"@aws-sdk/client-ecr-public": "^3.1020.0",
|
||||||
"@docker/actions-toolkit": "^0.63.0",
|
"@docker/actions-toolkit": "^0.86.0",
|
||||||
"http-proxy-agent": "^7.0.2",
|
"http-proxy-agent": "^9.0.0",
|
||||||
"https-proxy-agent": "^7.0.6",
|
"https-proxy-agent": "^9.0.0",
|
||||||
"js-yaml": "^4.1.0"
|
"js-yaml": "^4.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.39.3",
|
||||||
"@types/js-yaml": "^4.0.9",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"@types/node": "^20.19.9",
|
"@types/node": "^24.11.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
||||||
"@typescript-eslint/parser": "^7.18.0",
|
"@typescript-eslint/parser": "^8.56.1",
|
||||||
"@vercel/ncc": "^0.38.3",
|
"@vitest/coverage-v8": "^4.0.18",
|
||||||
"eslint": "^8.57.1",
|
"@vitest/eslint-plugin": "^1.6.9",
|
||||||
"eslint-config-prettier": "^9.1.2",
|
"esbuild": "^0.28.0",
|
||||||
"eslint-plugin-jest": "^28.14.0",
|
"eslint": "^9.39.3",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"jest": "^29.7.0",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"prettier": "^3.6.2",
|
"generate-license-file": "^4.1.1",
|
||||||
"ts-jest": "^29.4.1",
|
"globals": "^17.3.0",
|
||||||
"ts-node": "^10.9.2",
|
"prettier": "^3.8.1",
|
||||||
"typescript": "^5.9.2"
|
"typescript": "^5.9.3",
|
||||||
|
"vitest": "^4.0.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {NodeHttpHandler} from '@smithy/node-http-handler';
|
|||||||
import {HttpProxyAgent} from 'http-proxy-agent';
|
import {HttpProxyAgent} from 'http-proxy-agent';
|
||||||
import {HttpsProxyAgent} from 'https-proxy-agent';
|
import {HttpsProxyAgent} from 'https-proxy-agent';
|
||||||
|
|
||||||
const ecrRegistryRegex = /^(([0-9]{12})\.(dkr\.ecr|dkr-ecr)\.(.+)\.(on\.aws|amazonaws\.com(.cn)?))(\/([^:]+)(:.+)?)?$/;
|
const ecrRegistryRegex = /^(([0-9]{12})\.(dkr\.ecr|dkr-ecr)\.(.+)\.(on\.aws|amazonaws\.(com(.cn)?|eu)))(\/([^:]+)(:.+)?)?$/;
|
||||||
const ecrPublicRegistryRegex = /public\.ecr\.aws|ecr-public\.aws\.com/;
|
const ecrPublicRegistryRegex = /public\.ecr\.aws|ecr-public\.aws\.com/;
|
||||||
|
|
||||||
export const isECR = (registry: string): boolean => {
|
export const isECR = (registry: string): boolean => {
|
||||||
|
|||||||
@@ -1,21 +1,92 @@
|
|||||||
|
import path from 'path';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
import * as yaml from 'js-yaml';
|
||||||
|
|
||||||
|
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js';
|
||||||
|
import {Util} from '@docker/actions-toolkit/lib/util.js';
|
||||||
|
|
||||||
export interface Inputs {
|
export interface Inputs {
|
||||||
registry: string;
|
registry: string;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
|
scope: string;
|
||||||
ecr: string;
|
ecr: string;
|
||||||
logout: boolean;
|
logout: boolean;
|
||||||
registryAuth: string;
|
registryAuth: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Auth {
|
||||||
|
registry: string;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
scope: string;
|
||||||
|
ecr: string;
|
||||||
|
configDir: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function getInputs(): Inputs {
|
export function getInputs(): Inputs {
|
||||||
return {
|
return {
|
||||||
registry: core.getInput('registry'),
|
registry: core.getInput('registry'),
|
||||||
username: core.getInput('username'),
|
username: core.getInput('username'),
|
||||||
password: core.getInput('password'),
|
password: core.getInput('password'),
|
||||||
|
scope: core.getInput('scope'),
|
||||||
ecr: core.getInput('ecr'),
|
ecr: core.getInput('ecr'),
|
||||||
logout: core.getBooleanInput('logout'),
|
logout: core.getBooleanInput('logout'),
|
||||||
registryAuth: core.getInput('registry-auth')
|
registryAuth: core.getInput('registry-auth')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAuthList(inputs: Inputs): Array<Auth> {
|
||||||
|
if (inputs.registryAuth && (inputs.registry || inputs.username || inputs.password || inputs.scope || inputs.ecr)) {
|
||||||
|
throw new Error('Cannot use registry-auth with other inputs');
|
||||||
|
}
|
||||||
|
let auths: Array<Auth> = [];
|
||||||
|
if (!inputs.registryAuth) {
|
||||||
|
const registry = inputs.registry || 'docker.io';
|
||||||
|
auths.push({
|
||||||
|
registry,
|
||||||
|
username: inputs.username,
|
||||||
|
password: inputs.password,
|
||||||
|
scope: inputs.scope,
|
||||||
|
ecr: inputs.ecr || 'auto',
|
||||||
|
configDir: scopeToConfigDir(registry, inputs.scope)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
auths = (yaml.load(inputs.registryAuth) as Array<Auth>).map(auth => {
|
||||||
|
core.setSecret(auth.password); // redacted in workflow logs
|
||||||
|
const registry = auth.registry || 'docker.io';
|
||||||
|
return {
|
||||||
|
registry,
|
||||||
|
username: auth.username,
|
||||||
|
password: auth.password,
|
||||||
|
scope: auth.scope,
|
||||||
|
ecr: auth.ecr || 'auto',
|
||||||
|
configDir: scopeToConfigDir(registry, auth.scope)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (auths.length == 0) {
|
||||||
|
throw new Error('No registry to login');
|
||||||
|
}
|
||||||
|
return auths;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function scopeToConfigDir(registry: string, scope?: string): string {
|
||||||
|
if (scopeDisabled() || !scope || scope === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
let configDir = path.join(Buildx.configDir, 'config', registry === 'docker.io' ? 'registry-1.docker.io' : registry);
|
||||||
|
if (scope.startsWith('@')) {
|
||||||
|
configDir += scope;
|
||||||
|
} else {
|
||||||
|
configDir = path.join(configDir, scope);
|
||||||
|
}
|
||||||
|
return configDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scopeDisabled(): boolean {
|
||||||
|
if (process.env.DOCKER_LOGIN_SCOPE_DISABLED) {
|
||||||
|
return Util.parseBool(process.env.DOCKER_LOGIN_SCOPE_DISABLED);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,19 +1,31 @@
|
|||||||
import * as aws from './aws';
|
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
|
import {Docker} from '@docker/actions-toolkit/lib/docker/docker.js';
|
||||||
|
|
||||||
export async function login(registry: string, username: string, password: string, ecr: string): Promise<void> {
|
import * as aws from './aws.js';
|
||||||
if (/true/i.test(ecr) || (ecr == 'auto' && aws.isECR(registry))) {
|
import * as context from './context.js';
|
||||||
await loginECR(registry, username, password);
|
|
||||||
|
export async function login(auth: context.Auth): Promise<void> {
|
||||||
|
if (/true/i.test(auth.ecr) || (auth.ecr == 'auto' && aws.isECR(auth.registry))) {
|
||||||
|
await loginECR(auth.registry, auth.username, auth.password, auth.scope);
|
||||||
} else {
|
} else {
|
||||||
await loginStandard(registry, username, password);
|
await loginStandard(auth.registry, auth.username, auth.password, auth.scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function logout(registry: string): Promise<void> {
|
export async function logout(registry: string, configDir: string): Promise<void> {
|
||||||
|
let envs: {[key: string]: string} | undefined;
|
||||||
|
if (configDir !== '') {
|
||||||
|
envs = Object.assign({}, process.env, {
|
||||||
|
DOCKER_CONFIG: configDir
|
||||||
|
}) as {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
core.info(`Alternative config dir: ${configDir}`);
|
||||||
|
}
|
||||||
await Docker.getExecOutput(['logout', registry], {
|
await Docker.getExecOutput(['logout', registry], {
|
||||||
ignoreReturnCode: true
|
ignoreReturnCode: true,
|
||||||
|
env: envs
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||||
core.warning(res.stderr.trim());
|
core.warning(res.stderr.trim());
|
||||||
@@ -21,7 +33,7 @@ export async function logout(registry: string): Promise<void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loginStandard(registry: string, username: string, password: string): Promise<void> {
|
export async function loginStandard(registry: string, username: string, password: string, scope?: string): Promise<void> {
|
||||||
if (!username && !password) {
|
if (!username && !password) {
|
||||||
throw new Error('Username and password required');
|
throw new Error('Username and password required');
|
||||||
}
|
}
|
||||||
@@ -31,38 +43,39 @@ export async function loginStandard(registry: string, username: string, password
|
|||||||
if (!password) {
|
if (!password) {
|
||||||
throw new Error('Password required');
|
throw new Error('Password required');
|
||||||
}
|
}
|
||||||
|
await loginExec(registry, username, password, scope);
|
||||||
const loginArgs: Array<string> = ['login', '--password-stdin'];
|
|
||||||
loginArgs.push('--username', username);
|
|
||||||
loginArgs.push(registry);
|
|
||||||
|
|
||||||
core.info(`Logging into ${registry}...`);
|
|
||||||
await Docker.getExecOutput(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> {
|
export async function loginECR(registry: string, username: string, password: string, scope?: string): Promise<void> {
|
||||||
core.info(`Retrieving registries data through AWS SDK...`);
|
core.info(`Retrieving registries data through AWS SDK...`);
|
||||||
const regDatas = await aws.getRegistriesData(registry, username, password);
|
const regDatas = await aws.getRegistriesData(registry, username, password);
|
||||||
for (const regData of regDatas) {
|
for (const regData of regDatas) {
|
||||||
core.info(`Logging into ${regData.registry}...`);
|
await loginExec(regData.registry, regData.username, regData.password, scope);
|
||||||
await Docker.getExecOutput(['login', '--password-stdin', '--username', regData.username, regData.registry], {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loginExec(registry: string, username: string, password: string, scope?: string): Promise<void> {
|
||||||
|
let envs: {[key: string]: string} | undefined;
|
||||||
|
const configDir = context.scopeToConfigDir(registry, scope);
|
||||||
|
if (configDir !== '') {
|
||||||
|
envs = Object.assign({}, process.env, {
|
||||||
|
DOCKER_CONFIG: configDir
|
||||||
|
}) as {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
core.info(`Logging into ${registry} (scope ${scope})...`);
|
||||||
|
} else {
|
||||||
|
core.info(`Logging into ${registry}...`);
|
||||||
|
}
|
||||||
|
await Docker.getExecOutput(['login', '--password-stdin', '--username', username, registry], {
|
||||||
ignoreReturnCode: true,
|
ignoreReturnCode: true,
|
||||||
silent: true,
|
silent: true,
|
||||||
input: Buffer.from(regData.password)
|
input: Buffer.from(password),
|
||||||
|
env: envs
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||||
throw new Error(res.stderr.trim());
|
throw new Error(res.stderr.trim());
|
||||||
}
|
}
|
||||||
core.info('Login Succeeded!');
|
core.info('Login Succeeded!');
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
49
src/main.ts
49
src/main.ts
@@ -1,50 +1,25 @@
|
|||||||
import * as yaml from 'js-yaml';
|
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as actionsToolkit from '@docker/actions-toolkit';
|
import * as actionsToolkit from '@docker/actions-toolkit';
|
||||||
|
|
||||||
import * as context from './context';
|
import * as context from './context.js';
|
||||||
import * as docker from './docker';
|
import * as docker from './docker.js';
|
||||||
import * as stateHelper from './state-helper';
|
import * as stateHelper from './state-helper.js';
|
||||||
|
|
||||||
interface Auth {
|
|
||||||
registry: string;
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
ecr: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function main(): Promise<void> {
|
export async function main(): Promise<void> {
|
||||||
const inputs: context.Inputs = context.getInputs();
|
const inputs: context.Inputs = context.getInputs();
|
||||||
stateHelper.setLogout(inputs.logout);
|
stateHelper.setLogout(inputs.logout);
|
||||||
|
|
||||||
if (inputs.registryAuth && (inputs.registry || inputs.username || inputs.password || inputs.ecr)) {
|
const auths = context.getAuthList(inputs);
|
||||||
throw new Error('Cannot use registry-auth with other inputs');
|
stateHelper.setRegistries(Array.from(new Map(auths.map(auth => [`${auth.registry}|${auth.configDir}`, {registry: auth.registry, configDir: auth.configDir} as stateHelper.RegistryState])).values()));
|
||||||
}
|
|
||||||
|
|
||||||
if (!inputs.registryAuth) {
|
if (auths.length === 1) {
|
||||||
stateHelper.setRegistries([inputs.registry || 'docker.io']);
|
await docker.login(auths[0]);
|
||||||
await docker.login(inputs.registry || 'docker.io', inputs.username, inputs.password, inputs.ecr || 'auto');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auths = yaml.load(inputs.registryAuth) as Auth[];
|
|
||||||
if (auths.length == 0) {
|
|
||||||
throw new Error('No registry to login');
|
|
||||||
}
|
|
||||||
|
|
||||||
const registries: string[] = [];
|
|
||||||
for (const auth of auths) {
|
for (const auth of auths) {
|
||||||
if (!auth.registry) {
|
await core.group(`Login to ${auth.registry}`, async () => {
|
||||||
registries.push('docker.io');
|
await docker.login(auth);
|
||||||
} else {
|
|
||||||
registries.push(auth.registry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stateHelper.setRegistries(registries.filter((value, index, self) => self.indexOf(value) === index));
|
|
||||||
|
|
||||||
for (const auth of auths) {
|
|
||||||
await core.group(`Login to ${auth.registry || 'docker.io'}`, async () => {
|
|
||||||
await docker.login(auth.registry || 'docker.io', auth.username, auth.password, auth.ecr || 'auto');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,8 +28,10 @@ async function post(): Promise<void> {
|
|||||||
if (!stateHelper.logout) {
|
if (!stateHelper.logout) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const registry of stateHelper.registries.split(',')) {
|
for (const registryState of stateHelper.registries) {
|
||||||
await docker.logout(registry);
|
await core.group(`Logout from ${registryState.registry}`, async () => {
|
||||||
|
await docker.logout(registryState.registry, registryState.configDir);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
export const registries = process.env['STATE_registries'] || '';
|
export const registries = process.env['STATE_registries'] ? (JSON.parse(process.env['STATE_registries']) as Array<RegistryState>) : [];
|
||||||
export const logout = /true/i.test(process.env['STATE_logout'] || '');
|
export const logout = /true/i.test(process.env['STATE_logout'] || '');
|
||||||
|
|
||||||
export function setRegistries(registries: string[]) {
|
export interface RegistryState {
|
||||||
core.saveState('registries', registries.join(','));
|
registry: string;
|
||||||
|
configDir: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setRegistries(registries: Array<RegistryState>) {
|
||||||
|
core.saveState('registries', JSON.stringify(registries));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setLogout(logout: boolean) {
|
export function setLogout(logout: boolean) {
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"module": "nodenext",
|
||||||
|
"moduleResolution": "nodenext",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"target": "es6",
|
|
||||||
"module": "commonjs",
|
|
||||||
"strict": true,
|
|
||||||
"newLine": "lf",
|
"newLine": "lf",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
@@ -12,10 +11,7 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"useUnknownInCatchVariables": false,
|
"useUnknownInCatchVariables": false,
|
||||||
},
|
},
|
||||||
"exclude": [
|
"include": [
|
||||||
"./__tests__/**/*",
|
"src/**/*.ts"
|
||||||
"./lib/**/*",
|
|
||||||
"node_modules",
|
|
||||||
"jest.config.ts"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
16
vitest.config.ts
Normal file
16
vitest.config.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import {defineConfig} from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
clearMocks: true,
|
||||||
|
environment: 'node',
|
||||||
|
setupFiles: ['./__tests__/setup.unit.ts'],
|
||||||
|
include: ['**/*.test.ts'],
|
||||||
|
coverage: {
|
||||||
|
provider: 'v8',
|
||||||
|
reporter: ['clover'],
|
||||||
|
include: ['src/**/*.ts'],
|
||||||
|
exclude: ['src/**/main.ts']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user