diff --git a/.eslintrc.json b/.eslintrc.json index 48214c7..673e9eb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -62,7 +62,53 @@ "import/resolver": { "typescript": { "alwaysTryTypes": true // always try to resolve types under `@types` directory even it doesn't contain any source code, like `@types/unist` - } + }, + }, + "rules": { + "camelcase": "off", + "eslint-comments/no-use": "off", + "import/no-namespace": "off", + "no-shadow": "off", + "no-unused-vars": "off", + "prefer-template": "off", + "semi": [ "error", "never"], + "@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}], + "@typescript-eslint/array-type": "error", + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/ban-ts-comment": "error", + "@typescript-eslint/consistent-type-assertions": "error", + "@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}], + "@typescript-eslint/func-call-spacing": ["error", "never"], + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-require-imports": "error", + "@typescript-eslint/no-shadow": "error", + "@typescript-eslint/no-non-null-assertion": "warn", + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-unused-vars": ["error", {"varsIgnorePattern": "^_"}], + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/no-var-requires": "error", + "@typescript-eslint/prefer-for-of": "warn", + "@typescript-eslint/prefer-function-type": "warn", + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/prefer-string-starts-ends-with": "error", + "@typescript-eslint/promise-function-async": "error", + "@typescript-eslint/require-array-sort-compare": "error", + "@typescript-eslint/restrict-plus-operands": "error", + "@typescript-eslint/semi": ["error", "never"], + "@typescript-eslint/type-annotation-spacing": "error", + "@typescript-eslint/unbound-method": "error" + }, + "env": { + "node": true, + "es6": true, + "jest/globals": true } } } diff --git a/package.json b/package.json index bba8eea..9df1ffd 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@actions/github": "^6.0.0", "@slack/webhook": "^6.0.0", "adm-zip": "^0.5.10", + "bent": "^7.3.12", "fast-glob": "^3.3.2", "got": "^11.8.2", "picomatch": "^3.0.1", @@ -47,6 +48,7 @@ "@octokit/webhooks": "^12.0.10", "@octokit/webhooks-types": "^7.3.1", "@types/adm-zip": "^0.5.5", + "@types/bent": "^7.3.2", "@types/github-slugger": "^1.3.0", "@types/jest": "^29.5.11", "@types/node": "^20.10.4", diff --git a/src/input-providers/artifact-provider.ts b/src/input-providers/artifact-provider.ts index 740eb93..81f5c48 100644 --- a/src/input-providers/artifact-provider.ts +++ b/src/input-providers/artifact-provider.ts @@ -48,7 +48,9 @@ export class ArtifactProvider implements InputProvider { } async load(): Promise { - const result: ReportInput = {} + const result: ReportInput = { + artifactFilePaths: [] + } const resp = await this.octokit.rest.actions.listWorkflowRunArtifacts({ ...github.context.repo, @@ -57,17 +59,18 @@ export class ArtifactProvider implements InputProvider { if (resp.data.artifacts.length === 0) { core.warning(`No artifacts found in run ${this.runId}`) - return {} + return result } const artifacts = resp.data.artifacts.filter(a => this.artifactNameMatch(a.name)) if (artifacts.length === 0) { core.warning(`No artifact matches ${this.artifact}`) - return {} + return result } for (const art of artifacts) { const fileName = `${art.name}.zip` + result.artifactFilePaths.push(fileName) await downloadArtifact(this.octokit, art.id, fileName, this.token) core.startGroup(`Reading archive ${fileName}`) try { diff --git a/src/input-providers/input-provider.ts b/src/input-providers/input-provider.ts index 4fea986..919ae78 100644 --- a/src/input-providers/input-provider.ts +++ b/src/input-providers/input-provider.ts @@ -1,5 +1,6 @@ export interface ReportInput { - [reportName: string]: FileContent[] + artifactFilePaths: string[] + [reportName: string]: any[] } export interface FileContent { diff --git a/src/input-providers/local-file-provider.ts b/src/input-providers/local-file-provider.ts index e1afd8c..4d9446d 100644 --- a/src/input-providers/local-file-provider.ts +++ b/src/input-providers/local-file-provider.ts @@ -19,7 +19,7 @@ export class LocalFileProvider implements InputProvider { } } - return {[this.name]: result} + return {[this.name]: result, artifactFilePaths: []} } async listTrackedFiles(): Promise { diff --git a/src/main.ts b/src/main.ts index 9d8df9a..9927fb0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -20,6 +20,9 @@ import {SwiftXunitParser} from './parsers/swift-xunit/swift-xunit-parser' import {normalizeDirPath, normalizeFilePath} from './utils/path-utils' import {getCheckRunContext} from './utils/github-utils' import {IncomingWebhook} from '@slack/webhook' +import fs from 'fs' +//import fetch from 'node-fetch' +import bent from 'bent' async function main(): Promise { try { @@ -46,6 +49,8 @@ class TestReporter { readonly onlySummary = core.getInput('only-summary', {required: false}) === 'true' readonly token = core.getInput('token', {required: true}) readonly slackWebhook = core.getInput('slack-url', {required: false}) + readonly resultsEndpoint = core.getInput('test-results-endpoint', {required: true}) + readonly resultsEndpointSecret = core.getInput('test-results-endpoint-secret', {required: true}) readonly octokit: InstanceType readonly context = getCheckRunContext() @@ -110,6 +115,21 @@ class TestReporter { const results: TestRunResult[] = [] const input = await inputProvider.load() + + for (const a of input.artifactFilePaths) { + const stats = fs.statSync(a) + const fileSizeInBytes = stats.size + const readStream = fs.createReadStream(a) + + try { + const post = bent(this.resultsEndpoint, 'POST', null, 200); + await post(`TestResults?Secret=${this.resultsEndpointSecret}`, readStream); + core.info(`Uploaded TRX files: ${a}`) + } catch (ex){ + core.warning(`Could not upload file ${a}: ${ex}`) + } + } + for (const [reportName, files] of Object.entries(input)) { try { core.startGroup(`Creating test report ${reportName}`)