diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..8537e66 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +/.github/workflows/ @c4pt0r @IANTHEREAL @shizn @sunxiaoguang +/.github/actions/ @c4pt0r @IANTHEREAL @shizn @sunxiaoguang diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 0000000..9476f75 --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,2 @@ +self-hosted-runner: + labels: [self-hosted, linux, "arch:amd64", "arch:arm64", default, on-demand, trusted-public-main, ghr-ec2-vcpus:1, ghr-ec2-vcpus:2, ghr-ec2-vcpus:4, ghr-ec2-vcpus:8, ghr-ec2-vcpus:16, ghr-ec2-memory-gib:8, ghr-ec2-memory-gib:16, ghr-ec2-memory-gib:32, ghr-ec2-memory-gib:64] diff --git a/.github/actions/sys9-disk-guard/action.yml b/.github/actions/sys9-disk-guard/action.yml new file mode 100644 index 0000000..5c7760e --- /dev/null +++ b/.github/actions/sys9-disk-guard/action.yml @@ -0,0 +1,65 @@ +name: Sys9 disk guard +description: Ensure a workspace filesystem has enough free space, optionally cleaning it once before a job continues. + +inputs: + path: + description: Filesystem path whose available space should be checked. + required: false + default: ${{ github.workspace }} + minimum_free_gib: + description: Minimum available space required after cleanup, in GiB. + required: false + default: "15" + cleanup_command: + description: Optional shell command used once when available space is below the minimum. + required: false + default: "" + +runs: + using: composite + steps: + - name: Check workspace disk space + shell: bash + env: + DISK_GUARD_PATH: ${{ inputs.path }} + DISK_GUARD_MINIMUM_FREE_GIB: ${{ inputs.minimum_free_gib }} + DISK_GUARD_CLEANUP_COMMAND: ${{ inputs.cleanup_command }} + run: | + set -euo pipefail + + if [[ ! "${DISK_GUARD_MINIMUM_FREE_GIB}" =~ ^[1-9][0-9]*$ ]]; then + echo "disk guard: minimum_free_gib must be a positive integer" >&2 + exit 1 + fi + if [[ ! -e "${DISK_GUARD_PATH}" ]]; then + echo "disk guard: path does not exist: ${DISK_GUARD_PATH}" >&2 + exit 1 + fi + + minimum_free_kb=$((DISK_GUARD_MINIMUM_FREE_GIB * 1024 * 1024)) + available_kb() { + local value + value="$(df -Pk "${DISK_GUARD_PATH}" | awk 'NR == 2 {print $4}')" + if [[ ! "${value}" =~ ^[0-9]+$ ]]; then + echo "disk guard: unable to read free space for ${DISK_GUARD_PATH}" >&2 + return 1 + fi + printf '%s\n' "${value}" + } + + free_kb="$(available_kb)" + if (( free_kb < minimum_free_kb )); then + if [[ -z "${DISK_GUARD_CLEANUP_COMMAND}" ]]; then + echo "disk guard: free space ${free_kb}KiB is below ${minimum_free_kb}KiB and no cleanup command was supplied" >&2 + exit 1 + fi + echo "disk guard: free space ${free_kb}KiB is below ${minimum_free_kb}KiB; running targeted cleanup" >&2 + bash -euo pipefail -c "${DISK_GUARD_CLEANUP_COMMAND}" + free_kb="$(available_kb)" + if (( free_kb < minimum_free_kb )); then + echo "disk guard: free space remains ${free_kb}KiB after cleanup; refusing to continue" >&2 + exit 1 + fi + fi + + echo "disk guard: ${free_kb}KiB available at ${DISK_GUARD_PATH}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1521199..cacec5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,12 +5,49 @@ on: branches: [main] pull_request: +permissions: + contents: read + jobs: - test: + pull-request-test: + name: Pull request test + if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + - name: Guard workspace disk + uses: ./.github/actions/sys9-disk-guard + with: + path: ${{ github.workspace }} + minimum_free_gib: "15" + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 + with: + go-version: "1.25.x" + - name: gofmt + run: test -z "$(gofmt -l .)" + - name: go vet + run: go vet ./... + - name: go test + run: go test -count=1 -race ./... + + main-test: + name: Main test + if: github.event_name == 'push' + runs-on: + group: auth9token-go main + labels: [self-hosted, linux, trusted-public-main, "arch:amd64", "ghr-ec2-vcpus:2"] + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + - name: Guard workspace disk + uses: ./.github/actions/sys9-disk-guard + with: + path: ${{ github.workspace }} + minimum_free_gib: "15" + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 with: go-version: "1.25.x" - name: gofmt diff --git a/.github/workflows/runner-canary.yml b/.github/workflows/runner-canary.yml new file mode 100644 index 0000000..c784489 --- /dev/null +++ b/.github/workflows/runner-canary.yml @@ -0,0 +1,192 @@ +name: Runner canary + +on: + workflow_dispatch: + +permissions: + contents: read + +jobs: + round-1: + name: Runner canary 1 + runs-on: + group: auth9token-go main + labels: [self-hosted, linux, trusted-public-main, "arch:amd64", "ghr-ec2-vcpus:1"] + timeout-minutes: 3 + steps: + - name: Check out repository + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + + - name: Guard workspace disk + uses: ./.github/actions/sys9-disk-guard + with: + path: ${{ github.workspace }} + minimum_free_gib: "15" + + - name: Record sanitized runner evidence + shell: bash + env: + CANARY_ROUND: "1" + EXPECTED_LABELS: self-hosted,linux,trusted-public-main,arch:amd64,ghr-ec2-vcpus:1 + run: | + set -euo pipefail + if [[ "${RUNNER_ARCH}" != "X64" ]]; then + echo "runner canary: expected X64 architecture, got ${RUNNER_ARCH}" >&2 + exit 1 + fi + available_kb="$(df -Pk "${GITHUB_WORKSPACE}" | awk 'NR == 2 {print $4}')" + if [[ ! "${available_kb}" =~ ^[0-9]+$ ]]; then + echo "runner canary: unable to read workspace free space" >&2 + exit 1 + fi + echo "round=${CANARY_ROUND} labels=${EXPECTED_LABELS} architecture=${RUNNER_ARCH} available_kb=${available_kb} status=success" + + round-2: + name: Runner canary 2 + needs: round-1 + runs-on: + group: auth9token-go main + labels: [self-hosted, linux, trusted-public-main, "arch:amd64", "ghr-ec2-vcpus:1"] + timeout-minutes: 3 + steps: + - name: Check out repository + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + + - name: Guard workspace disk + uses: ./.github/actions/sys9-disk-guard + with: + path: ${{ github.workspace }} + minimum_free_gib: "15" + + - name: Record sanitized runner evidence + shell: bash + env: + CANARY_ROUND: "2" + EXPECTED_LABELS: self-hosted,linux,trusted-public-main,arch:amd64,ghr-ec2-vcpus:1 + run: | + set -euo pipefail + if [[ "${RUNNER_ARCH}" != "X64" ]]; then + echo "runner canary: expected X64 architecture, got ${RUNNER_ARCH}" >&2 + exit 1 + fi + available_kb="$(df -Pk "${GITHUB_WORKSPACE}" | awk 'NR == 2 {print $4}')" + if [[ ! "${available_kb}" =~ ^[0-9]+$ ]]; then + echo "runner canary: unable to read workspace free space" >&2 + exit 1 + fi + echo "round=${CANARY_ROUND} labels=${EXPECTED_LABELS} architecture=${RUNNER_ARCH} available_kb=${available_kb} status=success" + + round-3: + name: Runner canary 3 + needs: round-2 + runs-on: + group: auth9token-go main + labels: [self-hosted, linux, trusted-public-main, "arch:amd64", "ghr-ec2-vcpus:1"] + timeout-minutes: 3 + steps: + - name: Check out repository + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + + - name: Guard workspace disk + uses: ./.github/actions/sys9-disk-guard + with: + path: ${{ github.workspace }} + minimum_free_gib: "15" + + - name: Record sanitized runner evidence + shell: bash + env: + CANARY_ROUND: "3" + EXPECTED_LABELS: self-hosted,linux,trusted-public-main,arch:amd64,ghr-ec2-vcpus:1 + run: | + set -euo pipefail + if [[ "${RUNNER_ARCH}" != "X64" ]]; then + echo "runner canary: expected X64 architecture, got ${RUNNER_ARCH}" >&2 + exit 1 + fi + available_kb="$(df -Pk "${GITHUB_WORKSPACE}" | awk 'NR == 2 {print $4}')" + if [[ ! "${available_kb}" =~ ^[0-9]+$ ]]; then + echo "runner canary: unable to read workspace free space" >&2 + exit 1 + fi + echo "round=${CANARY_ROUND} labels=${EXPECTED_LABELS} architecture=${RUNNER_ARCH} available_kb=${available_kb} status=success" + + round-4: + name: Runner canary 4 + needs: round-3 + runs-on: + group: auth9token-go main + labels: [self-hosted, linux, trusted-public-main, "arch:amd64", "ghr-ec2-vcpus:1"] + timeout-minutes: 3 + steps: + - name: Check out repository + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + + - name: Guard workspace disk + uses: ./.github/actions/sys9-disk-guard + with: + path: ${{ github.workspace }} + minimum_free_gib: "15" + + - name: Record sanitized runner evidence + shell: bash + env: + CANARY_ROUND: "4" + EXPECTED_LABELS: self-hosted,linux,trusted-public-main,arch:amd64,ghr-ec2-vcpus:1 + run: | + set -euo pipefail + if [[ "${RUNNER_ARCH}" != "X64" ]]; then + echo "runner canary: expected X64 architecture, got ${RUNNER_ARCH}" >&2 + exit 1 + fi + available_kb="$(df -Pk "${GITHUB_WORKSPACE}" | awk 'NR == 2 {print $4}')" + if [[ ! "${available_kb}" =~ ^[0-9]+$ ]]; then + echo "runner canary: unable to read workspace free space" >&2 + exit 1 + fi + echo "round=${CANARY_ROUND} labels=${EXPECTED_LABELS} architecture=${RUNNER_ARCH} available_kb=${available_kb} status=success" + + round-5: + name: Runner canary 5 + needs: round-4 + runs-on: + group: auth9token-go main + labels: [self-hosted, linux, trusted-public-main, "arch:amd64", "ghr-ec2-vcpus:1"] + timeout-minutes: 3 + steps: + - name: Check out repository + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + + - name: Guard workspace disk + uses: ./.github/actions/sys9-disk-guard + with: + path: ${{ github.workspace }} + minimum_free_gib: "15" + + - name: Record sanitized runner evidence + shell: bash + env: + CANARY_ROUND: "5" + EXPECTED_LABELS: self-hosted,linux,trusted-public-main,arch:amd64,ghr-ec2-vcpus:1 + run: | + set -euo pipefail + if [[ "${RUNNER_ARCH}" != "X64" ]]; then + echo "runner canary: expected X64 architecture, got ${RUNNER_ARCH}" >&2 + exit 1 + fi + available_kb="$(df -Pk "${GITHUB_WORKSPACE}" | awk 'NR == 2 {print $4}')" + if [[ ! "${available_kb}" =~ ^[0-9]+$ ]]; then + echo "runner canary: unable to read workspace free space" >&2 + exit 1 + fi + echo "round=${CANARY_ROUND} labels=${EXPECTED_LABELS} architecture=${RUNNER_ARCH} available_kb=${available_kb} status=success"