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

bump: @humanitec/autogen and modernize the setup #51

Merged
merged 1 commit into from
Jun 25, 2024
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
33 changes: 0 additions & 33 deletions .eslintrc.json

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ jobs:

strategy:
matrix:
node-version: [16.x, 18.x]
node-version: [20.x, 22.x]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
Expand Down
224 changes: 122 additions & 102 deletions action.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
import {describe, expect, test, beforeEach, afterAll, afterEach} from '@jest/globals';
import {join as pathJoin} from 'node:path';
import {runAction} from './action';
import {randomBytes} from 'crypto';
import {mkdir} from 'node:fs/promises';
import {createApiClient} from './humanitec';
import {exec as actionsExec} from '@actions/exec';
import {
describe,
expect,
test,
beforeEach,
afterAll,
afterEach,
} from "vitest";
import { join as pathJoin } from "node:path";
import { runAction } from "./action.js";
import { randomBytes } from "crypto";
import { mkdir } from "node:fs/promises";
import { createApiClient } from "./humanitec.js";
import { exec as actionsExec } from "@actions/exec";
import { ResponseError } from "@humanitec/autogen";

// Emulate https://github.com/actions/toolkit/blob/819157bf8/packages/core/src/core.ts#L128
const setInputWithState = (state: string[], name: string, value: string): void => {
const envName = `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
const setInputWithState = (
state: string[],
name: string,
value: string,
): void => {
const envName = `INPUT_${name.replace(/ /g, "_").toUpperCase()}`;
process.env[envName] = value;

state.push(envName);
};

const clearInputs = (envNames: string[]) => {
for (const envName of envNames) {
process.env[envName] = '';
process.env[envName] = "";
}
};

const fixtures = pathJoin(__dirname, './fixtures');
const fixtures = pathJoin(__dirname, "./fixtures");

const ensureEnv = (name: string): string => {
const val = process.env[name];
Expand All @@ -31,14 +43,14 @@ const ensureEnv = (name: string): string => {
return val;
};

const token = ensureEnv('HUMANITEC_TOKEN');
const humanitecClient = createApiClient('api.humanitec.io', token);
const token = ensureEnv("HUMANITEC_TOKEN");
const humanitecClient = createApiClient("api.humanitec.io", token);

const orgId = ensureEnv('HUMANITEC_ORG');
const orgId = ensureEnv("HUMANITEC_ORG");

const tenMinInMs = 10 * 60 * 1000;

describe('action', () => {
describe("action", () => {
let repo: string;
let commit: string;

Expand All @@ -48,154 +60,162 @@ describe('action', () => {
};

afterAll(async () => {
const res = await humanitecClient.orgsOrgIdArtefactsGet({
const res = await humanitecClient.listArtefactVersionsInOrg({
orgId,
type: 'container',
type: "container",
});

// eslint-disable-next-line jest/no-standalone-expect
expect(res.status).toBe(200);

for (const artefact of res.data) {
for (const artefact of res) {
if (!artefact.name.startsWith(`registry.humanitec.io/${orgId}/test-`)) {
continue;
}

if (!artefact.created_at || Date.now() - Date.parse(artefact.created_at) < tenMinInMs) {
if (
!artefact.created_at ||
Date.now() - Date.parse(artefact.created_at) < tenMinInMs
) {
continue;
}
const res = await humanitecClient.orgsOrgIdArtefactsArtefactIdDelete({
orgId,
artefactId: artefact.id,
});

// Multiple tests might delete artifacts
// eslint-disable-next-line jest/no-standalone-expect
expect([204, 404]).toContain(res.status);

try {
await humanitecClient.deleteArtefact({
orgId,
artefactId: artefact.id,
});
} catch (err) {
if (err instanceof ResponseError) {
// Multiple tests might delete artifacts
if (err.response.status === 404) {
continue;
}
}
throw err;
}
}
});

beforeEach(async () => {
await mkdir(pathJoin(fixtures, '.git'), {recursive: true});
await mkdir(pathJoin(fixtures, ".git"), { recursive: true });

setInput('ref', '');
setInput('humanitec-token', token);
setInput('organization', orgId);
setInput('context', '.');
setInput("ref", "");
setInput("humanitec-token", token);
setInput("organization", orgId);
setInput("context", ".");

commit = randomBytes(20).toString('hex');
repo = `test-${randomBytes(20).toString('hex')}`;
commit = randomBytes(20).toString("hex");
repo = `test-${randomBytes(20).toString("hex")}`;

process.env['GITHUB_WORKSPACE'] = fixtures;
process.env['GITHUB_SHA'] = commit;
process.env['GITHUB_REPOSITORY'] = repo;
process.env["GITHUB_WORKSPACE"] = fixtures;
process.env["GITHUB_SHA"] = commit;
process.env["GITHUB_REPOSITORY"] = repo;
});

afterEach(() => {
process.exitCode = undefined;
clearInputs(inputs);
});

test('succeeds', async () => {
test("succeeds", async () => {
await runAction();
expect(process.exitCode).toBeFalsy();

const res = await humanitecClient.orgsOrgIdArtefactVersionsGet({orgId});
expect(res.status).toBe(200);
expect(res.data).toEqual(
expect.arrayContaining(
[
expect.objectContaining({
commit: commit,
name: `registry.humanitec.io/${orgId}/${repo}`,
}),
],
),
const res = await humanitecClient.listArtefactVersionsInOrg({ orgId });
expect(res).toEqual(
expect.arrayContaining([
expect.objectContaining({
commit: commit,
name: `registry.humanitec.io/${orgId}/${repo}`,
}),
]),
);
});

test('fails with an invalid ref', async () => {
setInput('ref', 'invalid');
test("fails with an invalid ref", async () => {
setInput("ref", "invalid");

await runAction();
expect(process.exitCode).toBeTruthy();
});

test('with slashed docker build args', async () => {
setInput('additional-docker-arguments', `
test("with slashed docker build args", async () => {
setInput(
"additional-docker-arguments",
`
--build-arg version=123 \\
--build-arg build_time=123 \\
--build-arg gitsha=132

`);
`,
);

await runAction();
expect(process.exitCode).toBeFalsy();

const res = await humanitecClient.orgsOrgIdArtefactVersionsGet({orgId});
expect(res.status).toBe(200);
expect(res.data).toEqual(
expect.arrayContaining(
[
expect.objectContaining({
commit: commit,
name: `registry.humanitec.io/${orgId}/${repo}`,
}),
],
),
const res = await humanitecClient.listArtefactVersionsInOrg({ orgId });
expect(res).toEqual(
expect.arrayContaining([
expect.objectContaining({
commit: commit,
name: `registry.humanitec.io/${orgId}/${repo}`,
}),
]),
);
});

test('supports an external registry', async () => {
repo = 'test-image';
process.env['GITHUB_REPOSITORY'] = repo;
test("supports an external registry", async () => {
repo = "test-image";
process.env["GITHUB_REPOSITORY"] = repo;

setInput('external-registry-url', 'ghcr.io/humanitec/build-push-to-humanitec');
setInput(
"external-registry-url",
"ghcr.io/humanitec/build-push-to-humanitec",
);

await runAction();
expect(process.exitCode).toBeFalsy();

const res = await humanitecClient.orgsOrgIdArtefactVersionsGet({orgId});
expect(res.status).toBe(200);
expect(res.data).toEqual(
expect.arrayContaining(
[
expect.objectContaining({
commit: commit,
name: `ghcr.io/humanitec/build-push-to-humanitec/${repo}`,
}),
],
),
const res = await humanitecClient.listArtefactVersionsInOrg({ orgId });
expect(res).toEqual(
expect.arrayContaining([
expect.objectContaining({
commit: commit,
name: `ghcr.io/humanitec/build-push-to-humanitec/${repo}`,
}),
]),
);
});

test('supports pushing an already existing image', async () => {
actionsExec('docker', ['pull', 'hello-world:latest']);
test("supports pushing an already existing image", async () => {
actionsExec("docker", ["pull", "hello-world:latest"]);

setInput('existing-image', 'hello-world:latest');
setInput("existing-image", "hello-world:latest");

await runAction();
expect(process.exitCode).toBeFalsy();

const res = await humanitecClient.orgsOrgIdArtefactVersionsGet({orgId});
expect(res.status).toBe(200);
expect(res.data).toEqual(
expect.arrayContaining(
[
expect.objectContaining({
commit: commit,
name: `registry.humanitec.io/${orgId}/${repo}`,
}),
],
),
const res = await humanitecClient.listArtefactVersionsInOrg({ orgId });
expect(res).toEqual(
expect.arrayContaining([
expect.objectContaining({
commit: commit,
name: `registry.humanitec.io/${orgId}/${repo}`,
}),
]),
);
});

test('fails when trying to specific an image on the same registry with a different tag', async () => {
actionsExec('docker', ['pull', 'hello-world:latest']);
actionsExec('docker', ['tag', 'hello-world:latest', `registry.humanitec.io/${orgId}/hello-world:latest`]);

setInput('existing-image', `registry.humanitec.io/${orgId}/hello-world:latest`);
test("fails when trying to specific an image on the same registry with a different tag", async () => {
actionsExec("docker", ["pull", "hello-world:latest"]);
actionsExec("docker", [
"tag",
"hello-world:latest",
`registry.humanitec.io/${orgId}/hello-world:latest`,
]);

setInput(
"existing-image",
`registry.humanitec.io/${orgId}/hello-world:latest`,
);

await runAction();
expect(process.exitCode).toBeTruthy();
Expand Down
Loading
Loading