Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch to actions-toolkit implementation #266

Merged
merged 2 commits into from Feb 24, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
215 changes: 55 additions & 160 deletions __tests__/context.test.ts
@@ -1,168 +1,63 @@
import {describe, expect, it, jest} from '@jest/globals';
import * as fs from 'fs';
import * as path from 'path';
import {beforeEach, describe, expect, test} from '@jest/globals';

import * as context from '../src/context';

jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
const tmpDir = path.join('/tmp/.docker-metadata-action-jest').split(path.sep).join(path.posix.sep);
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir, {recursive: true});
}
return tmpDir;
});

describe('getInputList', () => {
it('single line correctly', async () => {
await setInput('foo', 'bar');
const res = context.getInputList('foo');
expect(res).toEqual(['bar']);
});

it('multiline correctly', async () => {
setInput('foo', 'bar\nbaz');
const res = context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});

it('empty lines correctly', async () => {
setInput('foo', 'bar\n\nbaz');
const res = context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});

it('comment correctly', async () => {
setInput('foo', 'bar\n#com\n"#taken"\nhello#comment\nbaz');
const res = context.getInputList('foo');
expect(res).toEqual(['bar', '#taken', 'hello', 'baz']);
});

it('comma correctly', async () => {
setInput('foo', 'bar,baz');
const res = context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});

it('empty result correctly', async () => {
setInput('foo', 'bar,baz,');
const res = context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});

it('different new lines correctly', async () => {
setInput('foo', 'bar\r\nbaz');
const res = context.getInputList('foo');
expect(res).toEqual(['bar', 'baz']);
});

it('different new lines and comma correctly', async () => {
setInput('foo', 'bar\r\nbaz,bat');
const res = context.getInputList('foo');
expect(res).toEqual(['bar', 'baz', 'bat']);
});

it('multiline and ignoring comma correctly', async () => {
setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir');
const res = context.getInputList('cache-from', true);
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
});

it('different new lines and ignoring comma correctly', async () => {
setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir');
const res = context.getInputList('cache-from', true);
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
});

it('multiline values', async () => {
setInput(
'secrets',
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
"MYSECRET=aaaaaaaa
bbbbbbb
ccccccccc"
FOO=bar`
);
const res = context.getInputList('secrets', true);
expect(res).toEqual([
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
`MYSECRET=aaaaaaaa
bbbbbbb
ccccccccc`,
'FOO=bar'
]);
});

it('multiline values with empty lines', async () => {
setInput(
'secrets',
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
"MYSECRET=aaaaaaaa
bbbbbbb
ccccccccc"
FOO=bar
"EMPTYLINE=aaaa

bbbb
ccc"`
);
const res = context.getInputList('secrets', true);
expect(res).toEqual([
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
`MYSECRET=aaaaaaaa
bbbbbbb
ccccccccc`,
'FOO=bar',
`EMPTYLINE=aaaa

bbbb
ccc`
]);
describe('getInputs', () => {
beforeEach(() => {
process.env = Object.keys(process.env).reduce((object, key) => {
if (!key.startsWith('INPUT_')) {
object[key] = process.env[key];
}
return object;
}, {});
});

it('multiline values without quotes', async () => {
setInput(
'secrets',
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
MYSECRET=aaaaaaaa
bbbbbbb
ccccccccc
FOO=bar`
);
const res = context.getInputList('secrets', true);
expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']);
});

it('multiline values escape quotes', async () => {
setInput(
'secrets',
`GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789
"MYSECRET=aaaaaaaa
bbbb""bbb
ccccccccc"
FOO=bar`
);
const res = context.getInputList('secrets', true);
expect(res).toEqual([
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
`MYSECRET=aaaaaaaa
bbbb"bbb
ccccccccc`,
'FOO=bar'
]);
});
});

describe('asyncForEach', () => {
it('executes async tasks sequentially', async () => {
const testValues = [1, 2, 3, 4, 5];
const results: number[] = [];

await context.asyncForEach(testValues, async value => {
results.push(value);
});

expect(results).toEqual(testValues);
});
// prettier-ignore
test.each([
[
0,
new Map<string, string>([
['images', 'moby/buildkit\nghcr.io/moby/mbuildkit'],
]),
{
bakeTarget: 'docker-metadata-action',
flavor: [],
githubToken: '',
images: ['moby/buildkit', 'ghcr.io/moby/mbuildkit'],
labels: [],
sepLabels: '\n',
sepTags: '\n',
tags: [],
} as context.Inputs
],
[
1,
new Map<string, string>([
['bake-target', 'metadata'],
['images', 'moby/buildkit'],
['sep-labels', ','],
['sep-tags', ','],
]),
{
bakeTarget: 'metadata',
flavor: [],
githubToken: '',
images: ['moby/buildkit'],
labels: [],
sepLabels: ',',
sepTags: ',',
tags: [],
} as context.Inputs
]
])(
'[%d] given %p as inputs, returns %p',
async (num: number, inputs: Map<string, string>, expected: context.Inputs) => {
inputs.forEach((value: string, name: string) => {
setInput(name, value);
});
expect(await context.getInputs()).toEqual(expected);
}
);
});

// See: https://github.com/actions/toolkit/blob/master/packages/core/src/core.ts#L67
Expand Down
1 change: 1 addition & 0 deletions __tests__/flavor.test.ts
@@ -1,4 +1,5 @@
import {describe, expect, test} from '@jest/globals';

import {Flavor, Transform} from '../src/flavor';

describe('transform', () => {
Expand Down
14 changes: 0 additions & 14 deletions __tests__/github.test.ts

This file was deleted.

1 change: 1 addition & 0 deletions __tests__/image.test.ts
@@ -1,4 +1,5 @@
import {describe, expect, test} from '@jest/globals';

import {Transform, Image} from '../src/image';

describe('transform', () => {
Expand Down
50 changes: 24 additions & 26 deletions __tests__/meta.test.ts
Expand Up @@ -2,19 +2,17 @@ import {beforeEach, describe, expect, jest, test} from '@jest/globals';
import * as fs from 'fs';
import * as path from 'path';
import * as dotenv from 'dotenv';
import moment from 'moment-timezone';
import {getInputs, Inputs} from '../src/context';
import * as github from '../src/github';
import {Meta, Version} from '../src/meta';
import {Context} from '@actions/github/lib/context';
import {GitHub} from '@docker/actions-toolkit/lib/github';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
import {GitHubRepo} from '@docker/actions-toolkit/lib/types/github';

import * as repoFixture from './fixtures/repo.json';
jest.spyOn(github, 'repo').mockImplementation((): Promise<github.ReposGetResponseData> => {
return <Promise<github.ReposGetResponseData>>(repoFixture as unknown);
});
import {getInputs, Inputs} from '../src/context';
import {Meta, Version} from '../src/meta';

jest.spyOn(github, 'context').mockImplementation((): Context => {
return new Context();
import repoFixture from './fixtures/repo.json';
jest.spyOn(GitHub.prototype, 'repoData').mockImplementation((): Promise<GitHubRepo> => {
return <Promise<GitHubRepo>>(repoFixture as unknown);
});

jest.spyOn(global.Date.prototype, 'toISOString').mockImplementation(() => {
Expand All @@ -26,6 +24,7 @@ jest.mock('moment-timezone', () => {
});

beforeEach(() => {
jest.clearAllMocks();
Object.keys(process.env).forEach(function (key) {
if (key !== 'GITHUB_TOKEN' && key.startsWith('GITHUB_')) {
delete process.env[key];
Expand All @@ -48,10 +47,9 @@ describe('isRawStatement', () => {

const tagsLabelsTest = async (name: string, envFile: string, inputs: Inputs, exVersion: Version, exTags: Array<string>, exLabels: Array<string>) => {
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
const context = github.context();

const repo = await github.repo(process.env.GITHUB_TOKEN || '');
const meta = new Meta({...getInputs(), ...inputs}, context, repo);
const toolkit = new Toolkit();
const repo = await toolkit.github.repoData();
const meta = new Meta({...getInputs(), ...inputs}, new Context(), repo);

const version = meta.version;
expect(version).toEqual(exVersion);
Expand Down Expand Up @@ -2765,10 +2763,10 @@ describe('pr-head-sha', () => {
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exVersion: Version, exTags: Array<string>, exLabels: Array<string>) => {
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
process.env.DOCKER_METADATA_PR_HEAD_SHA = 'true';
const context = github.context();

const repo = await github.repo(process.env.GITHUB_TOKEN || '');
const meta = new Meta({...getInputs(), ...inputs}, context, repo);
const toolkit = new Toolkit();
const repo = await toolkit.github.repoData();
const meta = new Meta({...getInputs(), ...inputs}, new Context(), repo);

const version = meta.version;
expect(version).toEqual(exVersion);
Expand Down Expand Up @@ -3707,10 +3705,10 @@ describe('json', () => {
]
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exJSON: unknown) => {
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
const context = github.context();

const repo = await github.repo(process.env.GITHUB_TOKEN || '');
const meta = new Meta({...getInputs(), ...inputs}, context, repo);
const toolkit = new Toolkit();
const repo = await toolkit.github.repoData();
const meta = new Meta({...getInputs(), ...inputs}, new Context(), repo);

const jsonOutput = meta.getJSON();
expect(jsonOutput).toEqual(exJSON);
Expand Down Expand Up @@ -4013,10 +4011,10 @@ describe('bake', () => {
]
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, exBakeDefinition: unknown) => {
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
const context = github.context();

const repo = await github.repo(process.env.GITHUB_TOKEN || '');
const meta = new Meta({...getInputs(), ...inputs}, context, repo);
const toolkit = new Toolkit();
const repo = await toolkit.github.repoData();
const meta = new Meta({...getInputs(), ...inputs}, new Context(), repo);

const bakeFile = meta.getBakeFile();
expect(JSON.parse(fs.readFileSync(bakeFile, 'utf8'))).toEqual(exBakeDefinition);
Expand Down Expand Up @@ -4059,10 +4057,10 @@ describe('sepTags', () => {
]
])('given %p with %p event', async (name: string, envFile: string, inputs: Inputs, expTags: string) => {
process.env = dotenv.parse(fs.readFileSync(path.join(__dirname, 'fixtures', envFile)));
const context = github.context();

const repo = await github.repo(process.env.GITHUB_TOKEN || '');
const meta = new Meta({...getInputs(), ...inputs}, context, repo);
const toolkit = new Toolkit();
const repo = await toolkit.github.repoData();
const meta = new Meta({...getInputs(), ...inputs}, new Context(), repo);

expect(meta.getTags().join(inputs.sepTags)).toEqual(expTags);
});
Expand Down
1 change: 1 addition & 0 deletions __tests__/tag.test.ts
@@ -1,4 +1,5 @@
import {describe, expect, test} from '@jest/globals';

import {Transform, Parse, Tag, Type, RefEvent, ShaFormat, DefaultPriorities} from '../src/tag';

describe('transform', () => {
Expand Down