Compare commits

..

No commits in common. "master" and "v3" have entirely different histories.
master ... v3

34 changed files with 19220 additions and 10743 deletions

3
.eslintignore Normal file
View File

@ -0,0 +1,3 @@
/dist/**
/coverage/**
/node_modules/**

24
.eslintrc.json Normal file
View File

@ -0,0 +1,24 @@
{
"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"
]
}

View File

@ -4,12 +4,6 @@ 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"
@ -17,10 +11,6 @@ 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:

View File

@ -1,8 +1,5 @@
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
@ -22,7 +19,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Stop docker name: Stop docker
run: | run: |
@ -46,7 +43,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: ./ uses: ./
@ -63,7 +60,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: ./ uses: ./
@ -73,7 +70,7 @@ jobs:
password: ${{ secrets.GHCR_PAT }} password: ${{ secrets.GHCR_PAT }}
- -
name: DinD name: DinD
uses: docker://docker:29.3@sha256:4d90f1f6c400315c2dba96d3ec93c01e64198395cbba04f79d12adce4f737029 uses: docker://docker
with: with:
entrypoint: docker entrypoint: docker
args: pull ghcr.io/docker-ghactiontest/test args: pull ghcr.io/docker-ghactiontest/test
@ -88,7 +85,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to ACR name: Login to ACR
uses: ./ uses: ./
@ -108,7 +105,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to Docker Hub name: Login to Docker Hub
uses: ./ uses: ./
@ -127,7 +124,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to ECR name: Login to ECR
uses: ./ uses: ./
@ -147,10 +144,10 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Configure AWS Credentials name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0 uses: aws-actions/configure-aws-credentials@v5
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 }}
@ -172,7 +169,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to Public ECR name: Login to Public ECR
continue-on-error: ${{ matrix.os == 'windows-latest' }} continue-on-error: ${{ matrix.os == 'windows-latest' }}
@ -195,10 +192,10 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Configure AWS Credentials name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0 uses: aws-actions/configure-aws-credentials@v5
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 }}
@ -221,7 +218,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: ./ uses: ./
@ -241,7 +238,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to GitLab name: Login to GitLab
uses: ./ uses: ./
@ -261,7 +258,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to Google Artifact Registry name: Login to Google Artifact Registry
uses: ./ uses: ./
@ -281,7 +278,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to Google Container Registry name: Login to Google Container Registry
uses: ./ uses: ./
@ -295,7 +292,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to registries name: Login to registries
uses: ./ uses: ./
@ -318,7 +315,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to registries name: Login to registries
uses: ./ uses: ./
@ -339,7 +336,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to registries name: Login to registries
id: login id: login
@ -371,7 +368,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to Docker Hub name: Login to Docker Hub
uses: ./ uses: ./
@ -401,7 +398,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to Docker Hub name: Login to Docker Hub
uses: ./ uses: ./
@ -431,7 +428,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: ./ uses: ./
@ -462,7 +459,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: ./ uses: ./

View File

@ -1,46 +1,50 @@
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/**'
env: permissions:
NODE_VERSION: "24" actions: read
contents: read
security-events: write
jobs: jobs:
analyze: analyze:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: strategy:
contents: read fail-fast: false
security-events: write matrix:
language:
- javascript-typescript
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
-
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@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 uses: github/codeql-action/init@v4
with: with:
languages: javascript-typescript languages: ${{ matrix.language }}
build-mode: none config: |
paths:
- src
-
name: Autobuild
uses: github/codeql-action/autobuild@v4
- -
name: Perform CodeQL Analysis name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 uses: github/codeql-action/analyze@v4
with: with:
category: "/language:javascript-typescript" category: "/language:${{matrix.language}}"

View File

@ -4,14 +4,14 @@ permissions:
contents: read contents: read
on: on:
pull_request_target: # zizmor: ignore[dangerous-triggers] safe to use without checkout pull_request_target:
types: types:
- opened - opened
- reopened - reopened
jobs: jobs:
run: run:
uses: crazy-max/.github/.github/workflows/pr-assign-author.yml@64a0bfaf6e6bb1c448d6e4c42b11034ee7094f16 # v1.7.1 uses: crazy-max/.github/.github/workflows/pr-assign-author.yml@1b673f36fad86812f538c1df9794904038a23cbf
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write

View File

@ -1,12 +1,5 @@
name: publish name: publish
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on: on:
release: release:
types: types:
@ -22,7 +15,7 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Publish name: Publish
uses: actions/publish-immutable-action@4bc8754ffc40f27910afb20287dbbbb675a4e978 # v0.0.4 uses: actions/publish-immutable-action@v0.0.4

View File

@ -1,8 +1,5 @@
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
@ -20,16 +17,16 @@ jobs:
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Test name: Test
uses: docker/bake-action@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0 uses: docker/bake-action@v6
with: with:
source: . source: .
targets: test targets: test
- -
name: Upload coverage name: Upload coverage
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 uses: codecov/codecov-action@v5
with: with:
files: ./coverage/clover.xml files: ./coverage/clover.xml
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}

View File

@ -1,56 +0,0 @@
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

View File

@ -1,8 +1,5 @@
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
@ -18,15 +15,15 @@ jobs:
prepare: prepare:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
matrix: ${{ steps.generate.outputs.matrix }} targets: ${{ steps.generate.outputs.targets }}
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v6
- -
name: Generate matrix name: List targets
id: generate id: generate
uses: docker/bake-action/subaction/matrix@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0 uses: docker/bake-action/subaction/list-targets@v6
with: with:
target: validate target: validate
@ -37,10 +34,10 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: ${{ fromJson(needs.prepare.outputs.matrix) }} target: ${{ fromJson(needs.prepare.outputs.targets) }}
steps: steps:
- -
name: Validate name: Validate
uses: docker/bake-action@a66e1c87e2eca0503c343edf1d208c716d54b8a8 # v7.1.0 uses: docker/bake-action@v6
with: with:
targets: ${{ matrix.target }} targets: ${{ matrix.target }}

View File

@ -1,29 +0,0 @@
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@64a0bfaf6e6bb1c448d6e4c42b11034ee7094f16 # v1.7.1
permissions:
contents: read
security-events: write
with:
min-severity: medium
min-confidence: medium
persona: pedantic

View File

@ -6,5 +6,6 @@
"singleQuote": true, "singleQuote": true,
"trailingComma": "none", "trailingComma": "none",
"bracketSpacing": false, "bracketSpacing": false,
"arrowParens": "avoid" "arrowParens": "avoid",
"parser": "typescript"
} }

View File

@ -51,7 +51,7 @@ jobs:
steps: steps:
- -
name: Login to Docker Hub name: Login to Docker Hub
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
username: ${{ vars.DOCKERHUB_USERNAME }} username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
@ -76,7 +76,7 @@ jobs:
steps: steps:
- -
name: Login to GitHub Container Registry name: Login to GitHub Container Registry
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
@ -104,7 +104,7 @@ jobs:
steps: steps:
- -
name: Login to GitLab name: Login to GitLab
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: registry.gitlab.com registry: registry.gitlab.com
username: ${{ vars.GITLAB_USERNAME }} username: ${{ vars.GITLAB_USERNAME }}
@ -135,7 +135,7 @@ jobs:
steps: steps:
- -
name: Login to ACR name: Login to ACR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: <registry-name>.azurecr.io registry: <registry-name>.azurecr.io
username: ${{ vars.AZURE_CLIENT_ID }} username: ${{ vars.AZURE_CLIENT_ID }}
@ -183,7 +183,7 @@ jobs:
service_account: <service_account> service_account: <service_account>
- -
name: Login to GCR name: Login to GCR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: gcr.io registry: gcr.io
username: oauth2accesstoken username: oauth2accesstoken
@ -216,7 +216,7 @@ jobs:
steps: steps:
- -
name: Login to GCR name: Login to GCR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: gcr.io registry: gcr.io
username: _json_key username: _json_key
@ -254,7 +254,7 @@ jobs:
service_account: <service_account> service_account: <service_account>
- -
name: Login to GAR name: Login to GAR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: <location>-docker.pkg.dev registry: <location>-docker.pkg.dev
username: oauth2accesstoken username: oauth2accesstoken
@ -291,7 +291,7 @@ jobs:
steps: steps:
- -
name: Login to GAR name: Login to GAR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: <location>-docker.pkg.dev registry: <location>-docker.pkg.dev
username: _json_key username: _json_key
@ -320,7 +320,7 @@ jobs:
steps: steps:
- -
name: Login to ECR name: Login to ECR
uses: docker/login-action@v4 uses: docker/login-action@v3
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 }}
@ -343,7 +343,7 @@ jobs:
steps: steps:
- -
name: Login to ECR name: Login to ECR
uses: docker/login-action@v4 uses: docker/login-action@v3
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 }}
@ -377,7 +377,7 @@ jobs:
aws-region: <region> aws-region: <region>
- -
name: Login to ECR name: Login to ECR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com registry: <aws-account-number>.dkr.ecr.<region>.amazonaws.com
``` ```
@ -404,7 +404,7 @@ jobs:
steps: steps:
- -
name: Login to Public ECR name: Login to Public ECR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: public.ecr.aws registry: public.ecr.aws
username: ${{ vars.AWS_ACCESS_KEY_ID }} username: ${{ vars.AWS_ACCESS_KEY_ID }}
@ -438,7 +438,7 @@ jobs:
steps: steps:
- -
name: Login to OCIR name: Login to OCIR
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: <region>.ocir.io registry: <region>.ocir.io
username: ${{ vars.OCI_USERNAME }} username: ${{ vars.OCI_USERNAME }}
@ -465,7 +465,7 @@ jobs:
steps: steps:
- -
name: Login to Quay.io name: Login to Quay.io
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: quay.io registry: quay.io
username: ${{ vars.QUAY_USERNAME }} username: ${{ vars.QUAY_USERNAME }}
@ -489,7 +489,7 @@ jobs:
steps: steps:
- -
name: Login to DigitalOcean Container Registry name: Login to DigitalOcean Container Registry
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry: registry.digitalocean.com registry: registry.digitalocean.com
username: ${{ vars.DIGITALOCEAN_USERNAME }} username: ${{ vars.DIGITALOCEAN_USERNAME }}
@ -514,13 +514,13 @@ jobs:
steps: steps:
- -
name: Login to Docker Hub name: Login to Docker Hub
uses: docker/login-action@v4 uses: docker/login-action@v3
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@v4 uses: docker/login-action@v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
@ -548,7 +548,7 @@ jobs:
steps: steps:
- -
name: Login to registries name: Login to registries
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
registry-auth: | registry-auth: |
- username: ${{ vars.DOCKERHUB_USERNAME }} - username: ${{ vars.DOCKERHUB_USERNAME }}
@ -596,7 +596,7 @@ jobs:
steps: steps:
- -
name: Login to Docker Hub (scoped) name: Login to Docker Hub (scoped)
uses: docker/login-action@v4 uses: docker/login-action@v3
with: with:
username: ${{ vars.DOCKERHUB_USERNAME }} username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@ -1,7 +1,7 @@
import {beforeEach, describe, expect, test, vi} from 'vitest'; import {beforeEach, describe, expect, jest, test} from '@jest/globals';
import {AuthorizationData} from '@aws-sdk/client-ecr'; import {AuthorizationData} from '@aws-sdk/client-ecr';
import * as aws from '../src/aws.js'; import * as aws from '../src/aws';
describe('isECR', () => { describe('isECR', () => {
test.each([ test.each([
@ -65,28 +65,26 @@ describe('getAccountIDs', () => {
}); });
}); });
const mockEcrGetAuthToken = vi.fn(); const mockEcrGetAuthToken = jest.fn();
const mockEcrPublicGetAuthToken = vi.fn(); const mockEcrPublicGetAuthToken = jest.fn();
vi.mock('@aws-sdk/client-ecr', () => { jest.mock('@aws-sdk/client-ecr', () => {
class ECR {
getAuthorizationToken = mockEcrGetAuthToken;
}
return { return {
ECR ECR: jest.fn(() => ({
getAuthorizationToken: mockEcrGetAuthToken
}))
}; };
}); });
vi.mock('@aws-sdk/client-ecr-public', () => { jest.mock('@aws-sdk/client-ecr-public', () => {
class ECRPUBLIC {
getAuthorizationToken = mockEcrPublicGetAuthToken;
}
return { return {
ECRPUBLIC ECRPUBLIC: jest.fn(() => ({
getAuthorizationToken: mockEcrPublicGetAuthToken
}))
}; };
}); });
describe('getRegistriesData', () => { describe('getRegistriesData', () => {
beforeEach(() => { beforeEach(() => {
vi.clearAllMocks(); jest.clearAllMocks();
delete process.env.AWS_ACCOUNT_IDS; delete process.env.AWS_ACCOUNT_IDS;
}); });
// prettier-ignore // prettier-ignore

View File

@ -1,17 +1,6 @@
import {afterEach, expect, test} from 'vitest'; import {expect, test} from '@jest/globals';
import * as path from 'path';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js'; import {getInputs} from '../src/context';
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';
@ -21,15 +10,3 @@ 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')
});
});

View File

@ -1,11 +1,16 @@
import {expect, test, vi} from 'vitest'; import {expect, jest, test} from '@jest/globals';
import * as path from 'path';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker.js'; import {loginStandard, logout} from '../src/docker';
import {loginStandard, logout} from '../src/docker.js'; import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
process.env['RUNNER_TEMP'] = path.join(__dirname, 'runner');
test('loginStandard calls exec', async () => { test('loginStandard calls exec', async () => {
const execSpy = vi.spyOn(Docker, 'getExecOutput').mockImplementation(async () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @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),
@ -33,7 +38,9 @@ test('loginStandard calls exec', async () => {
}); });
test('logout calls exec', async () => { test('logout calls exec', async () => {
const execSpy = vi.spyOn(Docker, 'getExecOutput').mockImplementation(async () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @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),

View File

@ -1,12 +0,0 @@
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')
});

View File

@ -31,6 +31,6 @@ inputs:
required: false required: false
runs: runs:
using: 'node24' using: 'node20'
main: 'dist/index.cjs' main: 'dist/index.js'
post: 'dist/index.cjs' post: 'dist/index.js'

View File

@ -1,13 +1,12 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
ARG NODE_VERSION=24 ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine AS base FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git rsync RUN apk add --no-cache cpio findutils git
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
@ -35,27 +34,18 @@ RUN --mount=type=bind,target=.,rw <<EOT
EOT EOT
FROM deps AS build FROM deps AS build
RUN --mount=target=/context \ 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 <<EOT --mount=type=cache,target=/src/node_modules \
set -e yarn run build && mkdir /out && cp -Rf dist /out/
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=target=/context \ RUN --mount=type=bind,target=.,rw <<EOT
--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"'
@ -68,7 +58,8 @@ 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 && mkdir /out && find . -name '*.ts' -not -path './node_modules/*' -not -path './.yarn/*' | cpio -pdm /out yarn run format \
&& 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 /
@ -85,7 +76,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 --coverage.reportsDirectory=/tmp/coverage yarn run test --coverage --coverageDirectory=/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

File diff suppressed because one or more lines are too long

7
dist/index.cjs.map generated vendored

File diff suppressed because one or more lines are too long

103
dist/index.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/index.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

20002
dist/licenses.txt generated vendored

File diff suppressed because it is too large Load Diff

1
dist/sourcemap-register.js generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,52 +0,0 @@
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
}
]
}
}
]);

30
jest.config.ts Normal file
View File

@ -0,0 +1,30 @@
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
};

View File

@ -1,14 +1,16 @@
{ {
"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": "esbuild src/main.ts --bundle --platform=node --target=node24 --format=cjs --outfile=dist/index.cjs --sourcemap --minify && yarn run license", "build": "ncc build --source-map --minify --license licenses.txt",
"lint": "eslint --max-warnings=0 .", "lint": "yarn run prettier && yarn run eslint",
"format": "eslint --fix .", "format": "yarn run prettier:fix && yarn run eslint:fix",
"test": "vitest run", "eslint": "eslint --max-warnings=0 .",
"license": "generate-license-file --input package.json --output dist/licenses.txt --overwrite --ci --no-spinner --eol lf" "eslint:fix": "eslint --fix .",
"prettier": "prettier --check \"./**/*.ts\"",
"prettier:fix": "prettier --write \"./**/*.ts\"",
"test": "jest"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -23,30 +25,28 @@
"license": "Apache-2.0", "license": "Apache-2.0",
"packageManager": "yarn@4.9.2", "packageManager": "yarn@4.9.2",
"dependencies": { "dependencies": {
"@actions/core": "^3.0.0", "@actions/core": "^1.11.1",
"@aws-sdk/client-ecr": "^3.1020.0", "@aws-sdk/client-ecr": "^3.890.0",
"@aws-sdk/client-ecr-public": "^3.1020.0", "@aws-sdk/client-ecr-public": "^3.890.0",
"@docker/actions-toolkit": "^0.86.0", "@docker/actions-toolkit": "^0.63.0",
"http-proxy-agent": "^9.0.0", "http-proxy-agent": "^7.0.2",
"https-proxy-agent": "^9.0.0", "https-proxy-agent": "^7.0.6",
"js-yaml": "^4.1.1" "js-yaml": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.39.3",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/node": "^24.11.0", "@types/node": "^20.19.9",
"@typescript-eslint/eslint-plugin": "^8.56.1", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^8.56.1", "@typescript-eslint/parser": "^7.18.0",
"@vitest/coverage-v8": "^4.0.18", "@vercel/ncc": "^0.38.3",
"@vitest/eslint-plugin": "^1.6.9", "eslint": "^8.57.1",
"esbuild": "^0.28.0", "eslint-config-prettier": "^9.1.2",
"eslint": "^9.39.3", "eslint-plugin-jest": "^28.14.0",
"eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-prettier": "^5.5.5", "jest": "^29.7.0",
"generate-license-file": "^4.1.1", "prettier": "^3.6.2",
"globals": "^17.3.0", "ts-jest": "^29.4.1",
"prettier": "^3.8.1", "ts-node": "^10.9.2",
"typescript": "^5.9.3", "typescript": "^5.9.2"
"vitest": "^4.0.18"
} }
} }

