Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
name: CI

on:
push:
branches: ["main", "phase-*"]
pull_request:
branches: ["main"]

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

jobs:
# ── Job 1: Local tests (all platforms) ────────────────────────────────────────
test-local:
name: Test (local) — ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]

steps:
- uses: actions/checkout@v4

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry + build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-

- name: Run local workspace tests
# atomic-py requires maturin; atomic-worker breaks non-Python link step.
# Distributed tests are marked #[ignore] and run in a separate job.
run: |
cargo test \
--workspace \
--exclude atomic-py \
--exclude atomic-worker \
-- --test-threads=4

# ── Job 2: Distributed tests (Linux only — spawns child processes) ─────────────
test-distributed:
name: Test (distributed)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry + build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ubuntu-distributed-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ubuntu-distributed-

# Build the integration binaries first so the test harness can spawn them.
- name: Build integration binaries (release)
run: cargo build --release -p atomic-engine

# Distributed tests spawn real worker + driver processes over TCP.
# They are marked #[ignore] so they don't run in the local job above.
# Sequential execution (--test-threads=1) is required: each test binds a
# fixed port and spawning multiple simultaneously causes port-reuse races.
- name: Run distributed integration tests
run: |
cargo test \
-p atomic-engine \
-- \
--test-threads=1 \
--ignored

# ── Job 3: Dependency audit ────────────────────────────────────────────────────
deny:
name: Dependency audit (cargo deny)
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable

- name: Install cargo-deny
run: cargo install cargo-deny --locked

- name: Run cargo deny
run: cargo deny check licenses bans advisories

# ── Job 4: Lint ───────────────────────────────────────────────────────────────
lint:
name: Lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust stable + rustfmt + clippy
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Cache cargo registry + build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ubuntu-lint-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ubuntu-lint-

- name: Check formatting
run: cargo fmt --all -- --check

- name: Run Clippy
run: |
cargo clippy \
--workspace \
--exclude atomic-py \
--exclude atomic-worker \
-- -D warnings
102 changes: 102 additions & 0 deletions .github/workflows/release-js.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Release — JavaScript (npm)

on:
push:
tags:
- "v*"
workflow_dispatch:

jobs:
build-bindings:
name: Build native binding — ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
node-arch: x64
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
node-arch: arm64
- os: macos-latest
target: x86_64-apple-darwin
node-arch: x64
- os: macos-latest
target: aarch64-apple-darwin
node-arch: arm64

steps:
- uses: actions/checkout@v4

- name: Set up Node.js 20
uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

# Cross-compilation for aarch64-linux requires a linker.
- name: Install cross-compilation linker (Linux aarch64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: sudo apt-get install -y gcc-aarch64-linux-gnu

- name: Install JS dependencies
working-directory: crates/atomic-js
run: npm install

- name: Build native addon
working-directory: crates/atomic-js
run: |
npx napi build \
--platform \
--release \
--target ${{ matrix.target }}

- name: Upload .node binding artifact
uses: actions/upload-artifact@v4
with:
name: bindings-${{ matrix.target }}
path: crates/atomic-js/*.node

publish:
name: Publish to npm
runs-on: ubuntu-latest
needs: build-bindings

steps:
- uses: actions/checkout@v4

- name: Set up Node.js 20
uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"

- name: Install JS dependencies
working-directory: crates/atomic-js
run: npm install

- name: Download all binding artifacts
uses: actions/download-artifact@v4
with:
pattern: "bindings-*"
merge-multiple: true
path: crates/atomic-js/

# napi prepublish step: copies .node files to platform-specific packages
# and updates the root package.json optionalDependencies map.
- name: Prepublish (bundle platform packages)
working-directory: crates/atomic-js
run: npx napi prepublish --skip-gh-release

- name: Publish to npm
working-directory: crates/atomic-js
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
98 changes: 98 additions & 0 deletions .github/workflows/release-py.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Release — Python (PyPI)

on:
push:
tags:
- "v*"
workflow_dispatch:

jobs:
build-wheels:
name: Build wheel — ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
- os: macos-latest
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

# maturin-action handles Rust toolchain + cross-compilation automatically.
# It installs the correct target via rustup and runs maturin build.
- name: Build wheel (maturin)
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: >-
--release
--out dist
--manifest-path crates/atomic-py/Cargo.toml
# On Linux, use manylinux_2_28 for broad distro compatibility.
manylinux: auto

- name: Upload wheel artifact
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.target }}
path: dist/

# Build the pure-Python sdist (source distribution) on one platform.
build-sdist:
name: Build sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist --manifest-path crates/atomic-py/Cargo.toml
- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/

publish:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [build-wheels, build-sdist]
environment:
name: pypi
url: https://pypi.org/p/atomic

permissions:
id-token: write # required for trusted publishing (OIDC)

steps:
- name: Download all wheel artifacts
uses: actions/download-artifact@v4
with:
pattern: "wheels-*"
merge-multiple: true
path: dist/

- name: Download sdist
uses: actions/download-artifact@v4
with:
name: sdist
path: dist/

# Uses PyPI trusted publishing (OIDC) — no API token needed.
# Configure at https://pypi.org/manage/project/atomic/settings/publishing/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
Loading
Loading