release: v2.0.1 #95
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] | |
| pull_request: | |
| permissions: | |
| contents: read | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true' | |
| jobs: | |
| changes: | |
| name: Change detection | |
| runs-on: ubuntu-latest | |
| outputs: | |
| relevant: ${{ steps.filter.outputs.relevant }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - id: filter | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| base="${{ github.event.pull_request.base.sha }}" | |
| head="${{ github.sha }}" | |
| else | |
| base="${{ github.event.before }}" | |
| head="${{ github.sha }}" | |
| fi | |
| if [[ "$base" =~ ^0+$ ]]; then | |
| echo "relevant=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| relevant=false | |
| while IFS= read -r path; do | |
| case "$path" in | |
| *.md|docs/*|AGENTS.md|LICENSE|NOTICE) ;; | |
| *) relevant=true ;; | |
| esac | |
| done < <(git diff --name-only "$base" "$head") | |
| echo "relevant=$relevant" >> "$GITHUB_OUTPUT" | |
| ts: | |
| name: TypeScript engine + conformance | |
| runs-on: ubuntu-latest | |
| needs: changes | |
| if: needs.changes.outputs.relevant == 'true' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: pnpm/action-setup@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| - run: pnpm install --frozen-lockfile | |
| - run: pnpm build | |
| - name: Verify generated catalog matches checked-in catalog | |
| run: | | |
| pnpm build:catalog | |
| git diff --exit-code \ | |
| catalog/adguard.json \ | |
| catalog/brave.json \ | |
| catalog/catalog.json \ | |
| catalog/clearurls.json \ | |
| catalog/firefox.json \ | |
| crates/url-sanitize/catalog/catalog.json \ | |
| || (echo "generated catalog files are stale — run \`pnpm build:catalog\` and commit" && exit 1) | |
| - name: Verify generated conformance corpus matches checked-in files | |
| run: | | |
| pnpm build:conformance | |
| git diff --exit-code conformance/vectors.jsonl conformance/clearurls-corpus.jsonl conformance/manifest.json \ | |
| || (echo "conformance corpus is stale — run \`pnpm build:conformance\` and commit" && exit 1) | |
| - run: pnpm typecheck | |
| - run: pnpm test | |
| - run: pnpm lint | |
| rust: | |
| name: Rust engine + conformance | |
| runs-on: ubuntu-latest | |
| needs: changes | |
| if: needs.changes.outputs.relevant == 'true' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - run: cargo fmt --all --check | |
| - run: cargo build --workspace --all-targets | |
| - run: cargo clippy --workspace --all-targets -- -D warnings | |
| - run: cargo test --workspace | |
| - run: cargo package -p url-sanitize-core --allow-dirty | |
| - name: Package url-sanitize archive when core dependency is published | |
| run: | | |
| version="$(python3 -c 'import json, subprocess; data=json.loads(subprocess.check_output(["cargo", "metadata", "--no-deps", "--format-version=1"])); print(next(p["version"] for p in data["packages"] if p["name"] == "url-sanitize-core"))')" | |
| if curl -fsSA "url-sanitize-ci" "https://crates.io/api/v1/crates/url-sanitize-core/${version}" >/dev/null; then | |
| cargo package -p url-sanitize --allow-dirty | |
| else | |
| echo "url-sanitize-core ${version} is not on crates.io yet; skipping dependent package verification" | |
| fi | |
| - name: Release binary size check | |
| run: | | |
| cargo build --release -p url-sanitize | |
| ls -lh target/release/url-sanitize | |
| size=$(stat -c%s target/release/url-sanitize) | |
| echo "release binary size: $size bytes" | |
| # M1 soft cap: 1.5 MB. M3 target: < 1 MB. | |
| test "$size" -lt 1572864 || (echo "binary exceeded 1.5 MB soft cap" && exit 1) | |
| smoke: | |
| name: Package smoke tests | |
| runs-on: ubuntu-latest | |
| needs: changes | |
| if: needs.changes.outputs.relevant == 'true' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: pnpm/action-setup@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| cache: 'pnpm' | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.9' | |
| - run: pnpm install --frozen-lockfile | |
| - run: pnpm smoke | |
| install-smoke: | |
| name: Installer smoke tests | |
| needs: changes | |
| if: needs.changes.outputs.relevant == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-14, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Validate install metadata | |
| if: runner.os == 'Linux' | |
| run: | | |
| set -euo pipefail | |
| jq -e '.version and .architecture["64bit"].url and .architecture["64bit"].hash and .bin and .checkver and .autoupdate' bucket/url-sanitize.json | |
| ruby -c Formula/url-sanitize.rb | |
| sh -n scripts/install.sh | |
| - name: Smoke Homebrew formula | |
| if: runner.os == 'macOS' | |
| run: | | |
| set -euo pipefail | |
| formula_version="$(ruby -e 'print File.read("Formula/url-sanitize.rb")[/version "([^"]+)"/, 1]')" | |
| brew tap-new local/url-sanitize | |
| cp Formula/url-sanitize.rb "$(brew --repository local/url-sanitize)/Formula/url-sanitize.rb" | |
| brew install local/url-sanitize/url-sanitize | |
| scripts/smoke-cli.sh "$(brew --prefix)/bin/url-sanitize" "$formula_version" | |
| - name: Smoke Linux installer | |
| if: runner.os == 'Linux' | |
| run: | | |
| set -euo pipefail | |
| install_dir="$RUNNER_TEMP/url-sanitize-bin" | |
| URL_SANITIZE_INSTALL_DIR="$install_dir" sh scripts/install.sh | |
| scripts/smoke-cli.sh "$install_dir/url-sanitize" | |
| - name: Smoke Windows installer | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $InstallDir = Join-Path $env:RUNNER_TEMP "url-sanitize-bin" | |
| $env:URL_SANITIZE_INSTALL_DIR = $InstallDir | |
| ./scripts/install.ps1 | |
| ./scripts/smoke-cli.ps1 -Command (Join-Path $InstallDir "url-sanitize.exe") | |
| - name: Smoke Scoop manifest | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $env:SCOOP = Join-Path $env:RUNNER_TEMP "scoop" | |
| $env:SCOOP_GLOBAL = Join-Path $env:RUNNER_TEMP "scoop-global" | |
| [Environment]::SetEnvironmentVariable("SCOOP", $env:SCOOP, "User") | |
| [Environment]::SetEnvironmentVariable("SCOOP_GLOBAL", $env:SCOOP_GLOBAL, "User") | |
| Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force | |
| Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression | |
| if ($LASTEXITCODE -ne 0) { | |
| exit $LASTEXITCODE | |
| } | |
| $env:Path = "$env:SCOOP\shims;$env:Path" | |
| scoop install .\bucket\url-sanitize.json | |
| ./scripts/smoke-cli.ps1 -Command "url-sanitize" |