1+ name : Add check & status
2+ description : " Sets a commit/issue status on the given (or auto-detected) SHA."
3+
4+ inputs :
5+ checkState :
6+ description : " Check state: error, failure, pending, or success"
7+ default : success
8+ checkName :
9+ description : " Status-line “context” label (appears in the PR UI)"
10+ default : custom/check
11+ checkDescription :
12+ description : " Short description that shows next to the status"
13+ default : ' '
14+ sha :
15+ description : " Commit SHA to attach the status to (auto-detected if empty)"
16+ required : false
17+
18+ runs :
19+ using : composite
20+ steps :
21+ - name : Add issue/commit check
22+ id : comment-and-check
23+ # Run only if action wasn't triggered by comment or manually
24+ if : github.event_name == 'workflow_dispatch' || github.event_name == 'issue_comment'
25+ uses : actions/github-script@v7
26+ env :
27+ CHECK_STATE : ${{ inputs.checkState }}
28+ CHECK_NAME : ${{ inputs.checkName }}
29+ CHECK_DESCRIPTION : ${{ inputs.checkDescription }}
30+ SHA : ${{ inputs.sha }}
31+ with :
32+ script : |
33+ const {owner, repo} = context.repo;
34+
35+ const checkState = process.env.CHECK_STATE
36+ const checkName = process.env.CHECK_NAME
37+ const desc = process.env.CHECK_DESCRIPTION
38+ let sha = process.env.SHA
39+ let prNumber = undefined;
40+ let isPr = undefined;
41+
42+ //------------------------------------------------------------------
43+ // 1) Work out PR number & HEAD SHA
44+ //------------------------------------------------------------------
45+ if (context.payload.pull_request) {
46+ isPr = true;
47+ prNumber = context.payload.pull_request.number;
48+ sha ||= context.payload.pull_request.head.sha;
49+ } else if (context.payload.issue?.pull_request) {
50+ isPr = true;
51+ prNumber = context.payload.issue.number;
52+ if (!sha) {
53+ const pr = await github.request(
54+ context.payload.issue.pull_request.url);
55+ sha = pr.data.head.sha;
56+ }
57+ } else {
58+ isPr = false;
59+ sha ||= context.sha;
60+ }
61+
62+ core.info(`Going to work with the following sha: “${sha}”.`);
63+
64+ if (sha) {
65+ //------------------------------------------------------------------
66+ // 2) Map state → conclusion
67+ //------------------------------------------------------------------
68+ const conclusionToState = {
69+ success: 'success',
70+ failure: 'failure',
71+ pending: 'in_progress',
72+ error: 'neutral',
73+ skipped: 'failure'
74+ };
75+ const conclusion = conclusionToState[checkState] ?? 'neutral';
76+
77+ //------------------------------------------------------------------
78+ // 3) Create NEW run if none is currently in progress
79+ //------------------------------------------------------------------
80+ const list = await github.rest.checks.listForRef({ owner, repo, ref : sha });
81+
82+ let run = list.data.check_runs
83+ .find(cr => cr.name === checkName && cr.status !== 'completed');
84+
85+ if (!run) {
86+ core.info(`Creating a new check-run ”${checkName}”`);
87+ run = (await github.rest.checks.create({
88+ owner, repo,
89+ name : checkName,
90+ head_sha : sha,
91+ status : ' in_progress' ,
92+ output : {
93+ title : checkName,
94+ summary : [
95+ desc,
96+ ' ' ,
97+ ` [See the full workflow run](${process.env.GITHUB_SERVER_URL}/` +
98+ ` ${process.env.GITHUB_REPOSITORY}/actions/runs/` +
99+ ` ${process.env.GITHUB_RUN_ID})`
100+ ].join('\n')
101+ },
102+ details_url :
103+ ` ${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}` +
104+ ` /actions/runs/${process.env.GITHUB_RUN_ID}`
105+ })).data;
106+ core.info(`Created new run : ${run.id} (status=${run.status})`)
107+ } else {
108+ core.info(`Re-using existing run # ${run.id} (status=${run.status})`);
109+ }
110+
111+ //------------------------------------------------------------------
112+ // 4) Finish the run when we have a final state
113+ //------------------------------------------------------------------
114+ core.info(`Conclusion for ”${checkName}” is ”${conclusion} (state=${checkState})”`);
115+
116+ if (conclusion !== 'in_progress') {
117+ await github.rest.checks.update({
118+ owner, repo, check_run_id : run.id,
119+ status : ' completed' ,
120+ name : checkName,
121+ conclusion,
122+ output : {
123+ title : checkName,
124+ summary : [
125+ desc,
126+ ' ' ,
127+ ` [See the full workflow run](${process.env.GITHUB_SERVER_URL}/` +
128+ ` ${process.env.GITHUB_REPOSITORY}/actions/runs/` +
129+ ` ${process.env.GITHUB_RUN_ID})`
130+ ].join('\n')
131+ },
132+ details_url :
133+ ` ${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}` +
134+ ` /actions/runs/${process.env.GITHUB_RUN_ID}`
135+ });
136+ }
137+
138+ //------------------------------------------------------------------
139+ // 5) Set commit status as well
140+ //------------------------------------------------------------------
141+ if (!isPr) {
142+ const stateForStatusApi =
143+ checkState === 'pending' ? 'pending' :
144+ checkState === 'failure' ? 'failure' :
145+ checkState === 'error' ? 'error' : ' success' ;
146+
147+ core.info(`Updating commit status “${checkName}”=“${stateForStatusApi}” for sha : “${sha}”.`);
148+
149+ await github.rest.repos.createCommitStatus({
150+ owner, repo,
151+ sha,
152+ state : stateForStatusApi,
153+ context : checkName,
154+ description : desc,
155+ target_url :
156+ ` ${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}` +
157+ ` /actions/runs/${process.env.GITHUB_RUN_ID}`
158+ });
159+ } else {
160+ core.info(`Not going to create commit status for sha : “${sha}”.`);
161+ }
162+ }
0 commit comments