name: CI
on:
push:
branches:
- main
pull_request:
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
jobs:
fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all -- --check
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets --all-features -- -D warnings
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --all-features
e2e:
name: E2E Tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install cctr
uses: taiki-e/install-action@v2
with:
tool: cctr
- name: Build
run: cargo build --release
- name: Install Playwright
run: npm install -g playwright@1.56.1 ws && npx playwright install --with-deps chromium
- name: Add to PATH
run: echo "$PWD/target/release" >> $GITHUB_PATH
- name: Run e2e tests
run: cctr test/e2e
check-release:
name: Check Release
runs-on: ubuntu-latest
needs: [fmt, clippy, test, e2e]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
outputs:
should_release: ${{ steps.check.outputs.should_release }}
version: ${{ steps.check.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check if release needed
id: check
run: |
VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "Tag v$VERSION already exists"
echo "should_release=false" >> $GITHUB_OUTPUT
else
echo "Tag v$VERSION does not exist, will release"
echo "should_release=true" >> $GITHUB_OUTPUT
fi
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: check-release
if: needs.check-release.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- name: Create and push tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "v${{ needs.check-release.outputs.version }}" -m "Release v${{ needs.check-release.outputs.version }}"
git push origin "v${{ needs.check-release.outputs.version }}"
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "v${{ needs.check-release.outputs.version }}" \
--title "v${{ needs.check-release.outputs.version }}" \
--notes "Release v${{ needs.check-release.outputs.version }}" \
--draft
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
needs: [check-release, create-release]
if: needs.check-release.outputs.should_release == 'true'
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
features: vendored-openssl
- target: x86_64-unknown-linux-musl
os: ubuntu-latest
features: vendored-openssl
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
features: vendored-openssl
- target: aarch64-unknown-linux-musl
os: ubuntu-latest
features: vendored-openssl
- target: x86_64-apple-darwin
os: macos-latest
- target: aarch64-apple-darwin
os: macos-latest
steps:
- uses: actions/checkout@v4
with:
ref: v${{ needs.check-release.outputs.version }}
- uses: taiki-e/upload-rust-binary-action@v1
env:
PLAYWRIGHT_DRIVER_VERSION: "1.56.1"
with:
bin: plwr
target: ${{ matrix.target }}
features: ${{ matrix.features || '' }}
archive: plwr-v${{ needs.check-release.outputs.version }}-${{ matrix.target }}
ref: refs/tags/v${{ needs.check-release.outputs.version }}
token: ${{ secrets.GITHUB_TOKEN }}
publish:
name: Publish to crates.io
runs-on: ubuntu-latest
needs: [check-release, create-release]
if: needs.check-release.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
run: |
cargo generate-lockfile
cargo publish --no-verify --allow-dirty
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
release:
name: Update GitHub Release
runs-on: ubuntu-latest
needs: [check-release, build, publish]
if: needs.check-release.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- name: Publish Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cat > release_notes.md << 'EOF'
## Installation
```bash
# Via Homebrew (macOS/Linux)
brew install andreasjansson/tap/plwr
```
Requires Playwright: `npm install -g playwright && npx playwright install chromium`
## Binaries
Pre-built binaries are available for Linux and macOS (x86_64 and ARM64).
EOF
gh release edit "v${{ needs.check-release.outputs.version }}" \
--notes-file release_notes.md \
--latest \
--draft=false
homebrew:
name: Update Homebrew
runs-on: ubuntu-latest
needs: [check-release, release]
if: needs.check-release.outputs.should_release == 'true'
steps:
- name: Download and hash binaries
id: hashes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ needs.check-release.outputs.version }}"
BASE="https://github.com/andreasjansson/plwr/releases/download/v${VERSION}"
for target in x86_64-apple-darwin aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
FILE="plwr-v${VERSION}-${target}.tar.gz"
curl -sL "${BASE}/${FILE}" -o "${FILE}"
SHA=$(sha256sum "${FILE}" | cut -d' ' -f1)
NAME=$(echo "$target" | tr '-' '_')
echo "${NAME}=${SHA}" >> $GITHUB_OUTPUT
done
- name: Update Homebrew formula
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
run: |
VERSION="${{ needs.check-release.outputs.version }}"
cat > plwr.rb << EOF
class Plwr < Formula
desc "Clean CLI for Playwright browser automation with CSS selectors"
homepage "https://github.com/andreasjansson/plwr"
version "${VERSION}"
license "MIT"
on_macos do
on_intel do
url "https://github.com/andreasjansson/plwr/releases/download/v${VERSION}/plwr-v${VERSION}-x86_64-apple-darwin.tar.gz"
sha256 "${{ steps.hashes.outputs.x86_64_apple_darwin }}"
end
on_arm do
url "https://github.com/andreasjansson/plwr/releases/download/v${VERSION}/plwr-v${VERSION}-aarch64-apple-darwin.tar.gz"
sha256 "${{ steps.hashes.outputs.aarch64_apple_darwin }}"
end
end
on_linux do
on_intel do
url "https://github.com/andreasjansson/plwr/releases/download/v${VERSION}/plwr-v${VERSION}-x86_64-unknown-linux-gnu.tar.gz"
sha256 "${{ steps.hashes.outputs.x86_64_unknown_linux_gnu }}"
end
on_arm do
url "https://github.com/andreasjansson/plwr/releases/download/v${VERSION}/plwr-v${VERSION}-aarch64-unknown-linux-gnu.tar.gz"
sha256 "${{ steps.hashes.outputs.aarch64_unknown_linux_gnu }}"
end
end
def install
bin.install "plwr"
end
test do
assert_match version.to_s, shell_output("#{bin}/plwr --version")
end
end
EOF
git clone https://x-access-token:${GH_TOKEN}@github.com/andreasjansson/homebrew-tap.git
cp plwr.rb homebrew-tap/Formula/plwr.rb
cd homebrew-tap
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Formula/plwr.rb
git commit -m "Update plwr to ${VERSION}"
git push
smoke-test-macos:
name: Smoke Test (macOS/Homebrew)
runs-on: macos-latest
needs: [check-release, homebrew]
if: needs.check-release.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- name: Install plwr via Homebrew
run: brew install andreasjansson/tap/plwr
- name: Verify version
run: |
plwr --version
plwr --version | grep -q "${{ needs.check-release.outputs.version }}"
- name: Install cctr
uses: taiki-e/install-action@v2
with:
tool: cctr
- name: Install Playwright
run: npm install -g playwright@1.56.1 && npx playwright install --with-deps chromium
- name: Run e2e tests
run: cctr test/e2e
smoke-test-linux:
name: Smoke Test (Linux/GitHub Release)
runs-on: ubuntu-latest
needs: [check-release, homebrew]
if: needs.check-release.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v4
- name: Install plwr from GitHub Release
run: |
curl -L "https://github.com/andreasjansson/plwr/releases/download/v${{ needs.check-release.outputs.version }}/plwr-v${{ needs.check-release.outputs.version }}-x86_64-unknown-linux-gnu.tar.gz" | tar xz
sudo mv plwr /usr/local/bin/
- name: Verify version
run: |
plwr --version
plwr --version | grep -q "${{ needs.check-release.outputs.version }}"
- name: Install cctr
uses: taiki-e/install-action@v2
with:
tool: cctr
- name: Install Playwright
run: npm install -g playwright@1.56.1 && npx playwright install --with-deps chromium
- name: Run e2e tests
run: cctr test/e2e