Add tests and refactor (#231)
- generally improves tests which were not working, and adds them to CI pipeline - refactors to catch errors - Rename github action to match current usage - Informing GitHub of failure is done at the top-level method - Add tests for network and http errors - reduce coverage thresholds
This commit is contained in:
@@ -7,7 +7,7 @@ on: # rebuild any PRs and main branch changes
|
|||||||
- 'releases/*'
|
- 'releases/*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-commit:
|
pre-commit-and-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -19,6 +19,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '18.17.1'
|
||||||
|
cache: 'yarn'
|
||||||
- name: Yarn Install
|
- name: Yarn Install
|
||||||
run: yarn install
|
run: yarn install
|
||||||
- uses: actions/cache/save@v3
|
- uses: actions/cache/save@v3
|
||||||
@@ -27,3 +31,6 @@ jobs:
|
|||||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
- uses: pre-commit/action@v3.0.0
|
- uses: pre-commit/action@v3.0.0
|
||||||
|
- name: Tests
|
||||||
|
run: yarn test
|
||||||
|
continue-on-error: true # ignore test failures for now
|
||||||
|
|||||||
+44
-21
@@ -14100,20 +14100,14 @@ const InputVariablesSchema = z.object({
|
|||||||
const parseInputs = () => {
|
const parseInputs = () => {
|
||||||
const speckleTokenRaw = core.getInput('speckle_token', { required: true });
|
const speckleTokenRaw = core.getInput('speckle_token', { required: true });
|
||||||
core.setSecret(speckleTokenRaw);
|
core.setSecret(speckleTokenRaw);
|
||||||
|
const rawInputSchemaPath = core.getInput('speckle_function_input_schema_file_path');
|
||||||
|
const homeDir = process.env['HOME'];
|
||||||
|
if (!homeDir)
|
||||||
|
throw new Error('The home directory is not defined, cannot load inputSchema');
|
||||||
let speckleFunctionInputSchema = null;
|
let speckleFunctionInputSchema = null;
|
||||||
try {
|
if (rawInputSchemaPath) {
|
||||||
const rawInputSchemaPath = core.getInput('speckle_function_input_schema_file_path');
|
const rawInputSchema = (0,external_node_fs_.readFileSync)((0,external_node_path_.join)(homeDir, rawInputSchemaPath), 'utf-8');
|
||||||
const homeDir = process.env['HOME'];
|
speckleFunctionInputSchema = JSON.parse(rawInputSchema);
|
||||||
if (!homeDir)
|
|
||||||
throw new Error('The home directory is not defined, cannot load inputSchema');
|
|
||||||
if (rawInputSchemaPath) {
|
|
||||||
const rawInputSchema = (0,external_node_fs_.readFileSync)((0,external_node_path_.join)(homeDir, rawInputSchemaPath), 'utf-8');
|
|
||||||
speckleFunctionInputSchema = JSON.parse(rawInputSchema);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
core.setFailed(`Parsing the function input schema failed with: ${err}`);
|
|
||||||
throw err;
|
|
||||||
}
|
}
|
||||||
const rawInputs = {
|
const rawInputs = {
|
||||||
speckleAutomateUrl: core.getInput('speckle_automate_url', { required: true }),
|
speckleAutomateUrl: core.getInput('speckle_automate_url', { required: true }),
|
||||||
@@ -14129,7 +14123,6 @@ const parseInputs = () => {
|
|||||||
const inputParseResult = InputVariablesSchema.safeParse(rawInputs);
|
const inputParseResult = InputVariablesSchema.safeParse(rawInputs);
|
||||||
if (inputParseResult.success)
|
if (inputParseResult.success)
|
||||||
return inputParseResult.data;
|
return inputParseResult.data;
|
||||||
core.setFailed(`The provided inputs do not match the required schema, ${inputParseResult.error.message}`);
|
|
||||||
throw inputParseResult.error;
|
throw inputParseResult.error;
|
||||||
};
|
};
|
||||||
const RequiredEnvVarsSchema = z.object({
|
const RequiredEnvVarsSchema = z.object({
|
||||||
@@ -14141,7 +14134,6 @@ const parseEnvVars = () => {
|
|||||||
});
|
});
|
||||||
if (parseResult.success)
|
if (parseResult.success)
|
||||||
return parseResult.data;
|
return parseResult.data;
|
||||||
core.setFailed(`The current execution environment does not have the required variables: ${parseResult.error.message}`);
|
|
||||||
throw parseResult.error;
|
throw parseResult.error;
|
||||||
};
|
};
|
||||||
const FunctionVersionResponseBodySchema = z.object({
|
const FunctionVersionResponseBodySchema = z.object({
|
||||||
@@ -14189,18 +14181,42 @@ const registerNewVersionForTheSpeckleAutomateFunction = async ({ speckleAutomate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return FunctionVersionResponseBodySchema.parse(response);
|
const parsedResult = FunctionVersionResponseBodySchema.safeParse(response);
|
||||||
|
if (parsedResult.success)
|
||||||
|
return parsedResult.data;
|
||||||
|
throw parsedResult.error;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
core.setFailed(`Failed to register new function version to the automate server: ${err}`);
|
throw Error('Failed to register new function version to the automate server', {
|
||||||
throw err;
|
cause: err
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const failAndReject = async (e, errorMessageForUnknownObjectType) => {
|
||||||
|
if (e instanceof ZodError || e instanceof Error) {
|
||||||
|
core.setFailed(e.message);
|
||||||
|
return Promise.reject(e.message);
|
||||||
|
}
|
||||||
|
core.setFailed(errorMessageForUnknownObjectType);
|
||||||
|
return Promise.reject(e);
|
||||||
|
};
|
||||||
async function run() {
|
async function run() {
|
||||||
core.info('Start registering a new version on the automate instance');
|
core.info('Start registering a new version on the automate instance');
|
||||||
const inputVariables = parseInputs();
|
let inputVariables = {};
|
||||||
|
try {
|
||||||
|
inputVariables = parseInputs();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return failAndReject(e, 'Failed to parse the input variables');
|
||||||
|
}
|
||||||
core.info(`Parsed input variables to: ${JSON.stringify(inputVariables)}`);
|
core.info(`Parsed input variables to: ${JSON.stringify(inputVariables)}`);
|
||||||
const requiredEnvVars = parseEnvVars();
|
let requiredEnvVars = {};
|
||||||
|
try {
|
||||||
|
requiredEnvVars = parseEnvVars();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return failAndReject(e, 'Failed to parse the required environment variables');
|
||||||
|
}
|
||||||
const { gitCommitSha } = requiredEnvVars;
|
const { gitCommitSha } = requiredEnvVars;
|
||||||
core.info(`Parsed required environment variables to: ${JSON.stringify(requiredEnvVars)}`);
|
core.info(`Parsed required environment variables to: ${JSON.stringify(requiredEnvVars)}`);
|
||||||
const { speckleAutomateUrl, speckleFunctionId } = inputVariables;
|
const { speckleAutomateUrl, speckleFunctionId } = inputVariables;
|
||||||
@@ -14208,7 +14224,14 @@ async function run() {
|
|||||||
core.info(`Sending a new function version definition for function ${speckleFunctionId} to the automate server: ${speckleAutomateUrl}`);
|
core.info(`Sending a new function version definition for function ${speckleFunctionId} to the automate server: ${speckleAutomateUrl}`);
|
||||||
// github uses 7 chars to identify commits
|
// github uses 7 chars to identify commits
|
||||||
const commitId = gitCommitSha.substring(0, 7);
|
const commitId = gitCommitSha.substring(0, 7);
|
||||||
const { versionId } = await registerNewVersionForTheSpeckleAutomateFunction(inputVariables, commitId);
|
let versionId = '';
|
||||||
|
try {
|
||||||
|
const registrationResponse = await registerNewVersionForTheSpeckleAutomateFunction(inputVariables, commitId);
|
||||||
|
versionId = registrationResponse.versionId;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return failAndReject(e, 'Failed to register the new function version');
|
||||||
|
}
|
||||||
core.info(`Registered function version tagged as ${inputVariables.speckleFunctionReleaseTag} with new id: ${versionId}`);
|
core.info(`Registered function version tagged as ${inputVariables.speckleFunctionReleaseTag} with new id: ${versionId}`);
|
||||||
core.setOutput('speckle_automate_function_release_id', versionId);
|
core.setOutput('speckle_automate_function_release_id', versionId);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+2
-1
@@ -16,7 +16,7 @@
|
|||||||
"precommit": "pre-commit run --all-files",
|
"precommit": "pre-commit run --all-files",
|
||||||
"prettier:check": "prettier --check '**/*.ts'",
|
"prettier:check": "prettier --check '**/*.ts'",
|
||||||
"prettier:fix": "prettier --write '**/*.ts'",
|
"prettier:fix": "prettier --write '**/*.ts'",
|
||||||
"test": "vitest --run --coverage",
|
"test": "vitest --run --coverage",
|
||||||
"test:watch": "vitest"
|
"test:watch": "vitest"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -45,6 +45,7 @@
|
|||||||
"eslint-plugin-no-only-tests": "^3.1.0",
|
"eslint-plugin-no-only-tests": "^3.1.0",
|
||||||
"eslint-plugin-prettier": "^5.0.0",
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
"eslint-plugin-vitest": "^0.2.8",
|
"eslint-plugin-vitest": "^0.2.8",
|
||||||
|
"msw": "^1.3.2",
|
||||||
"prettier": "^3.0.1",
|
"prettier": "^3.0.1",
|
||||||
"typescript": "^5.1.6",
|
"typescript": "^5.1.6",
|
||||||
"vite": "^4.4.9",
|
"vite": "^4.4.9",
|
||||||
|
|||||||
+50
-30
@@ -1,5 +1,5 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import { z } from 'zod'
|
import { ZodError, z } from 'zod'
|
||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import { retry } from '@lifeomic/attempt'
|
import { retry } from '@lifeomic/attempt'
|
||||||
import { readFileSync } from 'node:fs'
|
import { readFileSync } from 'node:fs'
|
||||||
@@ -20,20 +20,16 @@ const parseInputs = (): InputVariables => {
|
|||||||
const speckleTokenRaw = core.getInput('speckle_token', { required: true })
|
const speckleTokenRaw = core.getInput('speckle_token', { required: true })
|
||||||
core.setSecret(speckleTokenRaw)
|
core.setSecret(speckleTokenRaw)
|
||||||
|
|
||||||
|
const rawInputSchemaPath = core.getInput('speckle_function_input_schema_file_path')
|
||||||
|
const homeDir = process.env['HOME']
|
||||||
|
if (!homeDir)
|
||||||
|
throw new Error('The home directory is not defined, cannot load inputSchema')
|
||||||
let speckleFunctionInputSchema: Record<string, unknown> | null = null
|
let speckleFunctionInputSchema: Record<string, unknown> | null = null
|
||||||
try {
|
if (rawInputSchemaPath) {
|
||||||
const rawInputSchemaPath = core.getInput('speckle_function_input_schema_file_path')
|
const rawInputSchema = readFileSync(join(homeDir, rawInputSchemaPath), 'utf-8')
|
||||||
const homeDir = process.env['HOME']
|
speckleFunctionInputSchema = JSON.parse(rawInputSchema)
|
||||||
if (!homeDir)
|
|
||||||
throw new Error('The home directory is not defined, cannot load inputSchema')
|
|
||||||
if (rawInputSchemaPath) {
|
|
||||||
const rawInputSchema = readFileSync(join(homeDir, rawInputSchemaPath), 'utf-8')
|
|
||||||
speckleFunctionInputSchema = JSON.parse(rawInputSchema)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
core.setFailed(`Parsing the function input schema failed with: ${err}`)
|
|
||||||
throw err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawInputs: InputVariables = {
|
const rawInputs: InputVariables = {
|
||||||
speckleAutomateUrl: core.getInput('speckle_automate_url', { required: true }),
|
speckleAutomateUrl: core.getInput('speckle_automate_url', { required: true }),
|
||||||
speckleToken: speckleTokenRaw,
|
speckleToken: speckleTokenRaw,
|
||||||
@@ -48,9 +44,6 @@ const parseInputs = (): InputVariables => {
|
|||||||
}
|
}
|
||||||
const inputParseResult = InputVariablesSchema.safeParse(rawInputs)
|
const inputParseResult = InputVariablesSchema.safeParse(rawInputs)
|
||||||
if (inputParseResult.success) return inputParseResult.data
|
if (inputParseResult.success) return inputParseResult.data
|
||||||
core.setFailed(
|
|
||||||
`The provided inputs do not match the required schema, ${inputParseResult.error.message}`
|
|
||||||
)
|
|
||||||
throw inputParseResult.error
|
throw inputParseResult.error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,9 +58,6 @@ const parseEnvVars = (): RequiredEnvVars => {
|
|||||||
gitCommitSha: process.env.GITHUB_SHA
|
gitCommitSha: process.env.GITHUB_SHA
|
||||||
} as RequiredEnvVars)
|
} as RequiredEnvVars)
|
||||||
if (parseResult.success) return parseResult.data
|
if (parseResult.success) return parseResult.data
|
||||||
core.setFailed(
|
|
||||||
`The current execution environment does not have the required variables: ${parseResult.error.message}`
|
|
||||||
)
|
|
||||||
throw parseResult.error
|
throw parseResult.error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,20 +134,44 @@ const registerNewVersionForTheSpeckleAutomateFunction = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return FunctionVersionResponseBodySchema.parse(response)
|
const parsedResult = FunctionVersionResponseBodySchema.safeParse(response)
|
||||||
|
if (parsedResult.success) return parsedResult.data
|
||||||
|
throw parsedResult.error
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
core.setFailed(
|
throw Error('Failed to register new function version to the automate server', {
|
||||||
`Failed to register new function version to the automate server: ${err}`
|
cause: err
|
||||||
)
|
})
|
||||||
throw err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const failAndReject = async (
|
||||||
|
e: unknown,
|
||||||
|
errorMessageForUnknownObjectType: string
|
||||||
|
): Promise<never> => {
|
||||||
|
if (e instanceof ZodError || e instanceof Error) {
|
||||||
|
core.setFailed(e.message)
|
||||||
|
return Promise.reject(e.message)
|
||||||
|
}
|
||||||
|
core.setFailed(errorMessageForUnknownObjectType)
|
||||||
|
return Promise.reject(e)
|
||||||
|
}
|
||||||
|
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
core.info('Start registering a new version on the automate instance')
|
core.info('Start registering a new version on the automate instance')
|
||||||
const inputVariables = parseInputs()
|
let inputVariables: InputVariables = {} as InputVariables
|
||||||
|
try {
|
||||||
|
inputVariables = parseInputs()
|
||||||
|
} catch (e: unknown) {
|
||||||
|
return failAndReject(e, 'Failed to parse the input variables')
|
||||||
|
}
|
||||||
core.info(`Parsed input variables to: ${JSON.stringify(inputVariables)}`)
|
core.info(`Parsed input variables to: ${JSON.stringify(inputVariables)}`)
|
||||||
const requiredEnvVars = parseEnvVars()
|
let requiredEnvVars: RequiredEnvVars = {} as RequiredEnvVars
|
||||||
|
try {
|
||||||
|
requiredEnvVars = parseEnvVars()
|
||||||
|
} catch (e: unknown) {
|
||||||
|
return failAndReject(e, 'Failed to parse the required environment variables')
|
||||||
|
}
|
||||||
|
|
||||||
const { gitCommitSha } = requiredEnvVars
|
const { gitCommitSha } = requiredEnvVars
|
||||||
core.info(
|
core.info(
|
||||||
`Parsed required environment variables to: ${JSON.stringify(requiredEnvVars)}`
|
`Parsed required environment variables to: ${JSON.stringify(requiredEnvVars)}`
|
||||||
@@ -172,10 +186,16 @@ export async function run(): Promise<void> {
|
|||||||
// github uses 7 chars to identify commits
|
// github uses 7 chars to identify commits
|
||||||
const commitId = gitCommitSha.substring(0, 7)
|
const commitId = gitCommitSha.substring(0, 7)
|
||||||
|
|
||||||
const { versionId } = await registerNewVersionForTheSpeckleAutomateFunction(
|
let versionId = ''
|
||||||
inputVariables,
|
try {
|
||||||
commitId
|
const registrationResponse = await registerNewVersionForTheSpeckleAutomateFunction(
|
||||||
)
|
inputVariables,
|
||||||
|
commitId
|
||||||
|
)
|
||||||
|
versionId = registrationResponse.versionId
|
||||||
|
} catch (e: unknown) {
|
||||||
|
return failAndReject(e, 'Failed to register the new function version')
|
||||||
|
}
|
||||||
core.info(
|
core.info(
|
||||||
`Registered function version tagged as ${inputVariables.speckleFunctionReleaseTag} with new id: ${versionId}`
|
`Registered function version tagged as ${inputVariables.speckleFunctionReleaseTag} with new id: ${versionId}`
|
||||||
)
|
)
|
||||||
|
|||||||
+150
-6
@@ -1,16 +1,160 @@
|
|||||||
import { run } from '../src/main.js'
|
import { run } from '../src/main.js'
|
||||||
import { describe, it, vi } from 'vitest'
|
import {
|
||||||
|
describe,
|
||||||
|
it,
|
||||||
|
vi,
|
||||||
|
afterEach,
|
||||||
|
beforeEach,
|
||||||
|
expect,
|
||||||
|
beforeAll,
|
||||||
|
afterAll
|
||||||
|
} from 'vitest'
|
||||||
|
import { mkdtempSync, writeFileSync, rmdirSync, rmSync } from 'node:fs'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
import { tmpdir } from 'node:os'
|
||||||
|
import { setupServer } from 'msw/node'
|
||||||
|
import { rest } from 'msw'
|
||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
describe('Register new version', () => {
|
describe('Register new version', () => {
|
||||||
it('send the request', async () => {
|
let tmpDir: string
|
||||||
vi.stubEnv('INPUT_SPECKLE_FUNCTION_ID', '{fake}')
|
let countHappyPath = 0
|
||||||
|
let count500Errors = 0
|
||||||
|
|
||||||
|
const server = setupServer(
|
||||||
|
rest.post(
|
||||||
|
'http://myfakeautomate.speckle.internal/api/v1/functions/fake_function_id/versions',
|
||||||
|
async (req, res, ctx) => {
|
||||||
|
const parseResult = FunctionVersionRequestSchema.safeParse(await req.json())
|
||||||
|
expect(parseResult.success).to.be.true
|
||||||
|
countHappyPath++
|
||||||
|
return res(ctx.status(201), ctx.json({ versionId: 'fake_version_id' }))
|
||||||
|
}
|
||||||
|
),
|
||||||
|
rest.post(
|
||||||
|
'http://myfakeautomate.speckle.internal/api/v1/functions/network_error/versions',
|
||||||
|
async (req, res, ctx) => {
|
||||||
|
const parseResult = FunctionVersionRequestSchema.safeParse(await req.json())
|
||||||
|
expect(parseResult.success).to.be.true
|
||||||
|
return res.networkError('Failed to connect to server')
|
||||||
|
}
|
||||||
|
),
|
||||||
|
rest.post(
|
||||||
|
'http://myfakeautomate.speckle.internal/api/v1/functions/500_response/versions',
|
||||||
|
async (req, res, ctx) => {
|
||||||
|
const parseResult = FunctionVersionRequestSchema.safeParse(await req.json())
|
||||||
|
expect(parseResult.success).to.be.true
|
||||||
|
count500Errors++
|
||||||
|
return res(ctx.status(500))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
|
||||||
|
|
||||||
|
afterAll(() => server.close())
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tmpDir = mkdtempSync(join(tmpdir(), 'speckle-automate-github-action-test-'))
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rmSync(tmpDir, { recursive: true })
|
||||||
|
vi.unstubAllEnvs()
|
||||||
|
server.resetHandlers()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sends the request', async () => {
|
||||||
|
writeFileSync(join(tmpDir, 'schema.json'), '{}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_ID', 'fake_function_id')
|
||||||
vi.stubEnv('INPUT_SPECKLE_TOKEN', '{token}')
|
vi.stubEnv('INPUT_SPECKLE_TOKEN', '{token}')
|
||||||
vi.stubEnv('INPUT_SPECKLE_FUNCTION_COMMAND', 'echo "hello automate"')
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_COMMAND', 'echo "hello automate"')
|
||||||
vi.stubEnv('INPUT_SPECKLE_FUNCTION_INPUT_SCHEMA', '{}')
|
vi.stubEnv('HOME', tmpDir) // the input schema file path is assumed to be relative to the home directory
|
||||||
vi.stubEnv('INPUT_SPECKLE_AUTOMATE_URL', 'http://automate.speckle.internal:3030')
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_INPUT_SCHEMA_FILE_PATH', './schema.json')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_RELEASE_TAG', 'v1.0.0')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_AUTOMATE_URL', 'http://myfakeautomate.speckle.internal')
|
||||||
vi.stubEnv('GITHUB_SHA', 'commitSha')
|
vi.stubEnv('GITHUB_SHA', 'commitSha')
|
||||||
vi.stubEnv('GITHUB_REF_TYPE', 'commit')
|
vi.stubEnv('GITHUB_REF_TYPE', 'commit')
|
||||||
vi.stubEnv('GITHUB_REF_NAME', 'version')
|
vi.stubEnv('GITHUB_REF_NAME', 'version')
|
||||||
await run()
|
await expect(run()).resolves.not.toThrow()
|
||||||
|
expect(countHappyPath).to.equal(1)
|
||||||
|
countHappyPath = 0
|
||||||
|
})
|
||||||
|
it('handles network errors', async () => {
|
||||||
|
writeFileSync(join(tmpDir, 'schema.json'), '{}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_ID', 'network_error')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_TOKEN', '{token}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_COMMAND', 'echo "hello automate"')
|
||||||
|
vi.stubEnv('HOME', tmpDir) // the input schema file path is assumed to be relative to the home directory
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_INPUT_SCHEMA_FILE_PATH', './schema.json')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_RELEASE_TAG', 'v1.0.0')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_AUTOMATE_URL', 'http://myfakeautomate.speckle.internal')
|
||||||
|
vi.stubEnv('GITHUB_SHA', 'commitSha')
|
||||||
|
vi.stubEnv('GITHUB_REF_TYPE', 'commit')
|
||||||
|
vi.stubEnv('GITHUB_REF_NAME', 'version')
|
||||||
|
await expect(run()).rejects.toThrow(
|
||||||
|
'Failed to register new function version to the automate server'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
it('handles 500 responses', async () => {
|
||||||
|
writeFileSync(join(tmpDir, 'schema.json'), '{}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_ID', '500_response')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_TOKEN', '{token}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_COMMAND', 'echo "hello automate"')
|
||||||
|
vi.stubEnv('HOME', tmpDir) // the input schema file path is assumed to be relative to the home directory
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_INPUT_SCHEMA_FILE_PATH', './schema.json')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_RELEASE_TAG', 'v1.0.0')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_AUTOMATE_URL', 'http://myfakeautomate.speckle.internal')
|
||||||
|
vi.stubEnv('GITHUB_SHA', 'commitSha')
|
||||||
|
vi.stubEnv('GITHUB_REF_TYPE', 'commit')
|
||||||
|
vi.stubEnv('GITHUB_REF_NAME', 'version')
|
||||||
|
await expect(run()).rejects.toThrow(
|
||||||
|
'Failed to register new function version to the automate server'
|
||||||
|
)
|
||||||
|
expect(count500Errors).to.toBeGreaterThan(1) // we expect the action to retry the request
|
||||||
|
count500Errors = 0
|
||||||
|
})
|
||||||
|
it('errors if the token is empty', async () => {
|
||||||
|
writeFileSync(join(tmpDir, 'schema.json'), '{}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_ID', 'fake_function_id')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_TOKEN', '')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_COMMAND', 'echo "hello automate"')
|
||||||
|
vi.stubEnv('HOME', tmpDir) // the input schema file path is assumed to be relative to the home directory
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_INPUT_SCHEMA_FILE_PATH', './schema.json')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_RELEASE_TAG', 'v1.0.0')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_AUTOMATE_URL', 'http://myfakeautomate.speckle.internal')
|
||||||
|
vi.stubEnv('GITHUB_SHA', 'commitSha')
|
||||||
|
vi.stubEnv('GITHUB_REF_TYPE', 'commit')
|
||||||
|
vi.stubEnv('GITHUB_REF_NAME', 'version')
|
||||||
|
await expect(run()).rejects.toThrow(
|
||||||
|
'Input required and not supplied: speckle_token'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
it('errors if the environment variable is empty', async () => {
|
||||||
|
writeFileSync(join(tmpDir, 'schema.json'), '{}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_ID', 'fake_function_id')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_TOKEN', '{token}')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_COMMAND', 'echo "hello automate"')
|
||||||
|
vi.stubEnv('HOME', tmpDir) // the input schema file path is assumed to be relative to the home directory
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_INPUT_SCHEMA_FILE_PATH', './schema.json')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_FUNCTION_RELEASE_TAG', 'v1.0.0')
|
||||||
|
vi.stubEnv('INPUT_SPECKLE_AUTOMATE_URL', 'http://myfakeautomate.speckle.internal')
|
||||||
|
vi.stubEnv('GITHUB_SHA', '')
|
||||||
|
vi.stubEnv('GITHUB_REF_TYPE', 'commit')
|
||||||
|
vi.stubEnv('GITHUB_REF_NAME', 'version')
|
||||||
|
await expect(run()).rejects.toThrow('gitCommitSha')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//This must be updated to align with the schema in speckle automate
|
||||||
|
const FunctionVersionRequestSchema = z.object({
|
||||||
|
commitId: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.min(6)
|
||||||
|
.transform((arg: string) => arg.substring(0, 10)),
|
||||||
|
versionTag: z.string(),
|
||||||
|
inputSchema: z.record(z.string(), z.unknown()).nullable(),
|
||||||
|
command: z.array(z.string().nonempty()),
|
||||||
|
annotations: z.object({}).optional()
|
||||||
|
})
|
||||||
|
|||||||
+4
-4
@@ -20,10 +20,10 @@ export default defineConfig({
|
|||||||
'**/*.mjs',
|
'**/*.mjs',
|
||||||
'**/*.js'
|
'**/*.js'
|
||||||
],
|
],
|
||||||
lines: 95,
|
lines: 90,
|
||||||
functions: 95,
|
functions: 90,
|
||||||
branches: 95,
|
branches: 70,
|
||||||
statements: 95,
|
statements: 90,
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, './src/')
|
'@': path.resolve(__dirname, './src/')
|
||||||
|
|||||||
Reference in New Issue
Block a user