From fab0c4d45e0162963965f1555df27b7bed5e20ec Mon Sep 17 00:00:00 2001 From: John Coffey Date: Mon, 21 Sep 2026 22:34:54 -0700 Subject: [PATCH] Add checkout composite action --- README.md | 20 ++++++++++++++ checkout/action.yml | 65 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 README.md create mode 100644 checkout/action.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..f11ca9c --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# actions + +Shared Gitea Actions for Coffey Labs and INBUXA workflows. The instance sets +`DEFAULT_ACTIONS_URL = self`, so `uses: coffey-labs/actions/@` +resolves here and nothing is fetched from GitHub implicitly. + +Pin every use by full commit SHA. + +## checkout + +```yaml +- uses: coffey-labs/actions/checkout@ + with: + fetch-depth: 0 # optional; default 1. 0 = all history and tags + tags: true # optional; tags with a shallow fetch +``` + +Works in any job image with a POSIX shell. Installs git with apk or apt-get +if the image has none, and clones from the runner's internal Gitea address +(`CI_SERVER_INTERNAL`) so CI traffic never crosses Cloudflare. diff --git a/checkout/action.yml b/checkout/action.yml new file mode 100644 index 0000000..d0ffdf8 --- /dev/null +++ b/checkout/action.yml @@ -0,0 +1,65 @@ +name: checkout +description: > + Check out the triggering commit into the workspace, from Gitea's internal + address, in any job image. Unlike actions/checkout it needs no node in the + job container -- only a POSIX shell -- and installs git itself when the image + lacks it (php, python-slim, docker:cli, shellcheck-alpine). + +inputs: + fetch-depth: + description: Commits to fetch. 0 fetches all history and tags. + default: "1" + tags: + description: Also fetch tags when fetch-depth is not 0. + default: "false" + +runs: + using: composite + steps: + - shell: sh + env: + CO_TOKEN: ${{ github.token }} + CO_DEPTH: ${{ inputs.fetch-depth }} + CO_TAGS: ${{ inputs.tags }} + run: | + set -eu + if ! command -v git >/dev/null 2>&1; then + if command -v apk >/dev/null 2>&1; then + apk add --no-cache -q git + elif command -v apt-get >/dev/null 2>&1; then + apt-get -qq update >/dev/null + DEBIAN_FRONTEND=noninteractive apt-get -qq install -y --no-install-recommends git ca-certificates >/dev/null + else + echo "checkout: no git and no apk/apt-get in this image" >&2; exit 1 + fi + fi + + base="${CI_SERVER_INTERNAL:-$GITHUB_SERVER_URL}" + # The token rides in a header, never in the remote URL, so it cannot + # end up in .git/config or a log line. + auth="Authorization: Basic $(printf 'x-access-token:%s' "$CO_TOKEN" | base64 | tr -d '\n')" + + cd "$GITHUB_WORKSPACE" + git init -q . + git config --global --add safe.directory "$GITHUB_WORKSPACE" + git remote add origin "$base/$GITHUB_REPOSITORY.git" 2>/dev/null \ + || git remote set-url origin "$base/$GITHUB_REPOSITORY.git" + + if [ "$CO_DEPTH" = 0 ]; then + git -c http.extraHeader="$auth" fetch -q --tags --prune origin \ + '+refs/heads/*:refs/remotes/origin/*' "+$GITHUB_REF:refs/remotes/ci/ref" + else + tagopt=--no-tags; [ "$CO_TAGS" = true ] && tagopt=--tags + git -c http.extraHeader="$auth" fetch -q $tagopt --depth="$CO_DEPTH" origin \ + "+$GITHUB_REF:refs/remotes/ci/ref" + fi + + # GITHUB_SHA is what the run is for; the ref may have moved on since. + if git cat-file -e "$GITHUB_SHA^{commit}" 2>/dev/null; then + git checkout -q --detach "$GITHUB_SHA" + else + git -c http.extraHeader="$auth" fetch -q --depth="${CO_DEPTH:-1}" origin "$GITHUB_SHA" \ + && git checkout -q --detach "$GITHUB_SHA" \ + || { echo "checkout: $GITHUB_SHA is no longer reachable from $GITHUB_REF" >&2; exit 1; } + fi + echo "checked out $(git rev-parse --short HEAD) ($GITHUB_REF)"