Docs
CI / GitHub Actions
Gate pull requests with proa check, then deploy from the same pipeline.
Use proa check as the default pull-request gate. It runs proa fmt --check --verify and proa lint, then fails on formatting differences, errors, or warnings. With explicit paths or Git-selected files it stays source-only; a whole-project proa check with no paths also runs the linked RSJS Cargo check.
Install a checksum-verified CLI binary before running the gate. There are two
download flows. The current prebuilt target is 64-bit Ubuntu 24.04+
(x86_64-unknown-linux-gnu); use a source build with repository access on
other runners.
Latest CLI From main
Inspect the exact commit-qualified snapshot and its available archives:
curl -fsSL https://proa.so/downloads/cli/main/latest.json | \
jq '{version, commit, assets}'
Install whatever that JSON document currently names. Leave PROA_VERSION
unset so the installer resolves it from the main channel:
curl -fsSL https://proa.so/install.sh | \
PROA_DOWNLOAD_BASE=https://proa.so/downloads/cli/main \
PROA_PREBUILT_ONLY=1 \
PROA_YES=1 sh
A Specific Published CLI Version
The stable metadata names the current published version and every archive that is available for it:
curl -fsSL https://proa.so/downloads/cli/latest.json | \
jq '{version, assets}'
Choose a published version from that metadata or your release policy, then pin
it. Versioned stable routes remain available after latest.json advances:
PROA_CLI_VERSION="<published-version>"
curl -fsSL https://proa.so/install.sh | \
PROA_VERSION="$PROA_CLI_VERSION" \
PROA_PREBUILT_ONLY=1 \
PROA_YES=1 sh
PROA_PREBUILT_ONLY=1 makes missing metadata or archives fail immediately
instead of silently recompiling the workspace. Add
$HOME/.proa/bin to PATH, or set PROA_INSTALL_DIR in CI as shown below.
To build it from source instead:
CARGO_NET_GIT_FETCH_WITH_CLI=true \
cargo install --git https://github.com/proa-labs/proa --locked proa-cli
Then confirm CI can resolve the binary:
proa --help
Minimal Gate
cargo fmt --all --check
proa test
proa check src
cargo fmt keeps Rust syntax stable. proa test runs the application suite through the linked pipeline, which is what the generated CI workflow does; a plain cargo test binary that links RSJS islands fails at link time by design (see Testing). In a workspace with several targets, name one with -p my_app --bin my_app or --test <name>. proa check keeps template macro bodies canonical and catches Proa-specific render, accessibility, composition, performance, and RSJS issues.
GitHub Actions
Start with a full gate on every pull request. Create a repository or
organization variable named PROA_CLI_VERSION and set it to an already
published stable CLI version:
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install Proa CLI
env:
PROA_VERSION: ${{ vars.PROA_CLI_VERSION }}
PROA_INSTALL_DIR: ${{ runner.temp }}/proa-bin
PROA_NO_MODIFY_PATH: "1"
PROA_PREBUILT_ONLY: "1"
PROA_TAILWIND: skip
PROA_YES: "1"
run: |
set -euo pipefail
: "${PROA_VERSION:?set the PROA_CLI_VERSION repository variable to a published CLI version}"
curl --proto '=https' --proto-redir '=https' --tlsv1.2 -fsSL https://proa.so/install.sh | sh
echo "$PROA_INSTALL_DIR" >> "$GITHUB_PATH"
- name: Rust checks
run: |
cargo fmt --all --check
proa test
- name: Proa checks
run: proa check src
While the Proa source repository is private, Cargo needs a GitHub token with read access to fetch it. Generated sites already include a scoped Git credential helper for their test and release-build steps: set the PROA_GITHUB_TOKEN Actions secret in the application repository. This is a GitHub credential, not a Cargo registry token. Installation covers local access requirements.
Changed Files
For faster pull-request checks, run against changed files:
proa check --changed --base origin/main
For pre-commit hooks, run against staged files:
proa check --staged
If no changed Rust files are selected, check succeeds without scanning. Do not combine explicit paths with --changed, --staged, or --base; Git-selected mode owns the file list.
In GitHub Actions, changed-file mode needs enough history to diff against the base ref:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Proa changed-file check
run: proa check --changed --base origin/main
GitHub Annotations
proa check is intentionally concise. Use proa lint --github when you want inline GitHub Actions annotations:
proa fmt --check --verify src
proa lint --github --deny-warnings src
For a changed-file workflow:
proa fmt --check --verify src
proa lint --github --deny-warnings --changed --base origin/main
lint --github emits error, warning, and notice annotations. JSON and GitHub output include info-level diagnostics by default. Use this mode when reviewers need inline file comments; use proa check when you want a shorter pass/fail log.
JSON Diagnostics
Use JSON when integrating with editor tooling or custom CI summaries:
proa lint --json --min-severity info src > proa-lint.json
proa chunks --json src > proa-chunks.json
proa site check --json > proa-site-check.json
The JSON shape includes the path, line, column, severity, diagnostic code, message, and optional help text. That makes it stable enough for custom PR summaries or agent workflows.
Monorepos
Run Proa checks close to the Rust render code. For a workspace with multiple apps, prefer explicit paths:
proa check apps/marketing/src apps/admin/src crates/ui/src
If each app owns its own generated docs or static routes, include site check for each app root:
proa site check --root apps/marketing
proa site check --root apps/docs
Failure Triage
When CI fails, use the narrow command first:
| Failure | Local command |
|---|---|
| Macro formatting differs | proa fmt src |
| Verify mode says formatting changed structure | proa fmt --check --verify src |
| Lint failed without enough detail | proa lint --min-severity info src |
| GitHub annotations are noisy | proa lint --github --min-severity warning src |
| Site structure failed | proa site check --json |
Keep the full gate on the branch that deploys. Use changed-file mode for fast feedback, not as the only production release check.
Docker
For Docker builds, pass the GitHub token as a build secret so Cargo can fetch Proa's git dependencies:
# syntax=docker/dockerfile:1.7
FROM rust:1.93 AS builder
WORKDIR /app
COPY . .
# Fetch Proa git dependencies through the git CLI. While the Proa repository
# is private, pass a GitHub token with read access as Docker secret
# `github_token`; drop the secret once the repository is public.
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
RUN --mount=type=secret,id=github_token \
set -eu; \
export GIT_CONFIG_COUNT=1; \
export GIT_CONFIG_KEY_0=credential.https://github.com.helper; \
export GIT_CONFIG_VALUE_0='!f() { if [ "$1" = get ] && [ -s /run/secrets/github_token ]; then printf "username=x-access-token\npassword=%s\n" "$(cat /run/secrets/github_token)"; fi; }; f'; \
proa build --locked --artifact-out /tmp/proa-app
proa build runs the linked RSJS pipeline and the configured asset build, then exports the binary and its assets to the --artifact-out directory; a plain cargo build --release skips the asset build and fails at link time on any crate with islands. The Dockerfile that proa new site --deploy docker writes uses the same command.
Build with:
docker build --secret id=github_token,env=GITHUB_TOKEN .
Security: The credential helper reads the BuildKit secret without writing its value into Git configuration, and multi-stage builds keep build tooling and sources out of the final image. The example above uses
AS builder, add a secondFROMstage that copies only the compiled binary. Docker shows the full multi-stage build.
Other CI Systems
The pattern is the same for any CI:
- Install a checksum-verified CLI binary (or build it from source) as shown above
- While the Proa repository is private, store a GitHub token with read access as a secret, set
CARGO_NET_GIT_FETCH_WITH_CLI=true, and configure git to authenticate with it for all cargo commands - Run the gate:
cargo fmt --all --check,proa test,proa check src
Next steps
- proa fmt / lint / check
- Format macro bodies, run lints, and gate CI.
- Deploy
- Pick a deployment target, then follow the guide for it.
- Testing
- Test Proa components with unit, snapshot, accessibility, and benchmark suites.
- Docker
- Run the Proa image yourself, and own everything a platform would have done.