actions/steps/create-status/action.yaml (150 lines of code) (raw):
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Create status
description: Creates a check on a commit.
inputs:
sha:
description: The commit SHA to create the check for.
required: true
name:
description: The name of the check.
required: true
status:
description: One of "queued", "in_progress", "success", "failure", "action_required", "cancelled", "neutral", "success", "skipped", or "timed_out".
default: queued
title:
description: The title of the check, this appears in the "progress" of the check UI.
url:
description: The URL to the details of the check.
repository-owner:
description: The owner of the repository.
default: ${{ github.repository_owner }}
repository-name:
description: The name of the repository.
default: ${{ github.event.repository.name }}
if:
description: If true the check is created, otherwise it is skipped.
default: "true"
outputs:
check:
description: The whole check in JSON.
value: ${{ steps.check.outputs.result }}
runs:
using: composite
steps:
- uses: actions/github-script@v7
id: check
with:
script: |
async function* listChecks({owner, repo, sha}) {
let page = 1;
let checks = [];
console.log(`Listing checks for ${sha}`);
do {
// https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#create-a-commit-status
// https://octokit.github.io/rest.js/v18/#repos-list-commit-statuses-for-ref
const response = await github.rest.repos.listCommitStatusesForRef({
owner: owner,
repo: repo,
ref: sha,
page: page++,
});
checks = response.data;
for (const check of checks) {
console.log(`- [${check.state}] ${check.context} -- ${check.description}`);
yield check;
}
} while (checks.length > 0 && page < 100);
}
async function findCheck({owner, repo, sha, name}) {
const checks = listChecks({owner: owner, repo: repo, sha: sha});
for await (const check of checks) {
if (check.context === name) {
console.log(`Found check: [${check.state}] ${check.context} -- ${check.description}`);
return check;
}
}
return null;
}
// Convert to what the Status API needs.
// We use this conversion to be able to migrate to Checks API in the future.
let state = null;
let title = `${{ inputs.title }}`;
switch ("${{ inputs.status }}") {
case "queued":
state = "pending";
title = title || "Queued";
break;
case "in_progress":
state = "pending";
title = title || "In progress";
break;
case "success":
state = "success";
title = title || "Successful";
break;
case "failure":
state = "failure";
title = title || "Failed";
break;
case "action_required":
state = "failure";
title = title || "Action required";
break;
case "cancelled":
state = "success";
title = title || "Cancelled";
break;
case "neutral":
state = "success";
title = title || "Neutral";
break;
case "skipped":
state = "success";
title = title || "Skipped";
break;
case "timed_out":
state = "failure";
title = title || "Timed out";
break;
default:
throw new Error('Unknown status "${{ inputs.status }}", must be one of "queued", "in_progress", "success", "failure", "action_required", "cancelled", "neutral", "success", "skipped", or "timed_out".');
}
if (${{ inputs.if }}) {
// If set to a terminal state, append the elapsed time.
if (["success", "failure", "timed_out"].includes("${{ inputs.status }}")) {
const check = await findCheck({
owner: "${{ inputs.repository-owner }}",
repo: "${{ inputs.repository-name }}",
sha: "${{ inputs.sha }}",
name: "${{ inputs.name }}",
});
if (check) {
const start = Date.parse(check.updated_at);
const end = Date.now();
const elapsed = Math.round((Date.now() - start) / 1000);
title = `${title} in ${elapsed}s`;
}
}
// https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#create-a-commit-status
// https://octokit.github.io/rest.js/v18/#repos-create-commit-status
// https://stackoverflow.com/a/72312617
console.log(`Create check: [${{ inputs.status }}] ${{ inputs.name }} -- ${title}`);
github.rest.repos.createCommitStatus({
owner: "${{ inputs.repository-owner }}",
repo: "${{ inputs.repository-name }}",
sha: "${{ inputs.sha }}",
state: state,
context: `${{ inputs.name }}`,
description: title,
target_url: `${{ inputs.url }}` || undefined,
});
}
return {
sha: "${{ inputs.sha }}",
name: "${{ inputs.name }}",
status: "${{ inputs.status }}",
title: "${{ inputs.title }}",
url: "${{ inputs.url }}",
"repository-name": "${{ inputs.repository-name }}",
"repository-owner": "${{ inputs.repository-owner }}",
if: ${{ inputs.if }},
};