name: CI
on:
pull_request:
branches: [main]
push:
branches: [main, develop]
permissions:
contents: read
actions: read
security-events: write
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
code_quality:
name: Code Quality
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-quality-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-quality-
${{ runner.os }}-cargo-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Check documentation
run: cargo doc --all-features --no-deps --document-private-items
env:
RUSTDOCFLAGS: "-D warnings"
test:
name: Test - ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
strategy:
matrix:
platform:
- name: Linux-x86_64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
rust: stable
cross_compile: false
- name: Linux-x86_64-beta
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
rust: beta
cross_compile: false
- name: Windows-x86_64
os: windows-latest
target: x86_64-pc-windows-msvc
rust: stable
cross_compile: false
- name: macOS-x86_64
os: macos-latest
target: x86_64-apple-darwin
rust: stable
cross_compile: false
- name: Linux-ARM64
os: ubuntu-latest
target: aarch64-unknown-linux-gnu
rust: stable
cross_compile: true
- name: Linux-musl
os: ubuntu-latest
target: x86_64-unknown-linux-musl
rust: stable
cross_compile: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install cross-compilation dependencies
if: matrix.platform.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
- name: Install musl tools
if: matrix.platform.target == 'x86_64-unknown-linux-musl'
run: |
sudo apt-get update
sudo apt-get install -y musl-tools
- name: Run tests and build (native)
if: matrix.platform.cross_compile == false
uses: houseabsolute/actions-rust-cross@v1
with:
command: both
target: ${{ matrix.platform.target }}
toolchain: ${{ matrix.platform.rust }}
args: "--locked --all-features"
use-rust-cache: true
- name: Build only (cross-compilation)
if: matrix.platform.cross_compile == true
uses: houseabsolute/actions-rust-cross@v1
with:
command: build
target: ${{ matrix.platform.target }}
toolchain: ${{ matrix.platform.rust }}
args: "--locked --all-features"
use-rust-cache: true
build-check:
name: Build Check
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: macos-latest
target: x86_64-apple-darwin
- os: windows-latest
target: x86_64-pc-windows-msvc
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-build-
${{ runner.os }}-cargo-
- name: Build verification (native target)
run: cargo build --release
security_audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run security audit
uses: rustsec/audit-check@v2.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
msrv:
name: MSRV
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-msrv-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-msrv-
${{ runner.os }}-cargo-
- name: Check MSRV
run: cargo check --all-features
release_plz_config_check:
name: Release-plz Config Validation
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha || github.head_ref }}
- name: Debug PR information
run: |
echo "π Debugging PR and checkout information..."
echo "Event name: ${{ github.event_name }}"
echo "Repository: ${{ github.repository }}"
echo "Head ref: ${{ github.head_ref }}"
echo "Base ref: ${{ github.base_ref }}"
echo "PR number: ${{ github.event.number }}"
echo "PR head SHA: ${{ github.event.pull_request.head.sha }}"
echo "PR head ref: ${{ github.event.pull_request.head.ref }}"
echo "PR head repo: ${{ github.event.pull_request.head.repo.full_name }}"
echo "PR base repo: ${{ github.event.pull_request.base.repo.full_name }}"
echo "Current SHA: ${{ github.sha }}"
echo ""
echo "π Current working directory contents:"
ls -la
echo ""
echo "πΏ Git branch information:"
git branch -a || echo "Git branch command failed"
echo ""
echo "π Git log (last 3 commits):"
git log --oneline -3 || echo "Git log command failed"
- name: Validate GitHub Token
run: |
echo "π Validating GitHub Token configuration..."
echo ""
# Check if RELEASE_PLZ_TOKEN is available (we can't access the actual value for security)
if [ -n "${{ secrets.RELEASE_PLZ_TOKEN }}" ]; then
echo "β
RELEASE_PLZ_TOKEN is configured"
TOKEN_SOURCE="RELEASE_PLZ_TOKEN"
else
echo "β οΈ RELEASE_PLZ_TOKEN not found, will use GITHUB_TOKEN"
TOKEN_SOURCE="GITHUB_TOKEN"
fi
# Test token format validation logic (using GITHUB_TOKEN as it's always available)
TEST_TOKEN="${{ secrets.GITHUB_TOKEN }}"
# Basic token format validation
if [[ "$TEST_TOKEN" =~ ^(ghp_|gho_|ghu_|ghs_|ghr_|github_pat_) ]]; then
echo "β
Token format validation logic works correctly"
else
echo "β Token format validation failed - this may indicate an issue"
exit 1
fi
# Test API connectivity with GITHUB_TOKEN
echo "π Testing GitHub API connectivity..."
curl -s -H "Authorization: Bearer $TEST_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/user > /dev/null || {
echo "β GitHub API connectivity test failed"
exit 1
}
echo "β
GitHub API connectivity test passed"
echo "π― Token validation will use: $TOKEN_SOURCE"
- name: Validate release-plz configuration file
run: |
echo "π§ Validating release-plz configuration..."
echo ""
# Check if config file exists
if [ -f "release-plz.toml" ]; then
echo "β
release-plz.toml found"
else
echo "β release-plz.toml not found"
exit 1
fi
# Validate TOML syntax
echo "π§ͺ Checking TOML syntax..."
if command -v toml-cli &> /dev/null; then
toml-cli get release-plz.toml . > /dev/null || {
echo "β Invalid TOML syntax in release-plz.toml"
exit 1
}
else
# Basic syntax check using Python (available in GitHub runners)
python3 -c "
import tomllib
try:
with open('release-plz.toml', 'rb') as f:
tomllib.load(f)
print('β
TOML syntax is valid')
except Exception as e:
print(f'β TOML syntax error: {e}')
exit(1)
" || exit 1
fi
echo ""
echo "β
Release-plz configuration validation completed!"
echo "π Configuration file exists and has valid TOML syntax."
echo "π― The workflow should work correctly when merged to main."
publish_simulation:
name: Publish Simulation
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-publish-sim-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-publish-sim-
${{ runner.os }}-cargo-
- name: Simulate package publishing
run: |
echo "π Simulating package publishing to detect dependency issues..."
echo ""
# Test packaging for key crates that have external dependencies
# Note: vx-cli temporarily excluded due to vx-paths dependency (new crate not yet published)
CRATES_TO_TEST=(
"vx-tool-standard"
"vx-tool-node"
"vx-tool-go"
"vx-tool-rust"
"vx-tool-uv"
"vx"
)
for crate in "${CRATES_TO_TEST[@]}"; do
echo "π¦ Testing package: $crate"
if cargo package -p "$crate" --allow-dirty --no-verify; then
echo "β
$crate packages successfully"
else
echo "β $crate packaging failed"
exit 1
fi
echo ""
done
echo "π All packages can be built for publishing!"
echo "π‘ This ensures dependencies are correctly specified for crates.io"
coverage:
name: Code Coverage
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-coverage-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-coverage-
${{ runner.os }}-cargo-
- name: Generate code coverage
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
fail_ci_if_error: false verbose: true
flags: unittests
name: codecov-umbrella