7 Commits

Author SHA1 Message Date
Fedor Dikarev
98b2971c0d Merge 087884b3d2 into 327cd5a69d 2025-01-09 11:00:08 +00:00
CrazyMax
327cd5a69d Merge pull request #838 from crazy-max/bake-v6
Some checks failed
validate / prepare (push) Successful in 1m1s
validate / validate (push) Failing after 17s
test / test (push) Failing after 8m44s
update bake-action to v6
2025-01-08 18:54:29 +01:00
CrazyMax
e217ef3a2d update bake-action to v6
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-01-08 12:58:36 +01:00
Fedor Dikarev
087884b3d2 mistype
Signed-off-by: Fedor Dikarev <fedor.dikarev@gmail.com>
2024-10-30 06:26:57 +01:00
Fedor Dikarev
ca362a507b add attempts to the action.yml
Signed-off-by: Fedor Dikarev <fedor.dikarev@gmail.com>
2024-10-29 22:28:24 +01:00
Fedor Dikarev
162c32cf05 trim stderr for checking
Signed-off-by: Fedor Dikarev <fedor.dikarev@gmail.com>
2024-10-29 22:14:18 +01:00
Fedor Dikarev
8479e9040e add retries for 502
Signed-off-by: Fedor Dikarev <fedor.dikarev@gmail.com>
2024-10-29 22:14:18 +01:00
7 changed files with 54 additions and 27 deletions

View File

@@ -15,12 +15,9 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
-
name: Checkout
uses: actions/checkout@v4
- -
name: Test name: Test
uses: docker/bake-action@v5 uses: docker/bake-action@v6
with: with:
targets: test targets: test
- -

View File

@@ -15,16 +15,17 @@ jobs:
prepare: prepare:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
targets: ${{ steps.targets.outputs.matrix }} targets: ${{ steps.generate.outputs.targets }}
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- -
name: Targets matrix name: List targets
id: targets id: generate
run: | uses: docker/bake-action/subaction/list-targets@v6
echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT with:
target: validate
validate: validate:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -35,11 +36,8 @@ jobs:
matrix: matrix:
target: ${{ fromJson(needs.prepare.outputs.targets) }} target: ${{ fromJson(needs.prepare.outputs.targets) }}
steps: steps:
-
name: Checkout
uses: actions/checkout@v4
- -
name: Validate name: Validate
uses: docker/bake-action@v5 uses: docker/bake-action@v6
with: with:
targets: ${{ matrix.target }} targets: ${{ matrix.target }}

View File

@@ -24,6 +24,10 @@ inputs:
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'
required: false required: false
attempts:
description: 'Number of attempts to try in case of server-side errors'
default: '1'
required: false
runs: runs:
using: 'node20' using: 'node20'

View File

@@ -1,3 +1,9 @@
target "_common" {
args = {
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
}
}
group "default" { group "default" {
targets = ["build"] targets = ["build"]
} }
@@ -11,42 +17,49 @@ group "validate" {
} }
target "build" { target "build" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile" dockerfile = "dev.Dockerfile"
target = "build-update" target = "build-update"
output = ["."] output = ["."]
} }
target "build-validate" { target "build-validate" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile" dockerfile = "dev.Dockerfile"
target = "build-validate" target = "build-validate"
output = ["type=cacheonly"] output = ["type=cacheonly"]
} }
target "format" { target "format" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile" dockerfile = "dev.Dockerfile"
target = "format-update" target = "format-update"
output = ["."] output = ["."]
} }
target "lint" { target "lint" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile" dockerfile = "dev.Dockerfile"
target = "lint" target = "lint"
output = ["type=cacheonly"] output = ["type=cacheonly"]
} }
target "vendor" { target "vendor" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile" dockerfile = "dev.Dockerfile"
target = "vendor-update" target = "vendor-update"
output = ["."] output = ["."]
} }
target "vendor-validate" { target "vendor-validate" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile" dockerfile = "dev.Dockerfile"
target = "vendor-validate" target = "vendor-validate"
output = ["type=cacheonly"] output = ["type=cacheonly"]
} }
target "test" { target "test" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile" dockerfile = "dev.Dockerfile"
target = "test-coverage" target = "test-coverage"
output = ["./coverage"] output = ["./coverage"]

View File

@@ -6,6 +6,7 @@ export interface Inputs {
password: string; password: string;
ecr: string; ecr: string;
logout: boolean; logout: boolean;
attempts: number;
} }
export function getInputs(): Inputs { export function getInputs(): Inputs {
@@ -14,6 +15,7 @@ export function getInputs(): Inputs {
username: core.getInput('username'), username: core.getInput('username'),
password: core.getInput('password'), password: core.getInput('password'),
ecr: core.getInput('ecr'), ecr: core.getInput('ecr'),
logout: core.getBooleanInput('logout') logout: core.getBooleanInput('logout'),
attempts: Number.parseInt(core.getInput('attempts'))
}; };
} }

View File

@@ -3,11 +3,11 @@ import * as core from '@actions/core';
import {Docker} from '@docker/actions-toolkit/lib/docker/docker'; import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
export async function login(registry: string, username: string, password: string, ecr: string): Promise<void> { export async function login(registry: string, username: string, password: string, ecr: string, attempts: number): Promise<void> {
if (/true/i.test(ecr) || (ecr == 'auto' && aws.isECR(registry))) { if (/true/i.test(ecr) || (ecr == 'auto' && aws.isECR(registry))) {
await loginECR(registry, username, password); await loginECR(registry, username, password);
} else { } else {
await loginStandard(registry, username, password); await loginStandard(registry, username, password, attempts);
} }
} }
@@ -21,7 +21,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, attempts: number): Promise<void> {
if (!username && !password) { if (!username && !password) {
throw new Error('Username and password required'); throw new Error('Username and password required');
} }
@@ -41,16 +41,29 @@ export async function loginStandard(registry: string, username: string, password
} else { } else {
core.info(`Logging into Docker Hub...`); core.info(`Logging into Docker Hub...`);
} }
let attempt: number = 1
let succeeded: boolean = false
for (let attempt = 1; (attempt <= attempts) && (!succeeded); attempt++) {
await Docker.getExecOutput(loginArgs, { await Docker.getExecOutput(loginArgs, {
ignoreReturnCode: true, ignoreReturnCode: true,
silent: true, silent: true,
input: Buffer.from(password) input: Buffer.from(password)
}).then(res => { }).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) { if (res.stderr.length > 0 && res.exitCode != 0) {
let isRetriable: boolean
isRetriable = res.stderr.trim().endsWith("502 Bad Gateway")
if (!isRetriable || (attempt >= attempts) {
throw new Error(res.stderr.trim()); throw new Error(res.stderr.trim());
} }
} else {
core.info(`Login Succeeded!`); core.info(`Login Succeeded!`);
succeeded = true;
}
}); });
if ((attempt < attempts) && !succeeded) {
await new Promise(r => setTimeout(r, 10000))
}
}
} }
export async function loginECR(registry: string, username: string, password: string): Promise<void> { export async function loginECR(registry: string, username: string, password: string): Promise<void> {

View File

@@ -8,7 +8,7 @@ export async function main(): Promise<void> {
const input: context.Inputs = context.getInputs(); const input: context.Inputs = context.getInputs();
stateHelper.setRegistry(input.registry); stateHelper.setRegistry(input.registry);
stateHelper.setLogout(input.logout); stateHelper.setLogout(input.logout);
await docker.login(input.registry, input.username, input.password, input.ecr); await docker.login(input.registry, input.username, input.password, input.ecr, input.attempts);
} }
async function post(): Promise<void> { async function post(): Promise<void> {