name: CI on: push: branches: ["**"] tags: ["v*"] pull_request: branches: ["**"] jobs: build-and-test: runs-on: self-hosted defaults: run: shell: bash steps: - name: Show runner env (debug) run: | set -x echo "GITHUB_SERVER_URL=${GITHUB_SERVER_URL:-}" echo "GITHUB_REPOSITORY=${GITHUB_REPOSITORY:-}" echo "GITHUB_REF=${GITHUB_REF:-}" echo "GITHUB_SHA=${GITHUB_SHA:-}" - name: Checkout (manual, no marketplace) run: | set -euo pipefail if git rev-parse --git-dir >/dev/null 2>&1; then echo "Repository already present." git --no-pager log -1 --oneline || true else : "${GITHUB_SERVER_URL:?GITHUB_SERVER_URL not set}" : "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY not set}" REPO_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" FETCH="${GITHUB_SHA:-${GITHUB_REF:-}}" [ -n "$FETCH" ] || { echo "::error::GITHUB_SHA and GITHUB_REF are empty; cannot checkout"; exit 1; } AUTH_URL="$REPO_URL" if [ -n "${GITHUB_TOKEN:-}" ]; then host="${GITHUB_SERVER_URL#https://}" AUTH_URL="https://x-access-token:${GITHUB_TOKEN}@${host}/${GITHUB_REPOSITORY}.git" fi git init . git remote add origin "$AUTH_URL" if [[ "$FETCH" == refs/* ]]; then git fetch --no-tags --depth=1 origin "$FETCH" && git checkout --detach FETCH_HEAD else git fetch --no-tags --depth=1 origin "$FETCH" && git checkout --detach "$FETCH" fi git submodule update --init --recursive git --no-pager log -1 --oneline fi - name: Install Node (tarball) if not present run: | set -euo pipefail if command -v node >/dev/null 2>&1; then echo "Using preinstalled Node: $(node -v)" else NODE_VERSION="20.12.2" OS="$(uname -s | tr '[:upper:]' '[:lower:]')" ARCH="$(uname -m)" case "$ARCH" in x86_64) ARCH="x64" ;; aarch64|arm64) ARCH="arm64" ;; *) echo "Unsupported arch: $ARCH" >&2; exit 1 ;; esac echo "Fetching Node v$NODE_VERSION for $OS-$ARCH" curl -fsSL "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-$OS-$ARCH.tar.xz" -o node.tar.xz mkdir -p "$HOME/node" tar -xJf node.tar.xz -C "$HOME/node" --strip-components=1 echo "$HOME/node/bin" >> "$GITHUB_PATH" export PATH="$HOME/node/bin:$PATH" hash -r node -v && npm -v fi - name: Install dependencies run: | if [ -f package-lock.json ]; then npm ci || npm i else npm i fi - name: Lint (if script exists) run: npm run -s lint || echo "No lint script" - name: Typecheck (if tsconfig.json exists) run: | if [ -f tsconfig.json ]; then npx tsc -b --noEmit else echo "No tsconfig.json; skipping typecheck" fi - name: Build (if script exists) run: npm run -s build || echo "No build script" - name: Tests with coverage (enforce thresholds) env: COV_LINES: "70" COV_BRANCHES: "70" COV_FUNCTIONS: "50" COV_STATEMENTS: "70" run: | npx vitest run --coverage node scripts/ci-check-coverage.mjs - name: Coverage summary if: always() run: | if [ -f coverage/coverage-summary.json ]; then node -e "console.log(JSON.stringify(require('./coverage/coverage-summary.json').total, null, 2))" else echo "No coverage summary found" fi