From 42711d156cba363fb791cf4a68025af8bd12b0ef Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Fri, 5 Sep 2025 18:14:00 +0200 Subject: [PATCH] multiple registries support Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- .github/workflows/ci.yml | 21 +++++++++++++++ action.yml | 3 +++ package.json | 4 ++- src/context.ts | 4 ++- src/main.ts | 57 ++++++++++++++++++++++++++++++++++++---- src/state-helper.ts | 6 ++--- yarn.lock | 9 +++++++ 7 files changed, 94 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 888441c..b50957b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -286,3 +286,24 @@ jobs: registry: gcr.io username: _json_key password: ${{ secrets.GCR_JSON_KEY }} + + multi: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Login to registries + uses: ./ + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + add: | + - registry: ${{ secrets.GAR_LOCATION }}-docker.pkg.dev + username: _json_key + password: ${{ secrets.GAR_JSON_KEY }} + - registry: registry.gitlab.com + username: ${{ secrets.GITLAB_USERNAME }} + password: ${{ secrets.GITLAB_TOKEN }} diff --git a/action.yml b/action.yml index 3a0856d..b511613 100644 --- a/action.yml +++ b/action.yml @@ -24,6 +24,9 @@ inputs: description: 'Log out from the Docker registry at the end of a job' default: 'true' required: false + add: + description: 'Add other registries to authenticate to defined as YAML objects' + required: false runs: using: 'node20' diff --git a/package.json b/package.json index 5f16a77..ff20db4 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "@aws-sdk/client-ecr-public": "^3.859.0", "@docker/actions-toolkit": "^0.62.1", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6" + "https-proxy-agent": "^7.0.6", + "js-yaml": "^4.1.0" }, "devDependencies": { + "@types/js-yaml": "^4.0.9", "@types/node": "^20.12.12", "@typescript-eslint/eslint-plugin": "^7.9.0", "@typescript-eslint/parser": "^7.9.0", diff --git a/src/context.ts b/src/context.ts index 8a38168..ac18d48 100644 --- a/src/context.ts +++ b/src/context.ts @@ -6,6 +6,7 @@ export interface Inputs { password: string; ecr: string; logout: boolean; + add: string; } export function getInputs(): Inputs { @@ -14,6 +15,7 @@ export function getInputs(): Inputs { username: core.getInput('username'), password: core.getInput('password'), ecr: core.getInput('ecr'), - logout: core.getBooleanInput('logout') + logout: core.getBooleanInput('logout'), + add: core.getInput('add') }; } diff --git a/src/main.ts b/src/main.ts index f35fa21..5d35283 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,21 +1,68 @@ +import * as yaml from 'js-yaml'; +import * as core from '@actions/core'; import * as actionsToolkit from '@docker/actions-toolkit'; import * as context from './context'; import * as docker from './docker'; import * as stateHelper from './state-helper'; +interface Auth { + registry: string; + username: string; + password: string; + ecr: string; +} + export async function main(): Promise { - const input: context.Inputs = context.getInputs(); - stateHelper.setRegistry(input.registry); - stateHelper.setLogout(input.logout); - await docker.login(input.registry, input.username, input.password, input.ecr); + const inputs: context.Inputs = context.getInputs(); + stateHelper.setLogout(inputs.logout); + + const auths: Array = []; + if (inputs.registry || inputs.username) { + auths.push({ + registry: inputs.registry, + username: inputs.username, + password: inputs.password, + ecr: inputs.ecr + }); + } + + const add = yaml.load(inputs.add) as Auth[]; + if (Array.isArray(add)) { + auths.push(...add); + } + + const registries: string[] = []; + for (const auth of auths) { + if (!auth.registry) { + registries.push('docker.io'); + } else { + registries.push(auth.registry); + } + } + stateHelper.setRegistries(registries); + + if (auths.length == 0) { + throw new Error('No registry to login'); + } + if (auths.length === 1) { + await docker.login(auths[0].registry, auths[0].username, auths[0].password, auths[0].ecr || 'auto'); + } else { + for (const auth of auths) { + await core.group(`Login to ${auth.registry || 'docker.io'}`, async () => { + await docker.login(auth.registry, auth.username, auth.password, auth.ecr || 'auto'); + }); + } + } } async function post(): Promise { if (!stateHelper.logout) { return; } - await docker.logout(stateHelper.registry); + for (const registry of stateHelper.registries.split(',')) { + await docker.logout(registry); + } } actionsToolkit.run(main, post); diff --git a/src/state-helper.ts b/src/state-helper.ts index 3732717..2120881 100644 --- a/src/state-helper.ts +++ b/src/state-helper.ts @@ -1,10 +1,10 @@ import * as core from '@actions/core'; -export const registry = process.env['STATE_registry'] || ''; +export const registries = process.env['STATE_registries'] || ''; export const logout = /true/i.test(process.env['STATE_logout'] || ''); -export function setRegistry(registry: string) { - core.saveState('registry', registry); +export function setRegistries(registries: string[]) { + core.saveState('registries', registries.join(',')); } export function setLogout(logout: boolean) { diff --git a/yarn.lock b/yarn.lock index e20b677..a8698a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3236,6 +3236,13 @@ __metadata: languageName: node linkType: hard +"@types/js-yaml@npm:^4.0.9": + version: 4.0.9 + resolution: "@types/js-yaml@npm:4.0.9" + checksum: e5e5e49b5789a29fdb1f7d204f82de11cb9e8f6cb24ab064c616da5d6e1b3ccfbf95aa5d1498a9fbd3b9e745564e69b4a20b6c530b5a8bbb2d4eb830cda9bc69 + languageName: node + linkType: hard + "@types/node-fetch@npm:^2.5.0": version: 2.6.4 resolution: "@types/node-fetch@npm:2.6.4" @@ -4315,6 +4322,7 @@ __metadata: "@aws-sdk/client-ecr": ^3.859.0 "@aws-sdk/client-ecr-public": ^3.859.0 "@docker/actions-toolkit": ^0.62.1 + "@types/js-yaml": ^4.0.9 "@types/node": ^20.12.12 "@typescript-eslint/eslint-plugin": ^7.9.0 "@typescript-eslint/parser": ^7.9.0 @@ -4326,6 +4334,7 @@ __metadata: http-proxy-agent: ^7.0.2 https-proxy-agent: ^7.0.6 jest: ^29.7.0 + js-yaml: ^4.1.0 prettier: ^3.2.5 ts-jest: ^29.1.2 ts-node: ^10.9.2