diff --git a/.github/workflows/shadowsocksx-ng2-ci.yml b/.github/workflows/shadowsocksx-ng2-ci.yml index b10f4f90..69e1a560 100644 --- a/.github/workflows/shadowsocksx-ng2-ci.yml +++ b/.github/workflows/shadowsocksx-ng2-ci.yml @@ -107,12 +107,12 @@ jobs: - name: Test working-directory: ShadowsocksX-NG2 - run: task --exit-code validate STRICT=true -- ${{ matrix.gate }} + run: task --exit-code validate -- ${{ matrix.gate }} - name: Build if: matrix.gate == 'test' working-directory: ShadowsocksX-NG2 - run: task --exit-code build STRICT=true + run: task --exit-code build - name: Upload failed test evidence if: failure() diff --git a/ShadowsocksX-NG2/Taskfile.dist.yml b/ShadowsocksX-NG2/Taskfile.dist.yml index 77926b16..92e9b252 100644 --- a/ShadowsocksX-NG2/Taskfile.dist.yml +++ b/ShadowsocksX-NG2/Taskfile.dist.yml @@ -15,8 +15,6 @@ vars: DERIVED_DATA_DIR: '{{default (printf "%s/derivedData" .BUILD_DIR) .DERIVED_DATA_DIR}}' RELEASE_VERSION_PATTERN: '^v?[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$' TEST_TIMEOUT_ARGS: '-test-timeouts-enabled YES -default-test-execution-time-allowance 120 -maximum-test-execution-time-allowance 300' - STRICT: '{{default "false" .STRICT}}' - STRICT_BUILD_ARGS: '{{if eq .STRICT "true"}}SWIFT_SUPPRESS_WARNINGS=NO SWIFT_TREAT_WARNINGS_AS_ERRORS=YES GCC_TREAT_WARNINGS_AS_ERRORS=YES{{end}}' tasks: validate: @@ -65,7 +63,6 @@ tasks: - "printf '%s\n' {{printf \"[%s] running; log: %s/raw.log\" .GATE .GATE_DIR | shellQuote}}" - >- task --exit-code --taskfile {{.TASKFILE_DIR | shellQuote}}/Taskfile.dist.yml {{.GATE | shellQuote}} - STRICT={{.STRICT | shellQuote}} RESULT_BUNDLE_PATH={{.GATE_DIR | shellQuote}}/result.xcresult > {{.GATE_DIR | shellQuote}}/raw.log 2>&1 @@ -135,7 +132,7 @@ tasks: -destination 'platform=macOS,arch=arm64' -derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}} {{if .RESULT_BUNDLE_PATH}}-resultBundlePath {{.RESULT_BUNDLE_PATH | shellQuote}}{{end}} - {{.STRICT_BUILD_ARGS}} + SWIFT_SUPPRESS_WARNINGS=NO SWIFT_TREAT_WARNINGS_AS_ERRORS=YES GCC_TREAT_WARNINGS_AS_ERRORS=YES build build:release: @@ -160,6 +157,7 @@ tasks: -derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}} {{printf "MARKETING_VERSION=%s" .BUNDLE_MARKETING_VERSION | shellQuote}} {{printf "CURRENT_PROJECT_VERSION=%s" .CURRENT_PROJECT_VERSION | shellQuote}} + SWIFT_SUPPRESS_WARNINGS=NO SWIFT_TREAT_WARNINGS_AS_ERRORS=YES GCC_TREAT_WARNINGS_AS_ERRORS=YES build format: @@ -175,12 +173,12 @@ tasks: lint: desc: 'Lint the swift code by swiftlint' cmds: - - swiftlint lint --config .swiftlint.yml --no-cache + - swiftlint lint --strict --config .swiftlint.yml --no-cache lint:fix: desc: 'Automatically fix SwiftLint violations' cmds: - - swiftlint lint --fix --config .swiftlint.yml --no-cache + - swiftlint lint --fix --strict --config .swiftlint.yml --no-cache test: desc: 'Run conversion and unit tests' @@ -197,7 +195,7 @@ tasks: -derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}} {{if .RESULT_BUNDLE_PATH}}-resultBundlePath {{.RESULT_BUNDLE_PATH | shellQuote}}{{end}} {{.TEST_TIMEOUT_ARGS}} - {{.STRICT_BUILD_ARGS}} + SWIFT_SUPPRESS_WARNINGS=NO SWIFT_TREAT_WARNINGS_AS_ERRORS=YES GCC_TREAT_WARNINGS_AS_ERRORS=YES test test:binaries: @@ -224,7 +222,7 @@ tasks: -derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}} {{if .RESULT_BUNDLE_PATH}}-resultBundlePath {{.RESULT_BUNDLE_PATH | shellQuote}}{{end}} {{.TEST_TIMEOUT_ARGS}} - {{.STRICT_BUILD_ARGS}} + SWIFT_SUPPRESS_WARNINGS=NO SWIFT_TREAT_WARNINGS_AS_ERRORS=YES GCC_TREAT_WARNINGS_AS_ERRORS=YES test clean: diff --git a/docs/development.md b/docs/development.md index 93daf3bc..c7b8b6e2 100644 --- a/docs/development.md +++ b/docs/development.md @@ -22,7 +22,7 @@ By default, stages run in this order: `lint → test → build`. Real-process sm Each local `validate` run creates a separate `.build/validation/-/` directory and prints its absolute path at the start and end. `summary.txt` records each stage's status, exit code, and evidence status. For every executed stage, the corresponding subdirectory contains a combined stdout/stderr `raw.log` and a `status.txt` (`test:smoke` uses `test-smoke/`); Xcode stages also save `result.xcresult`. The console shows progress and a summary. Read the corresponding logs for complete errors. All artifacts are inside existing ignored directories. `task clean` deletes them, so copy anything you need to keep. -CI runs two independent matrix jobs: `test` and `test:smoke`, with fail-fast disabled. Both run through `task --exit-code validate STRICT=true -- ` and treat compiler warnings as errors. The `test` job also checks formatting, runs lint, and builds. Failed jobs upload retained validation logs, summaries, and result bundles for seven days. Read the uploaded `summary.txt` and `test-summary.json` first; test output is retained in `raw.log`. +CI runs two independent matrix jobs: `test` and `test:smoke`, with fail-fast disabled. Both run through `task --exit-code validate -- ` and treat compiler warnings as errors. The `test` job also checks formatting, runs lint, and builds. Failed jobs upload retained validation logs, summaries, and result bundles for seven days. Read the uploaded `summary.txt` and `test-summary.json` first; test output is retained in `raw.log`. For test stages, the workflow uses the local `xcrun xcresulttool get test-results summary` and system `plutil` to read test counts on a best-effort basis; it adds no scripts or tool dependencies. `test-summary.json` stores the raw summary, `test-summary.stderr.log` stores xcresulttool errors, and `count-reader.log` stores count-reading errors. The summary shows passed, failed, skipped, expected-failure, and total counts using Xcode's summary semantics; parameterized tests may have a different actual execution count. Stage and overall exit codes come from the original command, and a failed command always remains a failure. A missing result bundle or unreadable summary is marked `evidence incomplete`, with counts shown as unknown. This does not change the command result, and missing counts are never reported as zero. Build stages do not read test counts; a stage that did not run is not the same as a skipped test. @@ -40,14 +40,12 @@ task format:check # Check formatting without modifying source files. task lint task lint:fix # Use for automatic SwiftLint fixes; run task lint afterward. task gen:prj # Generate the Xcode project. -task build # Build the Debug app. -task test # Run unit tests (without real-process smoke tests). -task test STRICT=true # Treat Swift and Clang compiler warnings as errors. -task build STRICT=true # Build the Debug app with the same strict policy. +task build # Build the Debug app; compiler warnings are errors. +task test # Run unit tests; compiler warnings are errors. task test:smoke # Run real-process smoke tests (launches real sslocal; see the release gate in the signing and distribution guide). ``` -`STRICT=true` enables `SWIFT_TREAT_WARNINGS_AS_ERRORS=YES` and `GCC_TREAT_WARNINGS_AS_ERRORS=YES` for `test` and `build`. It also sets `SWIFT_SUPPRESS_WARNINGS=NO` to avoid conflicting Swift compiler options in package dependencies, whose warnings are checked too. It is opt-in; omitted or `STRICT=false` preserves the project's warning policy. The validation wrapper forwards this option: `task --exit-code validate STRICT=true -- test build`. Diagnostics explicitly suppressed with `@diagnose` remain suppressed. Xcode tool messages, such as AppIntents metadata warnings, are outside this compiler policy. +All check, build, and test tasks use strict options directly. `lint` and `lint:fix` use SwiftLint's `--strict`, so warnings fail those tasks. `test`, `test:smoke`, `build`, and `build:release`, including calls from `package`, set `SWIFT_TREAT_WARNINGS_AS_ERRORS=YES` and `GCC_TREAT_WARNINGS_AS_ERRORS=YES`. They also set `SWIFT_SUPPRESS_WARNINGS=NO` to avoid conflicting Swift compiler options in package dependencies, whose warnings are checked too. `format:check` uses `swift format lint --strict`. These options cannot be disabled through a Taskfile variable. Diagnostics explicitly suppressed with `@diagnose` remain suppressed. Xcode tool messages, such as AppIntents metadata warnings, are outside this compiler policy. `task format` formats Swift files under `App/`, `Tests/`, `Domain/`, and `Agent/`. `task format:check` runs the same configuration in strict, read-only mode. `task lint:fix` modifies source files; inspect and review the diff afterward.