Harden dynamic Bash authorization without disrupting Auto / 加固动态 Bash 授权并保持 Auto 低干预 #10256
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main-v2] | |
| pull_request: | |
| branches: [main-v2] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Install and verify Linux sandbox backend | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y bubblewrap | |
| if sysctl -n kernel.unprivileged_userns_clone >/dev/null 2>&1; then | |
| sudo sysctl -w kernel.unprivileged_userns_clone=1 | |
| fi | |
| if sysctl -n kernel.apparmor_restrict_unprivileged_userns >/dev/null 2>&1; then | |
| sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 | |
| fi | |
| bwrap --ro-bind / / --dev /dev --proc /proc -- true || \ | |
| echo "::warning::bubblewrap is installed but this runner denies user namespaces; unavailable-backend tests will run fail-closed" | |
| # Skipped on Windows: the runner checks out CRLF, so gofmt -l flags every | |
| # file. gofmt output is OS-independent, so the Unix legs already cover it. | |
| - name: gofmt | |
| if: runner.os != 'Windows' | |
| run: | | |
| # Root module only — desktop/ is a separate module with its own tooling. | |
| unformatted=$(gofmt -l . | grep -v '^desktop/' || true) | |
| if [ -n "$unformatted" ]; then | |
| echo "These files are not gofmt-clean:" | |
| echo "$unformatted" | |
| exit 1 | |
| fi | |
| - name: vet | |
| run: go vet ./... | |
| - name: build | |
| run: go build ./... | |
| - name: test | |
| if: runner.os != 'Windows' | |
| env: | |
| # Run the prompt-cache prefix-stability guard (TestCacheHit*) in CI: a | |
| # regression there silently tanks the cache hit rate the project is | |
| # built around. | |
| REASONIX_RELEASE_CACHE_GUARD: "1" | |
| run: go test ./... | |
| - name: test | |
| if: runner.os == 'Windows' | |
| timeout-minutes: 10 | |
| env: | |
| # Run the prompt-cache prefix-stability guard (TestCacheHit*) in CI: a | |
| # regression there silently tanks the cache hit rate the project is | |
| # built around. | |
| REASONIX_RELEASE_CACHE_GUARD: "1" | |
| # Bound sandbox helper children in Windows tests so a failed OS-level | |
| # launch cannot pin the Actions step after Go's package timeout fires. | |
| WINDOWS_SANDBOX_WAIT_MS: "20000" | |
| run: go test -p 4 -timeout=3m ./... | |
| race: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Install and verify Linux sandbox backend | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y bubblewrap | |
| if sysctl -n kernel.unprivileged_userns_clone >/dev/null 2>&1; then | |
| sudo sysctl -w kernel.unprivileged_userns_clone=1 | |
| fi | |
| if sysctl -n kernel.apparmor_restrict_unprivileged_userns >/dev/null 2>&1; then | |
| sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 | |
| fi | |
| bwrap --ro-bind / / --dev /dev --proc /proc -- true || \ | |
| echo "::warning::bubblewrap is installed but this runner denies user namespaces; unavailable-backend tests will run fail-closed" | |
| # The matrix never runs -race (it needs cgo); the project's concurrency | |
| # (plugin fan-out, background phase B, jobs Kill/Wait) would otherwise | |
| # ship without race coverage. | |
| - name: test -race | |
| env: | |
| REASONIX_RELEASE_CACHE_GUARD: "1" | |
| run: go test -race ./... | |
| desktop: | |
| runs-on: ubuntu-22.04 | |
| defaults: | |
| run: | |
| working-directory: desktop | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: desktop/go.mod | |
| cache: true | |
| cache-dependency-path: desktop/go.sum | |
| - uses: pnpm/action-setup@v6 | |
| with: | |
| version: 10 | |
| run_install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| cache: pnpm | |
| cache-dependency-path: desktop/frontend/pnpm-lock.yaml | |
| - name: Install Wails CLI | |
| run: | | |
| echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" | |
| go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0 | |
| - name: gofmt | |
| run: | | |
| unformatted=$(gofmt -l .) | |
| if [ -n "$unformatted" ]; then | |
| echo "These files are not gofmt-clean:" | |
| echo "$unformatted" | |
| exit 1 | |
| fi | |
| - name: go.mod tidy | |
| run: | | |
| go mod tidy | |
| if ! git diff --quiet -- go.mod go.sum; then | |
| echo "desktop/go.mod or go.sum is stale - run 'cd desktop && go mod tidy' and commit." | |
| git diff -- go.mod go.sum | |
| exit 1 | |
| fi | |
| # WebKitGTK 4.0 toolchain (pinned to ubuntu-22.04; no webkit2_41 tag). | |
| - name: Install Linux build deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc libgtk-3-dev libwebkit2gtk-4.0-dev | |
| - name: Build frontend | |
| run: | | |
| wails generate module | |
| pnpm --dir frontend install --frozen-lockfile | |
| pnpm --dir frontend build | |
| - name: vet | |
| run: go vet ./... | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@v9 | |
| with: | |
| version: v2.12.2 | |
| working-directory: desktop | |
| args: --timeout=5m | |
| - name: build | |
| run: go build ./... | |
| - name: test | |
| run: go test ./... | |
| # Desktop project-root matching is case-insensitive only on Windows | |
| # (sameDesktopPath folds case when os.PathSeparator is '\'), so the | |
| # regression tests for that contract are named *OnWindows and can never | |
| # run on the ubuntu leg above. | |
| desktop-windows: | |
| runs-on: windows-latest | |
| defaults: | |
| run: | |
| shell: bash | |
| working-directory: desktop | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: desktop/go.mod | |
| cache: true | |
| cache-dependency-path: desktop/go.sum | |
| - uses: pnpm/action-setup@v6 | |
| with: | |
| version: 10 | |
| run_install: false | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| cache: pnpm | |
| cache-dependency-path: desktop/frontend/pnpm-lock.yaml | |
| - name: Install Wails CLI | |
| run: | | |
| echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" | |
| go install github.com/wailsapp/wails/v2/cmd/wails@v2.12.0 | |
| # go:embed of frontend/dist needs a built frontend before the package | |
| # compiles, same as the ubuntu desktop leg. | |
| - name: Build frontend | |
| run: | | |
| wails generate module | |
| pnpm --dir frontend install --frozen-lockfile | |
| pnpm --dir frontend build | |
| - name: test (Windows desktop and update helper) | |
| timeout-minutes: 15 | |
| run: go test ./... | |
| - name: Install NSIS | |
| run: pwsh -NoProfile -File ../scripts/install-nsis.ps1 | |
| - name: Build Windows installer and portable archive | |
| timeout-minutes: 20 | |
| run: ../scripts/desktop-build.sh windows/amd64 v0.0.0-ci canary | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@v9 | |
| with: | |
| version: v2.12.2 | |
| args: --timeout=5m | |
| - name: release workflow contracts | |
| run: | | |
| go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 \ | |
| -ignore 'label "windows-11-arm" is unknown' \ | |
| .github/workflows/release-stable.yml \ | |
| .github/workflows/release-cli-trigger.yml \ | |
| .github/workflows/release.yml \ | |
| .github/workflows/release-npm.yml \ | |
| .github/workflows/release-desktop.yml | |
| bash scripts/release-workflows.test.sh | |
| # The site/ auth client has security-sensitive redirect-validation logic | |
| # (safeNext) covered by node:test unit tests. Those tests use only Node | |
| # builtins, so no `npm install` is needed — run them directly on every PR so | |
| # a regression in redirect validation fails the build instead of shipping. | |
| site: | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: site | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| - name: test | |
| run: npm test | |
| govulncheck: | |
| runs-on: ubuntu-latest | |
| continue-on-error: true # informational — stdlib vulns need a Go patch release | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: install govulncheck | |
| run: go install golang.org/x/vuln/cmd/govulncheck@latest | |
| - name: govulncheck | |
| run: govulncheck ./... | |
| coverage: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: test with coverage | |
| run: go test -coverprofile=coverage.out -covermode=atomic ./... | |
| - name: upload coverage | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-report | |
| path: coverage.out | |
| retention-days: 7 |