Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions __tests__/github-builder/registry-identities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
* limitations under the License.
*/

import {describe, expect, it} from 'vitest';
import {afterEach, describe, expect, it, vi} from 'vitest';
import * as core from '@actions/core';

import {RegistryIdentities} from '../../src/github-builder/registry-identities.js';

vi.mock('@actions/core', () => ({info: vi.fn()}));

const aws = {type: 'aws-ecr', registry: '123.dkr.ecr.us-east-1.amazonaws.com', 'role-to-assume': 'arn:aws:iam::123:role/build', region: 'us-east-1'};
const gcp = {type: 'gcp-wif', registry: 'us-docker.pkg.dev', workload_identity_provider: 'projects/123/locations/global/workloadIdentityPools/pool/providers/provider', service_account: 'build@example.iam.gserviceaccount.com'};
const hub = {type: 'dockerhub', username: 'builder', connection_id: 'connection'};
Expand All @@ -26,8 +29,23 @@ const chainguard = {type: 'chainguard', identity: 'organization/identity'};
const identities = [aws, gcp, hub, azure, chainguard];

describe('RegistryIdentities.parse', () => {
it.each(['', ' \n\t', 'null', '~', '---\n', '[]'])('accepts empty configuration %j', input => {
afterEach(() => {
vi.mocked(core.info).mockReset();
});

it.each(['', ' \n\t'])('accepts blank configuration %j without logging', input => {
expect(RegistryIdentities.parse(input)).toEqual({});
expect(core.info).not.toHaveBeenCalled();
});

it.each(['null', '~', '---\n'])('accepts empty parsed configuration %j and logs why outputs are disabled', input => {
expect(RegistryIdentities.parse(input)).toEqual({});
expect(core.info).toHaveBeenCalledExactlyOnceWith('Registry identities input is empty after parsing; disabling registry identity outputs');
});

it('accepts an empty identity list and logs why outputs are disabled', () => {
expect(RegistryIdentities.parse('[]')).toEqual({});
expect(core.info).toHaveBeenCalledExactlyOnceWith('No registry identity entries parsed; disabling registry identity outputs');
});

it('accepts a single AWS identity and trims field values', () => {
Expand All @@ -44,6 +62,7 @@ describe('RegistryIdentities.parse', () => {
azureAcr: {registry: azure.registry, clientId: azure.client_id, tenantId: azure.tenant_id, subscriptionId: azure.subscription_id},
chainguard: {identity: chainguard.identity, apkHost: 'apk.cgr.dev', librariesHost: 'libraries.cgr.dev'}
});
expect(core.info).toHaveBeenCalledExactlyOnceWith('Validating 5 registry identity entries');
});

it('preserves explicit optional fields, trimming whitespace', () => {
Expand Down
10 changes: 10 additions & 0 deletions src/github-builder/registry-identities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import {load, YAMLException} from 'js-yaml';
import * as core from '@actions/core';

export interface RegistryIdentityConfig {
awsEcr?: {
Expand Down Expand Up @@ -53,6 +54,7 @@ export class RegistryIdentities {
if (!input.trim()) {
return {};
}

let parsed: unknown;
try {
parsed = load(input);
Expand All @@ -62,10 +64,18 @@ export class RegistryIdentities {
RegistryIdentities.fail(`Failed to parse YAML${location}`);
}
if (parsed === null || parsed === undefined) {
core.info('Registry identities input is empty after parsing; disabling registry identity outputs');
return {};
}

const result: RegistryIdentityConfig = {};
const entries = Array.isArray(parsed) ? parsed : [parsed];
if (entries.length === 0) {
core.info('No registry identity entries parsed; disabling registry identity outputs');
return result;
}

core.info(`Validating ${entries.length} registry identity ${entries.length === 1 ? 'entry' : 'entries'}`);
entries.forEach((entry, index) => {
const location = `registry-identities[${index}]`;
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
Expand Down
Loading