diff --git a/__mocks__/@actions/github.ts b/__mocks__/@actions/github.ts new file mode 100644 index 0000000..578a3de --- /dev/null +++ b/__mocks__/@actions/github.ts @@ -0,0 +1,207 @@ +import {jest} from '@jest/globals'; + +export const context = { + repo: { + owner: 'docker', + repo: 'actions-toolkit' + }, + ref: 'refs/heads/master', + runId: 123, + payload: { + after: '860c1904a1ce19322e91ac35af1ab07466440c37', + base_ref: null, + before: '5f3331d7f7044c18ca9f12c77d961c4d7cf3276a', + commits: [ + { + author: { + email: 'crazy-max@users.noreply.github.com', + name: 'CrazyMax', + username: 'crazy-max' + }, + committer: { + email: 'crazy-max@users.noreply.github.com', + name: 'CrazyMax', + username: 'crazy-max' + }, + distinct: true, + id: '860c1904a1ce19322e91ac35af1ab07466440c37', + message: 'hello dev', + timestamp: '2022-04-19T11:27:24+02:00', + tree_id: 'd2c60af597e863787d2d27f569e30495b0b92820', + url: 'https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37' + } + ], + compare: 'https://github.com/docker/test-docker-action/compare/5f3331d7f704...860c1904a1ce', + created: false, + deleted: false, + forced: false, + head_commit: { + author: { + email: 'crazy-max@users.noreply.github.com', + name: 'CrazyMax', + username: 'crazy-max' + }, + committer: { + email: 'crazy-max@users.noreply.github.com', + name: 'CrazyMax', + username: 'crazy-max' + }, + distinct: true, + id: '860c1904a1ce19322e91ac35af1ab07466440c37', + message: 'hello dev', + timestamp: '2022-04-19T11:27:24+02:00', + tree_id: 'd2c60af597e863787d2d27f569e30495b0b92820', + url: 'https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37' + }, + organization: { + avatar_url: 'https://avatars.githubusercontent.com/u/5429470?v=4', + description: 'Docker helps developers bring their ideas to life by conquering the complexity of app development.', + events_url: 'https://api.github.com/orgs/docker/events', + hooks_url: 'https://api.github.com/orgs/docker/hooks', + id: 5429470, + issues_url: 'https://api.github.com/orgs/docker/issues', + login: 'docker', + members_url: 'https://api.github.com/orgs/docker/members{/member}', + node_id: 'MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=', + public_members_url: 'https://api.github.com/orgs/docker/public_members{/member}', + repos_url: 'https://api.github.com/orgs/docker/repos', + url: 'https://api.github.com/orgs/docker' + }, + pusher: { + email: 'github@crazymax.dev', + name: 'crazy-max' + }, + ref: 'refs/heads/dev', + repository: { + allow_forking: true, + archive_url: 'https://api.github.com/repos/docker/test-docker-action/{archive_format}{/ref}', + archived: false, + assignees_url: 'https://api.github.com/repos/docker/test-docker-action/assignees{/user}', + blobs_url: 'https://api.github.com/repos/docker/test-docker-action/git/blobs{/sha}', + branches_url: 'https://api.github.com/repos/docker/test-docker-action/branches{/branch}', + clone_url: 'https://github.com/docker/test-docker-action.git', + collaborators_url: 'https://api.github.com/repos/docker/test-docker-action/collaborators{/collaborator}', + comments_url: 'https://api.github.com/repos/docker/test-docker-action/comments{/number}', + commits_url: 'https://api.github.com/repos/docker/test-docker-action/commits{/sha}', + compare_url: 'https://api.github.com/repos/docker/test-docker-action/compare/{base}...{head}', + contents_url: 'https://api.github.com/repos/docker/test-docker-action/contents/{+path}', + contributors_url: 'https://api.github.com/repos/docker/test-docker-action/contributors', + created_at: 1596792180, + default_branch: 'master', + deployments_url: 'https://api.github.com/repos/docker/test-docker-action/deployments', + description: 'Test "Docker" Actions', + disabled: false, + downloads_url: 'https://api.github.com/repos/docker/test-docker-action/downloads', + events_url: 'https://api.github.com/repos/docker/test-docker-action/events', + fork: false, + forks: 1, + forks_count: 1, + forks_url: 'https://api.github.com/repos/docker/test-docker-action/forks', + full_name: 'docker/test-docker-action', + git_commits_url: 'https://api.github.com/repos/docker/test-docker-action/git/commits{/sha}', + git_refs_url: 'https://api.github.com/repos/docker/test-docker-action/git/refs{/sha}', + git_tags_url: 'https://api.github.com/repos/docker/test-docker-action/git/tags{/sha}', + git_url: 'git://github.com/docker/test-docker-action.git', + has_downloads: true, + has_issues: true, + has_pages: false, + has_projects: true, + has_wiki: true, + homepage: '', + hooks_url: 'https://api.github.com/repos/docker/test-docker-action/hooks', + html_url: 'https://github.com/docker/test-docker-action', + id: 285789493, + is_template: false, + issue_comment_url: 'https://api.github.com/repos/docker/test-docker-action/issues/comments{/number}', + issue_events_url: 'https://api.github.com/repos/docker/test-docker-action/issues/events{/number}', + issues_url: 'https://api.github.com/repos/docker/test-docker-action/issues{/number}', + keys_url: 'https://api.github.com/repos/docker/test-docker-action/keys{/key_id}', + labels_url: 'https://api.github.com/repos/docker/test-docker-action/labels{/name}', + language: 'JavaScript', + languages_url: 'https://api.github.com/repos/docker/test-docker-action/languages', + license: { + key: 'mit', + name: 'MIT License', + node_id: 'MDc6TGljZW5zZTEz', + spdx_id: 'MIT', + url: 'https://api.github.com/licenses/mit' + }, + master_branch: 'master', + merges_url: 'https://api.github.com/repos/docker/test-docker-action/merges', + milestones_url: 'https://api.github.com/repos/docker/test-docker-action/milestones{/number}', + mirror_url: null, + name: 'test-docker-action', + node_id: 'MDEwOlJlcG9zaXRvcnkyODU3ODk0OTM=', + notifications_url: 'https://api.github.com/repos/docker/test-docker-action/notifications{?since,all,participating}', + open_issues: 6, + open_issues_count: 6, + organization: 'docker', + owner: { + avatar_url: 'https://avatars.githubusercontent.com/u/5429470?v=4', + email: 'info@docker.com', + events_url: 'https://api.github.com/users/docker/events{/privacy}', + followers_url: 'https://api.github.com/users/docker/followers', + following_url: 'https://api.github.com/users/docker/following{/other_user}', + gists_url: 'https://api.github.com/users/docker/gists{/gist_id}', + gravatar_id: '', + html_url: 'https://github.com/docker', + id: 5429470, + login: 'docker', + name: 'docker', + node_id: 'MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=', + organizations_url: 'https://api.github.com/users/docker/orgs', + received_events_url: 'https://api.github.com/users/docker/received_events', + repos_url: 'https://api.github.com/users/docker/repos', + site_admin: false, + starred_url: 'https://api.github.com/users/docker/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/docker/subscriptions', + type: 'Organization', + url: 'https://api.github.com/users/docker' + }, + private: true, + pulls_url: 'https://api.github.com/repos/docker/test-docker-action/pulls{/number}', + pushed_at: 1650360446, + releases_url: 'https://api.github.com/repos/docker/test-docker-action/releases{/id}', + size: 796, + ssh_url: 'git@github.com:docker/test-docker-action.git', + stargazers: 0, + stargazers_count: 0, + stargazers_url: 'https://api.github.com/repos/docker/test-docker-action/stargazers', + statuses_url: 'https://api.github.com/repos/docker/test-docker-action/statuses/{sha}', + subscribers_url: 'https://api.github.com/repos/docker/test-docker-action/subscribers', + subscription_url: 'https://api.github.com/repos/docker/test-docker-action/subscription', + svn_url: 'https://github.com/docker/test-docker-action', + tags_url: 'https://api.github.com/repos/docker/test-docker-action/tags', + teams_url: 'https://api.github.com/repos/docker/test-docker-action/teams', + topics: [], + trees_url: 'https://api.github.com/repos/docker/test-docker-action/git/trees{/sha}', + updated_at: '2022-04-19T09:05:09Z', + url: 'https://github.com/docker/test-docker-action', + visibility: 'private', + watchers: 0, + watchers_count: 0 + }, + sender: { + avatar_url: 'https://avatars.githubusercontent.com/u/1951866?v=4', + events_url: 'https://api.github.com/users/crazy-max/events{/privacy}', + followers_url: 'https://api.github.com/users/crazy-max/followers', + following_url: 'https://api.github.com/users/crazy-max/following{/other_user}', + gists_url: 'https://api.github.com/users/crazy-max/gists{/gist_id}', + gravatar_id: '', + html_url: 'https://github.com/crazy-max', + id: 1951866, + login: 'crazy-max', + node_id: 'MDQ6VXNlcjE5NTE4NjY=', + organizations_url: 'https://api.github.com/users/crazy-max/orgs', + received_events_url: 'https://api.github.com/users/crazy-max/received_events', + repos_url: 'https://api.github.com/users/crazy-max/repos', + site_admin: false, + starred_url: 'https://api.github.com/users/crazy-max/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/crazy-max/subscriptions', + type: 'User', + url: 'https://api.github.com/users/crazy-max' + } + } +}; + +export const getOctokit = jest.fn(); diff --git a/__tests__/builder.test.ts b/__tests__/builder.test.ts index 105726b..8c03ad2 100644 --- a/__tests__/builder.test.ts +++ b/__tests__/builder.test.ts @@ -1,15 +1,37 @@ -import {jest, describe, expect, it, test, beforeEach} from '@jest/globals'; +import {afterEach, beforeEach, describe, expect, it, jest, test} from '@jest/globals'; import * as fs from 'fs'; import * as path from 'path'; -import {Builder} from '../src/builder'; +import {Builder, BuilderInfo} from '../src/builder'; +import {Context} from '../src/context'; beforeEach(() => { jest.clearAllMocks(); }); +jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise => { + return { + name: 'builder2', + driver: 'docker-container', + lastActivity: new Date('2023-01-16 09:45:23 +0000 UTC'), + nodes: [ + { + buildkitVersion: 'v0.11.0', + buildkitdFlags: '--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', + driverOpts: ['BUILDKIT_STEP_LOG_MAX_SIZE=10485760', 'BUILDKIT_STEP_LOG_MAX_SPEED=10485760', 'JAEGER_TRACE=localhost:6831', 'image=moby/buildkit:latest', 'network=host'], + endpoint: 'unix:///var/run/docker.sock', + name: 'builder20', + platforms: 'linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6', + status: 'running' + } + ] + }; +}); + describe('inspect', () => { it('valid', async () => { - const builder = new Builder(); + const builder = new Builder({ + context: new Context() + }); const builderInfo = await builder.inspect(''); expect(builderInfo).not.toBeUndefined(); expect(builderInfo.name).not.toEqual(''); diff --git a/__tests__/buildkit.test.ts b/__tests__/buildkit.test.ts index ebfa37b..c0f69a9 100644 --- a/__tests__/buildkit.test.ts +++ b/__tests__/buildkit.test.ts @@ -1,23 +1,23 @@ -import {afterEach, beforeEach, describe, expect, it, jest, test} from '@jest/globals'; +import {describe, expect, it, jest, test, beforeEach, afterEach} from '@jest/globals'; import * as fs from 'fs'; import * as path from 'path'; -import * as semver from 'semver'; import rimraf from 'rimraf'; +import * as semver from 'semver'; import {BuildKit} from '../src/buildkit'; import {Builder, BuilderInfo} from '../src/builder'; +import {Context} from '../src/context'; const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep); const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep); -jest.spyOn(BuildKit.prototype as any, 'tmpDir').mockImplementation((): string => { +jest.spyOn(Context.prototype as any, 'tmpDir').mockImplementation((): string => { if (!fs.existsSync(tmpDir)) { fs.mkdirSync(tmpDir, {recursive: true}); } return tmpDir; }); - -jest.spyOn(BuildKit.prototype as any, 'tmpName').mockImplementation((): string => { +jest.spyOn(Context.prototype as any, 'tmpName').mockImplementation((): string => { return tmpName; }); @@ -50,7 +50,9 @@ jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise { it('valid', async () => { - const buildkit = new BuildKit(); + const buildkit = new BuildKit({ + context: new Context() + }); const version = await buildkit.getVersion('builder2'); expect(semver.valid(version)).not.toBeNull(); }); @@ -61,7 +63,9 @@ describe('satisfies', () => { ['builder2', '>=0.10.0', true], ['builder2', '>0.11.0', false] ])('given %p', async (builderName, range, expected) => { - const buildkit = new BuildKit(); + const buildkit = new BuildKit({ + context: new Context() + }); expect(await buildkit.versionSatisfies(builderName, range)).toBe(expected); }); }); @@ -81,7 +85,9 @@ describe('generateConfig', () => { ] ])('given %p config', async (val, file, exValue, error: Error) => { try { - const buildkit = new BuildKit(); + const buildkit = new BuildKit({ + context: new Context() + }); let config: string; if (file) { config = buildkit.generateConfigFile(val); diff --git a/__tests__/buildx.test.ts b/__tests__/buildx.test.ts index 8b282f8..c13befd 100644 --- a/__tests__/buildx.test.ts +++ b/__tests__/buildx.test.ts @@ -1,11 +1,12 @@ -import {afterEach, beforeEach, describe, expect, it, jest, test} from '@jest/globals'; +import {describe, expect, it, jest, test, beforeEach, afterEach} from '@jest/globals'; import * as fs from 'fs'; import * as path from 'path'; +import rimraf from 'rimraf'; import * as semver from 'semver'; import * as exec from '@actions/exec'; -import rimraf from 'rimraf'; import {Buildx} from '../src/buildx'; +import {Context} from '../src/context'; const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep); const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep); @@ -14,12 +15,15 @@ const metadata = `{ "containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c" }`; -jest.spyOn(Buildx.prototype as any, 'tmpDir').mockImplementation((): string => { +jest.spyOn(Context.prototype as any, 'tmpDir').mockImplementation((): string => { if (!fs.existsSync(tmpDir)) { fs.mkdirSync(tmpDir, {recursive: true}); } return tmpDir; }); +jest.spyOn(Context.prototype as any, 'tmpName').mockImplementation((): string => { + return tmpName; +}); beforeEach(() => { jest.clearAllMocks(); @@ -29,13 +33,11 @@ afterEach(() => { rimraf.sync(tmpDir); }); -jest.spyOn(Buildx.prototype as any, 'tmpName').mockImplementation((): string => { - return tmpName; -}); - describe('getBuildImageID', () => { it('matches', async () => { - const buildx = new Buildx(); + const buildx = new Buildx({ + context: new Context() + }); const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9'; const imageIDFile = buildx.getBuildImageIDFilePath(); await fs.writeFileSync(imageIDFile, imageID); @@ -46,7 +48,9 @@ describe('getBuildImageID', () => { describe('getBuildMetadata', () => { it('matches', async () => { - const buildx = new Buildx(); + const buildx = new Buildx({ + context: new Context() + }); const metadataFile = buildx.getBuildMetadataFilePath(); await fs.writeFileSync(metadataFile, metadata); const expected = buildx.getBuildMetadata(); @@ -56,7 +60,9 @@ describe('getBuildMetadata', () => { describe('getDigest', () => { it('matches', async () => { - const buildx = new Buildx(); + const buildx = new Buildx({ + context: new Context() + }); const metadataFile = buildx.getBuildMetadataFilePath(); await fs.writeFileSync(metadataFile, metadata); const expected = buildx.getDigest(); @@ -116,6 +122,7 @@ describe('isAvailable', () => { it('docker cli', async () => { const execSpy = jest.spyOn(exec, 'getExecOutput'); const buildx = new Buildx({ + context: new Context(), standalone: false }); buildx.isAvailable().catch(() => { @@ -130,6 +137,7 @@ describe('isAvailable', () => { it('standalone', async () => { const execSpy = jest.spyOn(exec, 'getExecOutput'); const buildx = new Buildx({ + context: new Context(), standalone: true }); buildx.isAvailable().catch(() => { @@ -147,6 +155,7 @@ describe('printVersion', () => { it('docker cli', () => { const execSpy = jest.spyOn(exec, 'exec'); const buildx = new Buildx({ + context: new Context(), standalone: false }); buildx.printVersion(); @@ -157,6 +166,7 @@ describe('printVersion', () => { it('standalone', () => { const execSpy = jest.spyOn(exec, 'exec'); const buildx = new Buildx({ + context: new Context(), standalone: true }); buildx.printVersion(); @@ -168,8 +178,10 @@ describe('printVersion', () => { describe('getVersion', () => { it('valid', async () => { - const buildx = new Buildx(); - expect(semver.valid(await buildx.version())).not.toBeNull(); + const buildx = new Buildx({ + context: new Context() + }); + expect(semver.valid(await buildx.version)).not.toBeNull(); }); }); @@ -190,7 +202,9 @@ describe('versionSatisfies', () => { ['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false], ['f117971', '>0.6.0', true] ])('given %p', async (version, range, expected) => { - const buildx = new Buildx(); + const buildx = new Buildx({ + context: new Context() + }); expect(await buildx.versionSatisfies(range, version)).toBe(expected); }); }); @@ -207,7 +221,9 @@ describe('generateBuildSecret', () => { [`notfound=secret`, true, '', '', new Error('secret file secret not found')] ])('given %p key and %p secret', async (kvp: string, file: boolean, exKey: string, exValue: string, error: Error) => { try { - const buildx = new Buildx(); + const buildx = new Buildx({ + context: new Context() + }); let secret: string; if (file) { secret = buildx.generateBuildSecretFile(kvp); diff --git a/__tests__/context.test.ts b/__tests__/context.test.ts new file mode 100644 index 0000000..2adab37 --- /dev/null +++ b/__tests__/context.test.ts @@ -0,0 +1,87 @@ +import fs from 'fs'; +import path from 'path'; +import rimraf from 'rimraf'; +import {describe, expect, jest, it, beforeEach, afterEach} from '@jest/globals'; + +import {Context, ReposGetResponseData} from '../src/context'; + +const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep); +const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep); + +beforeEach(() => { + jest.clearAllMocks(); +}); + +jest.spyOn(Context.prototype as any, 'tmpDir').mockImplementation((): string => { + if (!fs.existsSync(tmpDir)) { + fs.mkdirSync(tmpDir, {recursive: true}); + } + return tmpDir; +}); +jest.spyOn(Context.prototype as any, 'tmpName').mockImplementation((): string => { + return tmpName; +}); + +beforeEach(() => { + jest.clearAllMocks(); +}); + +afterEach(() => { + rimraf.sync(tmpDir); +}); + +import * as repoFixture from './fixtures/repo.json'; +jest.spyOn(Context.prototype as any, 'repoData').mockImplementation((): Promise => { + return >(repoFixture as unknown); +}); + +describe('serverURL', () => { + const originalEnv = process.env; + beforeEach(() => { + jest.resetModules(); + process.env = { + ...originalEnv, + GITHUB_SERVER_URL: 'https://foo.github.com' + }; + }); + afterEach(() => { + process.env = originalEnv; + }); + it('returns default', async () => { + process.env.GITHUB_SERVER_URL = ''; + const context = new Context(); + expect(context.serverURL).toEqual('https://github.com'); + }); + it('returns from env', async () => { + const context = new Context(); + expect(context.serverURL).toEqual('https://foo.github.com'); + }); +}); + +describe('gitContext', () => { + it('returns refs/heads/master', async () => { + const context = new Context(); + expect(context.buildGitContext).toEqual('https://github.com/docker/actions-toolkit.git#refs/heads/master'); + }); +}); + +describe('provenanceBuilderID', () => { + it('returns 123', async () => { + const context = new Context(); + expect(context.provenanceBuilderID).toEqual('https://github.com/docker/actions-toolkit/actions/runs/123'); + }); +}); + +describe('repo', () => { + it('returns GitHub repository', async () => { + const context = new Context(); + expect((await context.repoData()).name).toEqual('Hello-World'); + }); +}); + +describe('fromPayload', () => { + it('returns repository name from payload', async () => { + const context = new Context(); + expect(await context.fromPayload('repository.name')).toEqual('test-docker-action'); + }); +}); diff --git a/__tests__/fixtures/github-payload.json b/__tests__/fixtures/github-payload.json deleted file mode 100644 index 3a5abdb..0000000 --- a/__tests__/fixtures/github-payload.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "after": "860c1904a1ce19322e91ac35af1ab07466440c37", - "base_ref": null, - "before": "5f3331d7f7044c18ca9f12c77d961c4d7cf3276a", - "commits": [ - { - "author": { - "email": "crazy-max@users.noreply.github.com", - "name": "CrazyMax", - "username": "crazy-max" - }, - "committer": { - "email": "crazy-max@users.noreply.github.com", - "name": "CrazyMax", - "username": "crazy-max" - }, - "distinct": true, - "id": "860c1904a1ce19322e91ac35af1ab07466440c37", - "message": "hello dev", - "timestamp": "2022-04-19T11:27:24+02:00", - "tree_id": "d2c60af597e863787d2d27f569e30495b0b92820", - "url": "https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37" - } - ], - "compare": "https://github.com/docker/test-docker-action/compare/5f3331d7f704...860c1904a1ce", - "created": false, - "deleted": false, - "forced": false, - "head_commit": { - "author": { - "email": "crazy-max@users.noreply.github.com", - "name": "CrazyMax", - "username": "crazy-max" - }, - "committer": { - "email": "crazy-max@users.noreply.github.com", - "name": "CrazyMax", - "username": "crazy-max" - }, - "distinct": true, - "id": "860c1904a1ce19322e91ac35af1ab07466440c37", - "message": "hello dev", - "timestamp": "2022-04-19T11:27:24+02:00", - "tree_id": "d2c60af597e863787d2d27f569e30495b0b92820", - "url": "https://github.com/docker/test-docker-action/commit/860c1904a1ce19322e91ac35af1ab07466440c37" - }, - "organization": { - "avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4", - "description": "Docker helps developers bring their ideas to life by conquering the complexity of app development.", - "events_url": "https://api.github.com/orgs/docker/events", - "hooks_url": "https://api.github.com/orgs/docker/hooks", - "id": 5429470, - "issues_url": "https://api.github.com/orgs/docker/issues", - "login": "docker", - "members_url": "https://api.github.com/orgs/docker/members{/member}", - "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=", - "public_members_url": "https://api.github.com/orgs/docker/public_members{/member}", - "repos_url": "https://api.github.com/orgs/docker/repos", - "url": "https://api.github.com/orgs/docker" - }, - "pusher": { - "email": "github@crazymax.dev", - "name": "crazy-max" - }, - "ref": "refs/heads/dev", - "repository": { - "allow_forking": true, - "archive_url": "https://api.github.com/repos/docker/test-docker-action/{archive_format}{/ref}", - "archived": false, - "assignees_url": "https://api.github.com/repos/docker/test-docker-action/assignees{/user}", - "blobs_url": "https://api.github.com/repos/docker/test-docker-action/git/blobs{/sha}", - "branches_url": "https://api.github.com/repos/docker/test-docker-action/branches{/branch}", - "clone_url": "https://github.com/docker/test-docker-action.git", - "collaborators_url": "https://api.github.com/repos/docker/test-docker-action/collaborators{/collaborator}", - "comments_url": "https://api.github.com/repos/docker/test-docker-action/comments{/number}", - "commits_url": "https://api.github.com/repos/docker/test-docker-action/commits{/sha}", - "compare_url": "https://api.github.com/repos/docker/test-docker-action/compare/{base}...{head}", - "contents_url": "https://api.github.com/repos/docker/test-docker-action/contents/{+path}", - "contributors_url": "https://api.github.com/repos/docker/test-docker-action/contributors", - "created_at": 1596792180, - "default_branch": "master", - "deployments_url": "https://api.github.com/repos/docker/test-docker-action/deployments", - "description": "Test \"Docker\" Actions", - "disabled": false, - "downloads_url": "https://api.github.com/repos/docker/test-docker-action/downloads", - "events_url": "https://api.github.com/repos/docker/test-docker-action/events", - "fork": false, - "forks": 1, - "forks_count": 1, - "forks_url": "https://api.github.com/repos/docker/test-docker-action/forks", - "full_name": "docker/test-docker-action", - "git_commits_url": "https://api.github.com/repos/docker/test-docker-action/git/commits{/sha}", - "git_refs_url": "https://api.github.com/repos/docker/test-docker-action/git/refs{/sha}", - "git_tags_url": "https://api.github.com/repos/docker/test-docker-action/git/tags{/sha}", - "git_url": "git://github.com/docker/test-docker-action.git", - "has_downloads": true, - "has_issues": true, - "has_pages": false, - "has_projects": true, - "has_wiki": true, - "homepage": "", - "hooks_url": "https://api.github.com/repos/docker/test-docker-action/hooks", - "html_url": "https://github.com/docker/test-docker-action", - "id": 285789493, - "is_template": false, - "issue_comment_url": "https://api.github.com/repos/docker/test-docker-action/issues/comments{/number}", - "issue_events_url": "https://api.github.com/repos/docker/test-docker-action/issues/events{/number}", - "issues_url": "https://api.github.com/repos/docker/test-docker-action/issues{/number}", - "keys_url": "https://api.github.com/repos/docker/test-docker-action/keys{/key_id}", - "labels_url": "https://api.github.com/repos/docker/test-docker-action/labels{/name}", - "language": "JavaScript", - "languages_url": "https://api.github.com/repos/docker/test-docker-action/languages", - "license": { - "key": "mit", - "name": "MIT License", - "node_id": "MDc6TGljZW5zZTEz", - "spdx_id": "MIT", - "url": "https://api.github.com/licenses/mit" - }, - "master_branch": "master", - "merges_url": "https://api.github.com/repos/docker/test-docker-action/merges", - "milestones_url": "https://api.github.com/repos/docker/test-docker-action/milestones{/number}", - "mirror_url": null, - "name": "test-docker-action", - "node_id": "MDEwOlJlcG9zaXRvcnkyODU3ODk0OTM=", - "notifications_url": "https://api.github.com/repos/docker/test-docker-action/notifications{?since,all,participating}", - "open_issues": 6, - "open_issues_count": 6, - "organization": "docker", - "owner": { - "avatar_url": "https://avatars.githubusercontent.com/u/5429470?v=4", - "email": "info@docker.com", - "events_url": "https://api.github.com/users/docker/events{/privacy}", - "followers_url": "https://api.github.com/users/docker/followers", - "following_url": "https://api.github.com/users/docker/following{/other_user}", - "gists_url": "https://api.github.com/users/docker/gists{/gist_id}", - "gravatar_id": "", - "html_url": "https://github.com/docker", - "id": 5429470, - "login": "docker", - "name": "docker", - "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0Mjk0NzA=", - "organizations_url": "https://api.github.com/users/docker/orgs", - "received_events_url": "https://api.github.com/users/docker/received_events", - "repos_url": "https://api.github.com/users/docker/repos", - "site_admin": false, - "starred_url": "https://api.github.com/users/docker/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/docker/subscriptions", - "type": "Organization", - "url": "https://api.github.com/users/docker" - }, - "private": true, - "pulls_url": "https://api.github.com/repos/docker/test-docker-action/pulls{/number}", - "pushed_at": 1650360446, - "releases_url": "https://api.github.com/repos/docker/test-docker-action/releases{/id}", - "size": 796, - "ssh_url": "git@github.com:docker/test-docker-action.git", - "stargazers": 0, - "stargazers_count": 0, - "stargazers_url": "https://api.github.com/repos/docker/test-docker-action/stargazers", - "statuses_url": "https://api.github.com/repos/docker/test-docker-action/statuses/{sha}", - "subscribers_url": "https://api.github.com/repos/docker/test-docker-action/subscribers", - "subscription_url": "https://api.github.com/repos/docker/test-docker-action/subscription", - "svn_url": "https://github.com/docker/test-docker-action", - "tags_url": "https://api.github.com/repos/docker/test-docker-action/tags", - "teams_url": "https://api.github.com/repos/docker/test-docker-action/teams", - "topics": [], - "trees_url": "https://api.github.com/repos/docker/test-docker-action/git/trees{/sha}", - "updated_at": "2022-04-19T09:05:09Z", - "url": "https://github.com/docker/test-docker-action", - "visibility": "private", - "watchers": 0, - "watchers_count": 0 - }, - "sender": { - "avatar_url": "https://avatars.githubusercontent.com/u/1951866?v=4", - "events_url": "https://api.github.com/users/crazy-max/events{/privacy}", - "followers_url": "https://api.github.com/users/crazy-max/followers", - "following_url": "https://api.github.com/users/crazy-max/following{/other_user}", - "gists_url": "https://api.github.com/users/crazy-max/gists{/gist_id}", - "gravatar_id": "", - "html_url": "https://github.com/crazy-max", - "id": 1951866, - "login": "crazy-max", - "node_id": "MDQ6VXNlcjE5NTE4NjY=", - "organizations_url": "https://api.github.com/users/crazy-max/orgs", - "received_events_url": "https://api.github.com/users/crazy-max/received_events", - "repos_url": "https://api.github.com/users/crazy-max/repos", - "site_admin": false, - "starred_url": "https://api.github.com/users/crazy-max/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/crazy-max/subscriptions", - "type": "User", - "url": "https://api.github.com/users/crazy-max" - } -} diff --git a/__tests__/git.test.ts b/__tests__/git.test.ts index 45ceaed..a4de324 100644 --- a/__tests__/git.test.ts +++ b/__tests__/git.test.ts @@ -1,5 +1,6 @@ import {beforeEach, describe, expect, it, jest} from '@jest/globals'; -import * as git from '../src/git'; + +import {Git} from '../src/git'; beforeEach(() => { jest.clearAllMocks(); @@ -8,7 +9,7 @@ beforeEach(() => { describe('git', () => { it('returns git remote ref', async () => { try { - expect(await git.getRemoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head')).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'); + expect(await Git.getRemoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head')).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa'); } catch (e) { // eslint-disable-next-line jest/no-conditional-expect expect(e).toEqual(null); diff --git a/__tests__/github.test.ts b/__tests__/github.test.ts deleted file mode 100644 index 01cc841..0000000 --- a/__tests__/github.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import {describe, expect, jest, it, beforeEach, afterEach} from '@jest/globals'; - -import {Context} from '@actions/github/lib/context'; -import {GitHub, Payload, ReposGetResponseData} from '../src/github'; - -beforeEach(() => { - jest.clearAllMocks(); - GitHub.getInstance().reset(); -}); - -jest.spyOn(GitHub.prototype, 'context').mockImplementation((): Context => { - return new Context(); -}); - -import * as repoFixture from './fixtures/repo.json'; -jest.spyOn(GitHub.prototype, 'repo').mockImplementation((): Promise => { - return >(repoFixture as unknown); -}); - -import * as payloadFixture from './fixtures/github-payload.json'; -jest.spyOn(GitHub.prototype as any, 'payload').mockImplementation((): Promise => { - return >(payloadFixture as unknown); -}); -jest.spyOn(GitHub.prototype as any, 'ref').mockImplementation((): string => { - return 'refs/heads/master'; -}); - -describe('serverURL', () => { - const originalEnv = process.env; - beforeEach(() => { - jest.resetModules(); - process.env = { - ...originalEnv, - GITHUB_SERVER_URL: 'https://foo.github.com' - }; - }); - afterEach(() => { - process.env = originalEnv; - }); - it('returns default', async () => { - process.env.GITHUB_SERVER_URL = ''; - expect(GitHub.getInstance().serverURL()).toEqual('https://github.com'); - }); - it('returns from env', async () => { - expect(GitHub.getInstance().serverURL()).toEqual('https://foo.github.com'); - }); -}); - -describe('gitContext', () => { - it('returns refs/heads/master', async () => { - expect(GitHub.getInstance().gitContext()).toEqual('https://github.com/docker/test-docker-action.git#refs/heads/master'); - }); -}); - -describe('provenanceBuilderID', () => { - it('returns 123', async () => { - expect(GitHub.getInstance().provenanceBuilderID()).toEqual('https://github.com/docker/test-docker-action/actions/runs/123'); - }); -}); - -describe('repo', () => { - it('returns GitHub repository', async () => { - const repo = await GitHub.getInstance().repo(process.env.GITHUB_TOKEN || ''); - expect(repo.name).toEqual('Hello-World'); - }); -}); - -describe('fromPayload', () => { - it('returns repository name from payload', async () => { - const repoName = await GitHub.getInstance().fromPayload('repository.name'); - expect(repoName).toEqual('test-docker-action'); - }); -}); diff --git a/jest.config.ts b/jest.config.ts index f94c65b..36661f0 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,6 +1,5 @@ process.env = Object.assign({}, process.env, { - GITHUB_REPOSITORY: 'docker/test-docker-action', - GITHUB_RUN_ID: '123', + GITHUB_REPOSITORY: 'docker/actions-toolkit', RUNNER_TEMP: '/tmp/github_runner', RUNNER_TOOL_CACHE: '/tmp/github_tool_cache' }) as { @@ -19,5 +18,7 @@ module.exports = { moduleNameMapper: { '^csv-parse/sync': '/node_modules/csv-parse/dist/cjs/sync.cjs' }, + collectCoverageFrom: ['src/**/{!(toolkit.ts),}.ts'], + coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__mocks__/', '__tests__/'], verbose: true }; diff --git a/package.json b/package.json index 5711272..065a717 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ ], "author": "Docker Inc.", "license": "Apache-2.0", - "main": "lib/index.js", - "types": "lib/index.d.ts", + "main": "lib/toolkit.js", + "types": "lib/toolkit.d.ts", "directories": { "lib": "lib", "test": "__tests__" diff --git a/src/builder.ts b/src/builder.ts index a75e95b..634a6e6 100644 --- a/src/builder.ts +++ b/src/builder.ts @@ -1,6 +1,7 @@ import * as exec from '@actions/exec'; import {Buildx} from './buildx'; +import {Context} from './context'; export interface BuilderInfo { name?: string; @@ -20,14 +21,21 @@ export interface NodeInfo { } export interface BuilderOpts { + context: Context; buildx?: Buildx; } export class Builder { - private buildx: Buildx; + private readonly context: Context; + private readonly buildx: Buildx; - constructor(opts?: BuilderOpts) { - this.buildx = opts?.buildx || new Buildx(); + constructor(opts: BuilderOpts) { + this.context = opts.context; + this.buildx = + opts?.buildx || + new Buildx({ + context: this.context + }); } public async inspect(name: string): Promise { diff --git a/src/buildkit.ts b/src/buildkit.ts index b9e9402..8186727 100644 --- a/src/buildkit.ts +++ b/src/buildkit.ts @@ -1,37 +1,36 @@ import fs from 'fs'; -import os from 'os'; -import path from 'path'; import * as core from '@actions/core'; import * as exec from '@actions/exec'; import * as semver from 'semver'; -import * as tmp from 'tmp'; +import {Context} from './context'; import {Buildx} from './buildx'; import {Builder, BuilderInfo} from './builder'; export interface BuildKitOpts { + context: Context; buildx?: Buildx; } export class BuildKit { - private buildx: Buildx; + private readonly context: Context; + private readonly buildx: Buildx; private containerNamePrefix = 'buildx_buildkit_'; - private tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-')).split(path.sep).join(path.posix.sep); - constructor(opts?: BuildKitOpts) { - this.buildx = opts?.buildx || new Buildx(); - } - - public tmpDir() { - return this.tmpdir; - } - - public tmpName(options?: tmp.TmpNameOptions): string { - return tmp.tmpNameSync(options); + constructor(opts: BuildKitOpts) { + this.context = opts.context; + this.buildx = + opts?.buildx || + new Buildx({ + context: this.context + }); } private async getBuilderInfo(name: string): Promise { - const builder = new Builder({buildx: this.buildx}); + const builder = new Builder({ + context: this.context, + buildx: this.buildx + }); return builder.inspect(name); } @@ -118,7 +117,7 @@ export class BuildKit { } s = fs.readFileSync(s, {encoding: 'utf-8'}); } - const configFile = this.tmpName({tmpdir: this.tmpDir()}); + const configFile = this.context.tmpName({tmpdir: this.context.tmpDir()}); fs.writeFileSync(configFile, s); return configFile; } diff --git a/src/buildx.ts b/src/buildx.ts index 922e8b2..98e9605 100644 --- a/src/buildx.ts +++ b/src/buildx.ts @@ -1,39 +1,32 @@ import fs from 'fs'; -import os from 'os'; import path from 'path'; import * as exec from '@actions/exec'; import {parse} from 'csv-parse/sync'; import * as semver from 'semver'; -import * as tmp from 'tmp'; import {Docker} from './docker'; +import {Context} from './context'; export interface BuildxOpts { + context: Context; standalone?: boolean; } export class Buildx { - private _standalone: boolean; - private _version: Promise; - private _tmpdir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-')).split(path.sep).join(path.posix.sep); + private readonly context: Context; + public standalone: boolean; + public version: Promise; - constructor(opts?: BuildxOpts) { - this._standalone = opts?.standalone ?? !Docker.isAvailable(); - this._version = this.getVersion(); - } - - public tmpDir() { - return this._tmpdir; - } - - public tmpName(options?: tmp.TmpNameOptions): string { - return tmp.tmpNameSync(options); + constructor(opts: BuildxOpts) { + this.context = opts.context; + this.standalone = opts?.standalone ?? !Docker.isAvailable(); + this.version = this.getVersion(); } public getCommand(args: Array) { return { - command: this._standalone ? 'buildx' : 'docker', - args: this._standalone ? args : ['buildx', ...args] + command: this.standalone ? 'buildx' : 'docker', + args: this.standalone ? args : ['buildx', ...args] }; } @@ -71,10 +64,6 @@ export class Buildx { }); } - public async version(): Promise { - return this._version; - } - public async printVersion() { const cmd = this.getCommand(['version']); await exec.exec(cmd.command, cmd.args, { @@ -91,16 +80,16 @@ export class Buildx { } public async versionSatisfies(range: string, version?: string): Promise { - const ver = version ?? (await this.version()); + const ver = version ?? (await this.version); return semver.satisfies(ver, range) || /^[0-9a-f]{7}$/.exec(ver) !== null; } public getBuildImageIDFilePath(): string { - return path.join(this.tmpDir(), 'iidfile').split(path.sep).join(path.posix.sep); + return path.join(this.context.tmpDir(), 'iidfile').split(path.sep).join(path.posix.sep); } public getBuildMetadataFilePath(): string { - return path.join(this.tmpDir(), 'metadata-file').split(path.sep).join(path.posix.sep); + return path.join(this.context.tmpDir(), 'metadata-file').split(path.sep).join(path.posix.sep); } public getBuildImageID(): string | undefined { @@ -143,7 +132,7 @@ export class Buildx { return this.generateBuildSecret(kvp, true); } - private generateBuildSecret(kvp: string, file: boolean): string { + public generateBuildSecret(kvp: string, file: boolean): string { const delimiterIndex = kvp.indexOf('='); const key = kvp.substring(0, delimiterIndex); let value = kvp.substring(delimiterIndex + 1); @@ -156,7 +145,7 @@ export class Buildx { } value = fs.readFileSync(value, {encoding: 'utf-8'}); } - const secretFile = this.tmpName({tmpdir: this.tmpDir()}); + const secretFile = this.context.tmpName({tmpdir: this.context.tmpDir()}); fs.writeFileSync(secretFile, value); return `id=${key},src=${secretFile}`; } diff --git a/src/context.ts b/src/context.ts new file mode 100644 index 0000000..af7520a --- /dev/null +++ b/src/context.ts @@ -0,0 +1,71 @@ +import fs from 'fs'; +import os from 'os'; +import path from 'path'; +import * as tmp from 'tmp'; +import jwt_decode, {JwtPayload} from 'jwt-decode'; +import {GitHub} from '@actions/github/lib/utils'; +import * as github from '@actions/github'; +import {components as OctoOpenApiTypes} from '@octokit/openapi-types'; + +export type ReposGetResponseData = OctoOpenApiTypes['schemas']['repository']; +export interface Jwt extends JwtPayload { + ac?: string; +} + +export class Context { + public serverURL: string; + public gitRef: string; + public buildGitContext: string; + public provenanceBuilderID: string; + public octokit: InstanceType; + + private readonly _tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-')).split(path.sep).join(path.posix.sep); + + constructor(githubToken?: string) { + this.gitRef = github.context.ref; + if (github.context.sha && this.gitRef && !this.gitRef.startsWith('refs/')) { + this.gitRef = `refs/heads/${github.context.ref}`; + } + if (github.context.sha && !this.gitRef.startsWith(`refs/pull/`)) { + this.gitRef = github.context.sha; + } + this.serverURL = process.env.GITHUB_SERVER_URL || 'https://github.com'; + this.buildGitContext = `${this.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git#${this.gitRef}`; + this.provenanceBuilderID = `${this.serverURL}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`; + this.octokit = github.getOctokit(`${githubToken}`); + } + + public tmpDir(): string { + return this._tmpDir; + } + + public tmpName(options?: tmp.TmpNameOptions): string { + return tmp.tmpNameSync(options); + } + + public repoData(): Promise { + return this.octokit.rest.repos.get({...github.context.repo}).then(response => response.data as ReposGetResponseData); + } + + public parseRuntimeToken(): Jwt { + return jwt_decode(process.env['ACTIONS_RUNTIME_TOKEN'] || ''); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public fromPayload(path: string): any { + return this.select(github.context.payload, path); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private select(obj: any, path: string): any { + if (!obj) { + return undefined; + } + const i = path.indexOf('.'); + if (i < 0) { + return obj[path]; + } + const key = path.slice(0, i); + return this.select(obj[key], path.slice(i + 1)); + } +} diff --git a/src/git.ts b/src/git.ts index 9369af8..217b037 100644 --- a/src/git.ts +++ b/src/git.ts @@ -1,19 +1,21 @@ import * as exec from '@actions/exec'; -export async function getRemoteSha(repo: string, ref: string): Promise { - return await exec - .getExecOutput(`git`, ['ls-remote', repo, ref], { - ignoreReturnCode: true, - silent: true - }) - .then(res => { - if (res.stderr.length > 0 && res.exitCode != 0) { - throw new Error(res.stderr); - } - const [rsha] = res.stdout.trim().split(/[\s\t]/); - if (rsha.length == 0) { - throw new Error(`Cannot find remote ref for ${repo}#${ref}`); - } - return rsha; - }); +export class Git { + public static async getRemoteSha(repo: string, ref: string): Promise { + return await exec + .getExecOutput(`git`, ['ls-remote', repo, ref], { + ignoreReturnCode: true, + silent: true + }) + .then(res => { + if (res.stderr.length > 0 && res.exitCode != 0) { + throw new Error(res.stderr); + } + const [rsha] = res.stdout.trim().split(/[\s\t]/); + if (rsha.length == 0) { + throw new Error(`Cannot find remote ref for ${repo}#${ref}`); + } + return rsha; + }); + } } diff --git a/src/github.ts b/src/github.ts deleted file mode 100644 index 791aab6..0000000 --- a/src/github.ts +++ /dev/null @@ -1,90 +0,0 @@ -import jwt_decode, {JwtPayload} from 'jwt-decode'; -import * as github from '@actions/github'; -import {Context} from '@actions/github/lib/context'; -import {components as OctoOpenApiTypes} from '@octokit/openapi-types'; -import {WebhookPayload} from '@actions/github/lib/interfaces'; - -export type Payload = WebhookPayload; -export type ReposGetResponseData = OctoOpenApiTypes['schemas']['repository']; - -interface Jwt extends JwtPayload { - ac?: string; -} - -export class GitHub { - private static instance?: GitHub; - static getInstance = (): GitHub => (GitHub.instance = GitHub.instance ?? new GitHub()); - private static _serverURL: string; - private static _gitContext: string; - private static _provenanceBuilderID: string; - - private constructor() { - let ref = this.ref(); - if (github.context.sha && ref && !ref.startsWith('refs/')) { - ref = `refs/heads/${this.ref()}`; - } - if (github.context.sha && !ref.startsWith(`refs/pull/`)) { - ref = github.context.sha; - } - GitHub._serverURL = process.env.GITHUB_SERVER_URL || 'https://github.com'; - GitHub._gitContext = `${GitHub._serverURL}/${github.context.repo.owner}/${github.context.repo.repo}.git#${ref}`; - GitHub._provenanceBuilderID = `${GitHub._serverURL}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`; - } - - public reset() { - GitHub.instance = undefined; - } - - public context(): Context { - return github.context; - } - - private ref(): string { - return github.context.ref; - } - - public serverURL() { - return GitHub._serverURL; - } - - public gitContext() { - return GitHub._gitContext; - } - - public provenanceBuilderID() { - return GitHub._provenanceBuilderID; - } - - private payload(): Payload { - return github.context.payload; - } - - public repo(token: string): Promise { - return github - .getOctokit(token) - .rest.repos.get({...github.context.repo}) - .then(response => response.data as ReposGetResponseData); - } - - public parseRuntimeToken(): Jwt { - return jwt_decode(process.env['ACTIONS_RUNTIME_TOKEN'] || ''); - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - public fromPayload(path: string): any { - return this.select(this.payload(), path); - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private select(obj: any, path: string): any { - if (!obj) { - return undefined; - } - const i = path.indexOf('.'); - if (i < 0) { - return obj[path]; - } - const key = path.slice(0, i); - return this.select(obj[key], path.slice(i + 1)); - } -} diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index f6d51b8..0000000 --- a/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * as buildkit from './buildkit'; -export * as buildx from './buildx'; -export * as docker from './docker'; -export * as git from './git'; -export * as github from './github'; -export * as util from './util'; diff --git a/src/toolkit.ts b/src/toolkit.ts new file mode 100644 index 0000000..54c2ce4 --- /dev/null +++ b/src/toolkit.ts @@ -0,0 +1,31 @@ +import {Context} from './context'; +import {Buildx} from './buildx'; +import {BuildKit} from './buildkit'; + +export {BuildKit, BuildKitOpts} from './buildkit'; +export {Builder, BuilderOpts, BuilderInfo, NodeInfo} from './builder'; +export {Buildx, BuildxOpts} from './buildx'; +export {Context, ReposGetResponseData, Jwt} from './context'; +export {Docker} from './docker'; +export {Git} from './git'; +export {Util} from './util'; + +export interface ToolkitOpts { + /** + * GitHub token to use for authentication. + * Uses `process.env.GITHUB_TOKEN` by default. + */ + githubToken?: string; +} + +export class Toolkit { + public context: Context; + public buildx: Buildx; + public buildkit: BuildKit; + + constructor(opts: ToolkitOpts = {}) { + this.context = new Context(opts.githubToken); + this.buildx = new Buildx({context: this.context}); + this.buildkit = new BuildKit({context: this.context, buildx: this.buildx}); + } +} diff --git a/tsconfig.json b/tsconfig.json index 738674a..f6a43ac 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,9 +15,10 @@ "useUnknownInCatchVariables": false, }, "exclude": [ + "./__mocks__/**/*", + "./__tests__/**/*", "./lib/**/*", "node_modules", - "**/*.test.ts", "jest.config.ts" ] }