View File

@ -2,8 +2,8 @@ import path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as yaml from 'js-yaml'; import * as yaml from 'js-yaml';
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx.js'; import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
import {Util} from '@docker/actions-toolkit/lib/util.js'; import {Util} from '@docker/actions-toolkit/lib/util';
export interface Inputs { export interface Inputs {
registry: string; registry: string;
@ -42,26 +42,24 @@ export function getAuthList(inputs: Inputs): Array<Auth> {
} }
let auths: Array<Auth> = []; let auths: Array<Auth> = [];
if (!inputs.registryAuth) { if (!inputs.registryAuth) {
const registry = inputs.registry || 'docker.io';
auths.push({ auths.push({
registry, registry: inputs.registry || 'docker.io',
username: inputs.username, username: inputs.username,
password: inputs.password, password: inputs.password,
scope: inputs.scope, scope: inputs.scope,
ecr: inputs.ecr || 'auto', ecr: inputs.ecr || 'auto',
configDir: scopeToConfigDir(registry, inputs.scope) configDir: scopeToConfigDir(inputs.registry, inputs.scope)
}); });
} else { } else {
auths = (yaml.load(inputs.registryAuth) as Array<Auth>).map(auth => { auths = (yaml.load(inputs.registryAuth) as Array<Auth>).map(auth => {
core.setSecret(auth.password); // redacted in workflow logs core.setSecret(auth.password); // redacted in workflow logs
const registry = auth.registry || 'docker.io';
return { return {
registry, registry: auth.registry || 'docker.io',
username: auth.username, username: auth.username,
password: auth.password, password: auth.password,
scope: auth.scope, scope: auth.scope,
ecr: auth.ecr || 'auto', ecr: auth.ecr || 'auto',
configDir: scopeToConfigDir(registry, auth.scope) configDir: scopeToConfigDir(auth.registry || 'docker.io', auth.scope)
}; };
}); });
} }

View File

@ -1,9 +1,9 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker.js'; import * as aws from './aws';
import * as context from './context';
import * as aws from './aws.js'; import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
import * as context from './context.js';
export async function login(auth: context.Auth): Promise<void> { export async function login(auth: context.Auth): Promise<void> {
if (/true/i.test(auth.ecr) || (auth.ecr == 'auto' && aws.isECR(auth.registry))) { if (/true/i.test(auth.ecr) || (auth.ecr == 'auto' && aws.isECR(auth.registry))) {

View File

@ -1,9 +1,9 @@
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.js'; import * as context from './context';
import * as docker from './docker.js'; import * as docker from './docker';
import * as stateHelper from './state-helper.js'; import * as stateHelper from './state-helper';
export async function main(): Promise<void> { export async function main(): Promise<void> {
const inputs: context.Inputs = context.getInputs(); const inputs: context.Inputs = context.getInputs();

View File

@ -1,8 +1,9 @@
{ {
"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",
@ -11,7 +12,10 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"useUnknownInCatchVariables": false, "useUnknownInCatchVariables": false,
}, },
"include": [ "exclude": [
"src/**/*.ts" "./__tests__/**/*",
"./lib/**/*",
"node_modules",
"jest.config.ts"
] ]
} }

View File

@ -1,16 +0,0 @@
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']
}
}
});

9001
yarn.lock

File diff suppressed because it is too large Load Diff