Skip to content
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
2 changes: 1 addition & 1 deletion .github/actions/reports-group/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PKG_LIST := node-sdk find load-metadata create codecov-uploader codacy-uploader
PKG_LIST := node-sdk find load-metadata create codecov-uploader codacy-uploader attach-check-run-to-triggering-workflow-action
TARGETS := configure install build package lint test

define FOR_EACH_PKG
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/** -diff linguist-generated=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.yarn
node_modules
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.PHONY: install
install:
yarn install

.PHONY: build
build: install package

.PHONY: package
package:
rm -Rf dist/* && ./node_modules/.bin/ncc build index.js --minify --source-map --license LICENSE --out dist

.PHONY: lint
lint:
./node_modules/.bin/eslint index.js

.PHONY: test
test:
echo "Error: no test specified"
exit 1

get-action-nodejs-version: ## Display node version configured on action.yml
@grep -E "using:\s*'?node" action.yml | sed -e "s/^.*using: '*node\([0-9][0-9]\)'*.*$$/\1/"
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: TODO
description: TODO
inputs:
name:
description: Status check name
required: true
github-token:
description: Github Authentication token used to create the check through GitHub API
required: true
job-status:
description: Job check status
required: true

outputs:
check-run-id:
description: Related check run id

runs:
using: 'node20'
main: 'dist/index.js'
post: 'dist/index.js'

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const core = require("@actions/core"); // @TODO move to 'imports from' when moved to TS !

if (!!core.getState('check-run-id')) {
require('./src/cleanup');
} else {
require('./src/main');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "attach-check-run-to-triggering-workflow-action",
"private": true,
"version": "0.0.0",
"author": "yoanm",
"main": "dist/index.js",
"license": "MIT",
"scripts": {
"build": "make build"
},
"dependencies": {
"@actions/core": "^1.10.1",
"@actions/github": "^6.0.0"
},
"devDependencies": {
"@vercel/ncc": "^0.38.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const github = require('@actions/github'); // @TODO move to 'imports from' when moved to TS !
const core = require('@actions/core');

const {GITHUB_REPOSITORY} = process.env;

async function run() {
if (core.getState('check-run-already-concluded').length > 0) {
core.info('Check run already concluded, skipping check run update');
}
const checkRunId = core.getState('check-run-id');
if (checkRunId.length === 0) {
throw new Error('Unable to retrieve check run id !');
}

/** INPUTS **/
const jobStatus = core.getInput('job-status', {required: true});
const githubToken = core.getInput('github-token', {required: true});

const requestParams = await core.group(
'Build API params',
async () => {
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');

return {
conclusion: jobStatus,
// Url path parameters
owner: repoOwner,
repo: repoName,
check_run_id: checkRunId
};
}
);
core.debug('API params=' + JSON.stringify(requestParams));

const apiResponse = await core.group('Conclude check-run ', async () => {
const octokit = github.getOctokit(githubToken);

// @TODO Move back to `octokit.rest.checks.update()`
return octokit.request('PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}', requestParams);
});
core.debug('API call to ' +apiResponse.url + ' => HTTP ' + apiResponse.status);
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
const github = require('@actions/github'); // @TODO move to 'imports from' when moved to TS !
const core = require('@actions/core');

const {GITHUB_REPOSITORY} = process.env;

/**
* @returns {number|undefined}
*/
function guessPrNumber() {
if ('pull_request' === github.context.eventName) {
return github.context.payload.number
}
if ('workflow_run' === github.context.eventName) {
return 'pull_request' === github.context.payload.workflow_run.event
? github.context.payload.pull_requests[0]?.number
: undefined
;
}

return undefined;
}

/**
* @returns {string|undefined}
*/
function guessCommitSha() {
if ('pull_request' === github.context.eventName) {
return github.context.payload.pull_request.head.sha;
}
if ('push' === github.context.eventName) {
return github.context.payload.after;
}
if ('workflow_run' === github.context.eventName && ['pull_request', 'push'].includes(github.context.payload.workflow_run.event)) {
return github.context.payload.workflow_run.head_sha;
}

throw new Error('Unable to guess the commit SHA !');
}

