Files
ShadowsocksX-NG/ShadowsocksX-NG2/Taskfile.dist.yml

233 lines
9.5 KiB
YAML

# https://taskfile.dev/
version: '3'
includes:
packaging:
taskfile: ./Taskfile.package.yml
flatten: true
publishing:
taskfile: ./Taskfile.publish.yml
flatten: true
vars:
PROJECT_NAME: "ShadowsocksX-NG2"
BUILD_DIR: "{{ .TASKFILE_DIR }}/.build"
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:
desc: 'Run validation gates in order and retain logs/results; stop on first failure'
dir: '{{.TASKFILE_DIR}}'
silent: true
vars:
GATES: '{{default "lint test build" .CLI_ARGS | trim}}'
RUN_DIR:
sh: |
mkdir -p {{.BUILD_DIR | shellQuote}}/validation
mktemp -d {{.BUILD_DIR | shellQuote}}/validation/$(date -u +%Y%m%dT%H%M%SZ)-XXXXXX
preconditions:
- sh: '{{if regexMatch "^(format:check|lint|test|test:smoke|build)( (format:check|lint|test|test:smoke|build))*$" .GATES}}true{{else}}false{{end}}'
msg: 'Choose validation gates: format:check, lint, test, test:smoke, build (space separated).'
- sh: '{{if eq (len (splitList " " .GATES)) (len (uniq (splitList " " .GATES)))}}true{{else}}false{{end}}'
msg: 'Choose each validation gate at most once.'
cmds:
- defer:
task: validate:summary
vars:
RUN_DIR: '{{.RUN_DIR}}'
GATES: '{{.GATES}}'
CODE: '{{default "0" .EXIT_CODE}}'
- "printf '%s\n' {{printf \"Validation results: %s\" .RUN_DIR | shellQuote}}"
- for: {var: GATES, split: ' '}
task: validate:gate
vars:
RUN_DIR: '{{.RUN_DIR}}'
GATE: '{{.ITEM}}'
validate:gate:
internal: true
dir: '{{.TASKFILE_DIR}}'
silent: true
vars:
GATE_DIR: '{{.RUN_DIR}}/{{.GATE | replace ":" "-"}}'
cmds:
- mkdir -p {{.GATE_DIR | shellQuote}}
- defer:
task: validate:result
vars:
GATE: '{{.GATE}}'
GATE_DIR: '{{.GATE_DIR}}'
CODE: '{{default "0" .EXIT_CODE}}'
- "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
validate:result:
internal: true
silent: true
cmds:
- |
status=failed
if [ {{.CODE | shellQuote}} = 0 ]; then status=passed; fi
echo "[{{.GATE}}] $status; exit={{.CODE}}" > {{.GATE_DIR | shellQuote}}/status.txt
- cmd: |
{{if and (ne .GATE "lint") (ne .GATE "format:check")}}
if [ ! -d {{.GATE_DIR | shellQuote}}/result.xcresult ]; then
echo '[{{.GATE}}] evidence incomplete: result bundle missing; test counts unknown' >> {{.GATE_DIR | shellQuote}}/status.txt
{{if ne .GATE "build"}}
elif xcrun xcresulttool get test-results summary --path {{.GATE_DIR | shellQuote}}/result.xcresult > {{.GATE_DIR | shellQuote}}/test-summary.json 2> {{.GATE_DIR | shellQuote}}/test-summary.stderr.log; then
if passed=$(plutil -extract passedTests raw -expect integer {{.GATE_DIR | shellQuote}}/test-summary.json) &&
failed=$(plutil -extract failedTests raw -expect integer {{.GATE_DIR | shellQuote}}/test-summary.json) &&
skipped=$(plutil -extract skippedTests raw -expect integer {{.GATE_DIR | shellQuote}}/test-summary.json) &&
expected=$(plutil -extract expectedFailures raw -expect integer {{.GATE_DIR | shellQuote}}/test-summary.json) &&
total=$(plutil -extract totalTestCount raw -expect integer {{.GATE_DIR | shellQuote}}/test-summary.json); then
echo "[{{.GATE}}] tests: passed=$passed failed=$failed skipped=$skipped expectedFailures=$expected total=$total" >> {{.GATE_DIR | shellQuote}}/status.txt
else
printf '%s\n' "$passed" "$failed" "$skipped" "$expected" "$total" >> {{.GATE_DIR | shellQuote}}/count-reader.log
echo '[{{.GATE}}] evidence incomplete: invalid test summary; test counts unknown (see count-reader.log)' >> {{.GATE_DIR | shellQuote}}/status.txt
fi 2> {{.GATE_DIR | shellQuote}}/count-reader.log
else
echo '[{{.GATE}}] evidence incomplete: xcresulttool failed; test counts unknown (see test-summary.stderr.log)' >> {{.GATE_DIR | shellQuote}}/status.txt
{{end}}
fi
{{end}}
- cat {{.GATE_DIR | shellQuote}}/status.txt
validate:summary:
internal: true
silent: true
cmds:
- |
echo 'Validation command exit={{.CODE}}' > {{.RUN_DIR | shellQuote}}/summary.txt
echo 'Selected gates: {{.GATES}}' >> {{.RUN_DIR | shellQuote}}/summary.txt
- for: {var: GATES, split: ' '}
cmd: |
if [ -f {{.RUN_DIR | shellQuote}}/{{.ITEM | replace ":" "-"}}/status.txt ]; then
cat {{.RUN_DIR | shellQuote}}/{{.ITEM | replace ":" "-"}}/status.txt >> {{.RUN_DIR | shellQuote}}/summary.txt
else
echo '[{{.ITEM}}] not_run' >> {{.RUN_DIR | shellQuote}}/summary.txt
fi
- cat {{.RUN_DIR | shellQuote}}/summary.txt
- "printf '%s\n' {{printf \"Summary: %s/summary.txt\" .RUN_DIR | shellQuote}}"
gen:prj:
desc: 'Generate xcode project by xcodegen'
cmds:
- xcodegen generate
build:
desc: Build the ShadowsocksX-NG2 macOS application with Debug Config
deps:
- gen:prj
cmds:
- >-
xcodebuild
-project ShadowsocksX-NG2.xcodeproj
-scheme ShadowsocksX-NG2
-configuration Debug
-destination 'platform=macOS,arch=arm64'
-derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}}
{{if .RESULT_BUNDLE_PATH}}-resultBundlePath {{.RESULT_BUNDLE_PATH | shellQuote}}{{end}}
{{.STRICT_BUILD_ARGS}}
build
build:release:
desc: Build the ShadowsocksX-NG2 macOS application with Release Config
requires:
vars: [MARKETING_VERSION, CURRENT_PROJECT_VERSION]
vars:
BUNDLE_MARKETING_VERSION: '{{regexFind "[0-9]+\\.[0-9]+\\.[0-9]+" (default "" .MARKETING_VERSION)}}'
preconditions:
- sh: '{{if regexMatch .RELEASE_VERSION_PATTERN .MARKETING_VERSION}}true{{else}}false{{end}}'
msg: 'MARKETING_VERSION must be a release version (for example, 2.1.0 or v2.0.0-alpha-1).'
- sh: '{{if regexMatch "^[0-9]+(\\.[0-9]+){0,2}$" .CURRENT_PROJECT_VERSION}}true{{else}}false{{end}}'
msg: 'CURRENT_PROJECT_VERSION must have one to three numeric components.'
cmds:
- task: gen:prj
- >-
xcodebuild
-project ShadowsocksX-NG2.xcodeproj
-scheme ShadowsocksX-NG2
-configuration Release
-destination 'platform=macOS,arch=arm64'
-derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}}
{{printf "MARKETING_VERSION=%s" .BUNDLE_MARKETING_VERSION | shellQuote}}
{{printf "CURRENT_PROJECT_VERSION=%s" .CURRENT_PROJECT_VERSION | shellQuote}}
build
format:
desc: 'Format the code by swift-format'
cmds:
- swift format format --in-place --recursive --configuration .swift-format App Tests Domain Agent
format:check:
desc: 'Check Swift formatting without modifying files'
cmds:
- swift format lint --strict --recursive --configuration .swift-format App Tests Domain Agent
lint:
desc: 'Lint the swift code by swiftlint'
cmds:
- swiftlint lint --config .swiftlint.yml --no-cache
lint:fix:
desc: 'Automatically fix SwiftLint violations'
cmds:
- swiftlint lint --fix --config .swiftlint.yml --no-cache
test:
desc: 'Run conversion and unit tests'
deps:
- gen:prj
cmds:
- task: test:binaries
- task: test:rules
- >-
xcodebuild
-project ShadowsocksX-NG2.xcodeproj
-scheme ShadowsocksX-NG2
-destination 'platform=macOS,arch=arm64'
-derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}}
{{if .RESULT_BUNDLE_PATH}}-resultBundlePath {{.RESULT_BUNDLE_PATH | shellQuote}}{{end}}
{{.TEST_TIMEOUT_ARGS}}
{{.STRICT_BUILD_ARGS}}
test
test:binaries:
desc: 'Verify pinned external binary downloads with local assets'
cmds:
- PYTHONDONTWRITEBYTECODE=1 python3 Scripts/test-external-binary-fetch.py
test:rules:
desc: 'Run offline rule conversion and generated fixture checks'
cmds:
- PYTHONDONTWRITEBYTECODE=1 python3 Scripts/test-rule-snapshot-converters.py
- PYTHONDONTWRITEBYTECODE=1 python3 Scripts/test-rule-conversion-behavior.py
test:smoke:
desc: 'Run real-process smoke tests (real sslocal; release gate)'
deps:
- gen:prj
cmds:
- >-
xcodebuild
-project ShadowsocksX-NG2.xcodeproj
-scheme ShadowsocksX-NG2Smoke
-destination 'platform=macOS,arch=arm64'
-derivedDataPath {{.DERIVED_DATA_DIR | shellQuote}}
{{if .RESULT_BUNDLE_PATH}}-resultBundlePath {{.RESULT_BUNDLE_PATH | shellQuote}}{{end}}
{{.TEST_TIMEOUT_ARGS}}
{{.STRICT_BUILD_ARGS}}
test
clean:
cmds:
- rm -rf {{ .BUILD_DIR }}