Files
sigma/.github/workflows/test.yml
T
Tosone 2009156bf5 ci: replace Minio with rs3 and make E2E CI run
Run the self-hosted rs3 service instead of Minio in test.yml and swap the
local helper script, Makefile helm values, and AGENTS.md notes accordingly.

Fix the E2E workflow (refs #426): it only triggered on the `main` branch,
which does not exist in this repository, so the job never ran. Trigger it
on `dev` for both push and pull_request like test.yml, build the image via
the consolidated `make docker-build`, bump the checkout/setup-go actions,
drop the hosted-toolcache cleanup, and refresh the E2E tooling to k6
v2.3.0 and skopeo v1.24.1.

Repair the image startup path as well: start nginx with an explicit
/etc/nginx/nginx.conf and a /dev/stderr error log so the non-root user does
not touch the compiled-in log path, create /etc/sigma with mode 0755 before
copying config.yaml (COPY --chmod made the directory non-traversable), and
disable redis in the shipped default config since cache, locker and work
queue are inmemory.
2026-09-26 19:42:46 +08:00

300 lines
10 KiB
YAML

# yaml-language-server: $schema=https://www.schemastore.org/github-workflow.json
name: Test CI
on:
push:
branches:
- dev
pull_request:
branches:
- dev
jobs:
unit-test:
name: unit-test
runs-on: ubuntu-24.04
strategy:
matrix:
go: ["1.27"]
bun: ["latest"]
services:
mysql:
image: mysql:9
env:
MYSQL_ROOT_PASSWORD: sigma
MYSQL_DATABASE: sigma
MYSQL_USER: sigma
MYSQL_PASSWORD: sigma
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=10
postgresql:
image: postgres:18-alpine
env:
POSTGRES_PASSWORD: sigma
POSTGRES_USER: sigma
POSTGRES_DB: sigma
ports:
- 5432:5432
options: --health-cmd="pg_isready -U sigma -d sigma || exit 1" --health-interval=10s --health-timeout=5s --health-retries=10
rs3:
image: ghcr.io/go-sigma/rs3:latest
env:
RS3_HOST: 0.0.0.0
RS3_PORT: 9000
RS3_DATA_DIR: /var/lib/rs3/data
RS3_ACCESS_KEY: sigma
RS3_SECRET_KEY: sigma-sigma
RS3_ENDPOINT: http://127.0.0.1:9000
ports:
- 9000:9000
entrypoint: /bin/sh
command: '-c "mkdir -p /var/lib/rs3/data/sigma && exec rs3"'
options: >-
--health-cmd "curl --fail http://127.0.0.1:${RS3_PORT}/readyz || exit 1"
--health-interval 30s
--health-timeout 3s
--health-start-period 5s
--health-retries 3
steps:
- name: Checkout branch
uses: actions/checkout@v7
with:
fetch-depth: 0
lfs: true
- name: Setup redis
run: |
docker run --name sigma-redis -p 6379:6379 -d --rm --health-cmd "redis-cli -a sigma ping || exit 1" --health-interval 10s --health-timeout 5s --health-retries 10 redis:7-alpine --requirepass sigma
- name: Setup golang
uses: actions/setup-go@v7
with:
go-version: ${{ matrix.go }}
cache: false
- name: Setup bun
uses: oven-sh/setup-bun@v2
with:
bun-version: ${{ matrix.bun }}
- name: Cache bun
uses: actions/cache@v6
with:
path: |
~/.bun/install/cache
web/node_modules
key: ${{ runner.os }}-bun-${{ matrix.bun }}-${{ hashFiles('web/bun.lock', 'web/package.json') }}
restore-keys: |
${{ runner.os }}-bun-${{ matrix.bun }}-
${{ runner.os }}-bun-
- name: Build web
run: |
cd web
bun install --frozen-lockfile
bun run build
- name: Cache go modules
uses: actions/cache@v6
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-mod-${{ matrix.go }}-${{ hashFiles('go.sum') }}
restore-keys: |
${{ runner.os }}-go-mod-${{ matrix.go }}-
${{ runner.os }}-go-mod-
- name: Cache go build and test
uses: actions/cache@v6
with:
path: /home/runner/.cache/go-build
key: ${{ runner.os }}-go-build-test-${{ matrix.go }}-${{ hashFiles('go.mod', 'go.sum') }}-${{ hashFiles('cmd/**/*.go', 'pkg/**/*.go', 'main.go') }}
restore-keys: |
${{ runner.os }}-go-build-test-${{ matrix.go }}-${{ hashFiles('go.mod', 'go.sum') }}-
${{ runner.os }}-go-build-test-${{ matrix.go }}-
${{ runner.os }}-go-build-test-
- name: Run unit tests
env:
COS_ENDPOINT: ${{ secrets.COS_ENDPOINT }}
COS_AK: ${{ secrets.COS_AK }}
COS_SK: ${{ secrets.COS_SK }}
OSS_ENDPOINT: ${{ secrets.OSS_ENDPOINT }}
OSS_AK: ${{ secrets.OSS_AK }}
OSS_SK: ${{ secrets.OSS_SK }}
OSS_BUCKET: ${{ secrets.OSS_BUCKET }}
GOCACHE: /home/runner/.cache/go-build
run: |
set -euo pipefail
# Avoid the flaky turso native library cache ("cached library file hash sum mismatch")
rm -rf "${HOME}/.cache/turso-go"
mkdir -p test-results
packages() {
local excludes=(
"pkg/api"
"pkg/dal/models"
"pkg/dal/query"
"pkg/dal/cmd"
"pkg/version"
)
if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then
excludes+=("pkg/storage/oss")
fi
go list ./... | while read -r pkg; do
local skipped=0
for exclude in "${excludes[@]}"; do
if [[ "${pkg}" == *"${exclude}"* ]]; then
skipped=1
break
fi
done
if [ "${skipped}" -eq 0 ]; then
echo "${pkg}"
fi
done
}
database_packages() {
packages | while read -r pkg; do
case "${pkg}" in
github.com/go-sigma/sigma/pkg/dal|github.com/go-sigma/sigma/pkg/dal/repository/*)
echo "${pkg}"
;;
esac
done
}
application_packages() {
packages | while read -r pkg; do
case "${pkg}" in
github.com/go-sigma/sigma/pkg/dal|github.com/go-sigma/sigma/pkg/dal/repository/*)
;;
*)
echo "${pkg}"
;;
esac
done
}
run_tests() {
local suite="$1"
local database_type="$2"
local cos_endpoint="$3"
local oss_bucket="$4"
local coverage_file="coverage-${suite}-${database_type}.txt"
local -a test_packages
if [ "${suite}" = "database" ]; then
mapfile -t test_packages < <(database_packages)
else
mapfile -t test_packages < <(application_packages)
fi
{
echo ""
echo "========== unit-test-${suite}-${database_type} =========="
echo "Running ${suite} tests with CI_DATABASE_TYPE=${database_type}"
} | tee -a test-results/unit-test.log
set +e
CI_DATABASE_TYPE="${database_type}" \
COS_ENDPOINT="${cos_endpoint}" \
OSS_BUCKET="${oss_bucket}" \
go test -parallel 1 -failfast \
-tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" \
-timeout 30m -v \
-coverprofile="${coverage_file}" -covermode=atomic \
"${test_packages[@]}" 2>&1 | tee -a test-results/unit-test.log
local status="${PIPESTATUS[0]}"
set -e
echo "${suite}:${database_type}:${status}" >> test-results/status.txt
return "${status}"
}
status=0
run_tests "application" "postgresql" "${COS_ENDPOINT}" "${OSS_BUCKET}" || status=1
run_tests "database" "sqlite3" "${COS_ENDPOINT}" "${OSS_BUCKET}" || status=1
run_tests "database" "turso" "${COS_ENDPOINT}" "${OSS_BUCKET}" || status=1
run_tests "database" "postgresql" "${COS_ENDPOINT}" "${OSS_BUCKET}" || status=1
run_tests "database" "mysql" "${COS_ENDPOINT}" "${OSS_BUCKET}" || status=1
{
echo "### Package Results"
echo ""
echo "| Suite | Database | Status | Package | Duration | Coverage | Notes |"
echo "| --- | --- | --- | --- | --- | --- | --- |"
awk '
/^========== unit-test-/ {
section = $0
sub(/^========== unit-test-/, "", section)
sub(/ ==========$/, "", section)
split(section, section_parts, "-")
suite = section_parts[1]
database = section_parts[2]
next
}
/^(ok|FAIL|\?)[[:space:]]+github\.com\/go-sigma\/sigma\// {
status = $1
package_name = $2
sub(/^github\.com\/go-sigma\/sigma\//, "", package_name)
duration = "-"
coverage = "-"
notes = "-"
if (status == "ok") {
status = "passed"
} else if (status == "FAIL") {
status = "failed"
} else {
status = "no tests"
}
for (i = 3; i <= NF; i++) {
if ($i ~ /^[0-9]+(\.[0-9]+)?s$/) {
duration = $i
} else if ($i == "coverage:" && i < NF) {
coverage = $(i + 1)
}
}
if (index($0, "(cached)") > 0) {
notes = "cached"
}
if (index($0, "[no test files]") > 0) {
notes = "no test files"
} else if (index($0, "[no tests to run]") > 0) {
notes = notes == "-" ? "no tests to run" : notes ", no tests to run"
}
database_order = 99
if (database == "postgresql") {
database_order = 1
} else if (database == "mysql") {
database_order = 2
} else if (database == "sqlite3") {
database_order = 3
} else if (database == "turso") {
database_order = 4
}
printf "%d\t| %s | %s | %s | `%s` | %s | %s | %s |\n", database_order, suite, database, status, package_name, duration, coverage, notes
}
' test-results/unit-test.log |
sort -s -k1,1n |
cut -f2- || true
} | tee test-results/summary.md >> "$GITHUB_STEP_SUMMARY"
exit "${status}"
- name: Upload unit test logs
if: always()
uses: actions/upload-artifact@v7
with:
name: unit-test-results
path: |
test-results/
- name: Upload coverage reports to Coveralls
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.COVERALLS_REPO_TOKEN }}
format: golang
flag-name: unit-test
files: coverage-application-postgresql.txt coverage-database-sqlite3.txt coverage-database-turso.txt coverage-database-postgresql.txt coverage-database-mysql.txt