/**
* @returns {string}
*/
function guessTriggeringWorkflowName() {
if ('workflow_run' === github.context.eventName) {
return github.context.payload.workflow.name;
}

return github.context.workflow;
}

/**
* @returns {string}
*/
function guessRunId() {
if ('workflow_run' === github.context.eventName) {
return github.context.payload.id.toString();
}

return github.context.runId.toString();
}

async function getWorkflowJobsForRunId(octokit, owner, repo, runId) {
return octokit.paginate(
'GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs',
{
//filter: 'latest',
// Url path parameters
owner: owner,
repo: repo,
run_id: runId
}
);
}

async function run() {
/** INPUTS **/
const checkName = core.getInput('name', {required: true});
const githubToken = core.getInput('github-token', {required: true});
const jobStatus = core.getInput('job-status', {required: true});

const isSuccessfulJobAsOfNow = 'success' === jobStatus;
const octokit = github.getOctokit(githubToken);

const requestParams = await core.group(
'Build API params',
async () => {
const repoInfo = github.context.repo;
const triggeringWorkflowRunId = guessRunId();
//core.info('TMP DEBUG context=' + JSON.stringify(github.context));
//const jobsForCurrentWorkflow = await getWorkflowJobsForRunId(octokit, repoInfo.owner, repoInfo.repo, github.context.runId);
//core.info('TMP DEBUG jobsForCurrentWorkflow=' + JSON.stringify(jobsForCurrentWorkflow.map(v => {v.steps = '-_-'; return v;})));
//const jobsForTriggeringWorkflow = await getWorkflowJobsForRunId(octokit, repoInfo.owner, repoInfo.repo, triggeringWorkflowRunId);
//core.info('TMP DEBUG jobsForTriggeringWorkflow=' + JSON.stringify(jobsForTriggeringWorkflow.map(v => {v.steps = '-_-'; return v;})));
//core.info('TMP DEBUG job name=' + process.env.GITHUB_JOB);
const commitSha = guessCommitSha();
const startedAt = (new Date()).toISOString();
const prNumber = guessPrNumber();
const originalWorkflowName = guessTriggeringWorkflowName();
const outputTitle = '🔔 ' + github.context.workflow; // Current workflow name !
const originalWorkflowUrl = github.context.serverUrl + '/' + GITHUB_REPOSITORY + '/actions/runs/' + triggeringWorkflowRunId + (undefined !== prNumber ? '?pr=' + prNumber : '');
const outputSummary = '🪢 Triggered by <a href="' + originalWorkflowUrl + '" target="blank">**' + originalWorkflowName + '** workflow</a>';

return {
name: checkName,
head_sha: commitSha,
//details_url: detailsUrl,
external_id: triggeringWorkflowRunId?.toString(),
status: isSuccessfulJobAsOfNow ? 'in_progress' : 'completed',
output: {
title: outputTitle,
summary: outputSummary,
},
// Conclusion
conclusion: isSuccessfulJobAsOfNow ? undefined : jobStatus,
started_at: startedAt,
completed_at: isSuccessfulJobAsOfNow ? undefined : startedAt,
// Url path parameters
owner: repoInfo.owner,
repo: repoInfo.repo
};
}
);
core.debug('API params=' + JSON.stringify(requestParams));

const apiResponse = await core.group('Create check-run', async () => {
// @TODO Move back to `octokit.rest.checks.create()`
return octokit.request('POST /repos/{owner}/{repo}/check-runs', requestParams);
});
core.debug('API call to ' +apiResponse.url + ' => HTTP ' + apiResponse.status);

core.setOutput('check-run-id', apiResponse.data.id);
core.saveState('check-run-id', apiResponse.data.id); // In order to use it during POST hook
if (true === isSuccessfulJobAsOfNow) {
core.saveState('check-run-already-concluded', 'yes'); // In order to use it during POST hook
}
}

run();
Loading