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
32 changes: 32 additions & 0 deletions .github/scripts/fork-changed-packages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Map changed file paths to their cargo package names.

Reads `cargo metadata --no-deps --format-version 1` on stdin and file paths,
one per line, on argv. A file belongs to the package whose manifest directory
is the longest prefix of its path, so a nested crate wins over its parent and
the directory name never has to equal the package name.
"""

import json
import os
import sys

meta = json.load(sys.stdin)
root = os.getcwd()
dirs = []
for package in meta["packages"]:
manifest = os.path.relpath(package["manifest_path"], root)
dirs.append((os.path.dirname(manifest), package["name"]))
dirs.sort(key=lambda entry: len(entry[0]), reverse=True)

seen = []
for argument in sys.argv[1:]:
path = os.path.normpath(argument)
prefix = "codex-rs" + os.sep
if path.startswith(prefix):
path = path[len(prefix):]
for directory, name in dirs:
if path == directory or path.startswith(directory + os.sep):
if name not in seen:
seen.append(name)
break
print("\n".join(seen))
111 changes: 111 additions & 0 deletions .github/workflows/fork-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Fork-only CI. The upstream blocking-ci, CLA and v8-canary workflows are
# disabled on this fork, so this is the check that runs on fork pull requests.
# New file with a fork-unique name; no upstream workflow is edited.
name: fork-ci

on:
pull_request:
branches: [fork/main]
workflow_dispatch:

permissions:
contents: read

jobs:
check:
name: fmt, clippy, test
runs-on: ubuntu-24.04
# The workspace Cargo.toml is codex-rs/Cargo.toml; the repo root has none.
defaults:
run:
working-directory: codex-rs
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.0.1
with:
persist-credentials: false
fetch-depth: 0

- name: Set up Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
with:
components: rustfmt, clippy

# linux-sandbox's build.rs links libcap through pkg-config.
- name: Install build libraries
working-directory: ${{ github.workspace }}
run: sudo apt-get update && sudo apt-get install -y libcap-dev pkg-config libasound2-dev

# Directory names are not package names (app-server-protocol is the
# package codex-app-server-protocol) and crates nest (codex-rs/ext/skills),
# so each changed file maps to the package whose manifest directory is
# the longest prefix of its path. A workspace manifest change rebuilds
# every package.
- name: Packages changed against fork/main
id: crates
shell: bash
run: |
set -euo pipefail
base="$(git merge-base HEAD origin/fork/main 2>/dev/null || git merge-base HEAD fork/main)"
mapfile -t files < <(git diff --name-only "$base"...HEAD)
all=false
for f in "${files[@]}"; do
case "$f" in
codex-rs/Cargo.toml|codex-rs/Cargo.lock) all=true ;;
esac
done
if $all; then
mapfile -t packages < <(cargo metadata --no-deps --format-version 1 \
| jq -r '.packages[].name' | sort -u)
else
mapfile -t packages < <(cargo metadata --no-deps --format-version 1 \
| python3 "${GITHUB_WORKSPACE}/.github/scripts/fork-changed-packages.py" "${files[@]}")
fi
echo "changed: ${packages[*]:-none}"
{
echo "list<<EOF"
printf '%s\n' "${packages[@]:-}"
echo "EOF"
} >> "$GITHUB_OUTPUT"

# v8's build.rs otherwise downloads librusty_v8 from denoland, which does
# not publish the ptrcomp_sandbox profile this tree expects. This fetches
# the Codex-built artifacts from the upstream release and verifies them
# against the in-tree checksum manifest, the same as fork-release.
- name: Configure rusty_v8 artifact overrides and verify checksums
uses: ./.github/actions/setup-rusty-v8
with:
target: x86_64-unknown-linux-gnu

# codex-voice-host is excluded: it is the only package pulling in GStreamer,
# and it requires gstreamer-1.0 >= 1.28. Ubuntu 24.04 ships 1.24, so no
# apt package satisfies it. Upstream never builds it with cargo either; it
# builds //codex-rs/voice-host with Bazel against a bundled GStreamer.
- name: cargo check
run: cargo check --workspace --all-targets --exclude codex-voice-host

- name: cargo fmt
shell: bash
run: |
set -euo pipefail
while IFS= read -r crate; do
[[ -z "$crate" ]] && continue
cargo fmt -p "$crate" -- --check
done <<< "${{ steps.crates.outputs.list }}"

- name: cargo clippy
shell: bash
run: |
set -euo pipefail
while IFS= read -r crate; do
[[ -z "$crate" ]] && continue
cargo clippy -p "$crate" --all-targets -- -D warnings
done <<< "${{ steps.crates.outputs.list }}"

- name: cargo test
shell: bash
run: |
set -euo pipefail
while IFS= read -r crate; do
[[ -z "$crate" ]] && continue
cargo test -p "$crate"
done <<< "${{ steps.crates.outputs.list }}"