mirror of
https://github.com/alphaXiv/OpenResearch.git
synced 2026-11-11 09:59:34 +08:00
* fix: polish workspace controls and tooltips Assisted-by: gpt-6.1-terra * feat: add desktop update channels Assisted-by: gpt-6.1-terra Assisted-by: gpt-6.1-sol Assisted-by: claude-opus-5.5
325 lines
12 KiB
YAML
325 lines
12 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
workflow_dispatch:
|
|
workflow_call:
|
|
inputs:
|
|
# Required by cargo-dist's custom-ci calling convention.
|
|
plan:
|
|
required: true
|
|
type: string
|
|
source-sha:
|
|
required: false
|
|
type: string
|
|
default: ''
|
|
release:
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
|
|
concurrency:
|
|
group: ci-${{ github.workflow }}-${{ inputs.release && format('release-{0}', github.run_id) || (github.event_name == 'workflow_dispatch' && github.run_id || github.ref) }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
|
|
jobs:
|
|
changes:
|
|
name: Select checks
|
|
runs-on: ubuntu-24.04
|
|
outputs:
|
|
frontend: ${{ steps.changes.outputs.frontend }}
|
|
rust: ${{ steps.changes.outputs.rust }}
|
|
windows: ${{ steps.changes.outputs.windows }}
|
|
linux: ${{ steps.changes.outputs.linux }}
|
|
macos: ${{ steps.changes.outputs.macos }}
|
|
dev_slot: ${{ steps.changes.outputs.dev_slot }}
|
|
chart: ${{ steps.changes.outputs.chart }}
|
|
release_notes: ${{ steps.changes.outputs.release_notes }}
|
|
javascript: ${{ steps.changes.outputs.javascript }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ inputs.source-sha || github.sha }}
|
|
fetch-depth: 1
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- name: CI selection and release safety tests
|
|
run: node --test scripts/ci-changes.test.mjs scripts/ci-workflows.test.mjs scripts/canary-tag.test.mjs
|
|
- name: Select checks for changed files
|
|
id: changes
|
|
env:
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
|
|
HEAD_SHA: ${{ inputs.source-sha || github.sha }}
|
|
FORCE_ALL: ${{ github.event_name == 'workflow_dispatch' || inputs.release || inputs.plan != '' }}
|
|
run: node scripts/ci-changes.mjs
|
|
|
|
frontend:
|
|
name: Frontend
|
|
needs: changes
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ inputs.source-sha || github.sha }}
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- name: Localization catalogs
|
|
run: node ui/scripts/check-i18n.mjs
|
|
- name: Style tokens
|
|
run: node ui/scripts/check-styles.mjs
|
|
- uses: pnpm/action-setup@v4
|
|
with:
|
|
version: 10
|
|
- name: Install UI dependencies
|
|
working-directory: ui
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Build UI
|
|
working-directory: ui
|
|
run: pnpm exec vite build
|
|
- name: UI typecheck
|
|
working-directory: ui
|
|
run: pnpm typecheck
|
|
- name: UI unit tests
|
|
run: node --test --experimental-strip-types ui/tests/*.test.mjs
|
|
|
|
helpers:
|
|
name: Helper tests
|
|
needs: changes
|
|
if: needs.changes.outputs.dev_slot == 'true' || needs.changes.outputs.chart == 'true' || needs.changes.outputs.release_notes == 'true' || needs.changes.outputs.javascript == 'true'
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ inputs.source-sha || github.sha }}
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- name: Dev-slot helper tests
|
|
if: needs.changes.outputs.dev_slot == 'true'
|
|
run: node --test scripts/dev-slot.test.mjs
|
|
- name: Interactive chart authoring tests
|
|
if: needs.changes.outputs.chart == 'true'
|
|
run: python3 scripts/test_orx_chart.py
|
|
- name: Embedded JavaScript tests
|
|
if: needs.changes.outputs.javascript == 'true'
|
|
run: node --test ui/tests/zcodeOauth.test.mjs ui/tests/macosEscape.test.mjs ui/tests/orxChart.test.mjs
|
|
- name: Release notes composition
|
|
if: needs.changes.outputs.release_notes == 'true'
|
|
run: python3 scripts/test_release_notes.py
|
|
|
|
rust:
|
|
name: Rust
|
|
needs: changes
|
|
if: needs.changes.outputs.rust == 'true'
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ inputs.source-sha || github.sha }}
|
|
- name: Shared SSH helper protocol tests
|
|
run: |
|
|
python3 scripts/test_ssh_helper.py
|
|
for version in 3.6.15-slim-buster 3.7.17-slim-bullseye 3.8.20-slim-bookworm; do
|
|
docker run --rm --network none \
|
|
-v "$GITHUB_WORKSPACE:/work:ro" -w /work \
|
|
"python:$version" python scripts/test_ssh_helper.py
|
|
done
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: rustfmt, clippy
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: check # Preserve the former Rust job's cache namespace.
|
|
- name: Format
|
|
run: |
|
|
cargo fmt --all --check
|
|
cargo fmt --manifest-path windows/launcher/Cargo.toml --check
|
|
- name: Clippy
|
|
run: cargo clippy --all-targets --locked -- -D warnings
|
|
- name: Test
|
|
shell: bash
|
|
run: |
|
|
if [ "${{ github.event_name }}" = 'pull_request' ] && [ "${{ inputs.release }}" != 'true' ]; then
|
|
cargo test --locked -- --skip slurm_supervisor_survives_connection_and_accounting_loss --skip ssh_supervisor_survives_proxy_output_without_skipping_logs
|
|
else
|
|
cargo test --locked
|
|
fi
|
|
- name: Source builds disable production telemetry
|
|
shell: bash
|
|
run: test "$(target/debug/orx --no-telemetry version --build-channel)" = "development"
|
|
- name: Remove checked-in UI
|
|
if: inputs.release && github.event_name != 'pull_request'
|
|
shell: bash
|
|
run: rm -rf ui/dist
|
|
- name: Download release UI
|
|
if: inputs.release && github.event_name != 'pull_request'
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
name: release-ui
|
|
path: ui/dist
|
|
- name: Optimized source builds disable production telemetry
|
|
if: inputs.release && github.event_name != 'pull_request'
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
cargo build --release --locked
|
|
test "$(target/release/orx --no-telemetry version --build-channel)" = "development"
|
|
|
|
linux-app:
|
|
name: linux app (${{ matrix.arch }}, ${{ matrix.mode }})
|
|
needs: changes
|
|
if: needs.changes.outputs.linux == 'true'
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include: ${{ fromJSON(github.event_name == 'pull_request' && !inputs.release && '[{"arch":"x86_64","mode":"all"},{"arch":"aarch64","mode":"lint"},{"arch":"aarch64","mode":"build"}]' || '[{"arch":"x86_64","mode":"all"},{"arch":"aarch64","mode":"all"}]') }}
|
|
runs-on: ${{ matrix.arch == 'aarch64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04' }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ inputs.source-sha || github.sha }}
|
|
- name: Install WebKitGTK
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y --no-install-recommends libwebkit2gtk-4.1-dev libgtk-3-dev
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: clippy
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: linux-app
|
|
save-if: ${{ matrix.mode == 'all' }}
|
|
- name: Clippy
|
|
if: matrix.mode != 'build'
|
|
run: cargo clippy --all-targets --locked --features desktop -- -D warnings
|
|
- name: Build
|
|
if: github.event_name == 'pull_request' && !inputs.release && matrix.mode != 'lint'
|
|
run: cargo build --locked --features desktop
|
|
- name: Test
|
|
if: github.event_name != 'pull_request' || inputs.release
|
|
run: cargo test --locked --features desktop
|
|
|
|
windows:
|
|
name: windows (${{ matrix.mode }})
|
|
needs: changes
|
|
if: needs.changes.outputs.windows == 'true'
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
mode: ${{ fromJSON(github.event_name == 'pull_request' && !inputs.release && '["lint", "test"]' || '["all"]') }}
|
|
runs-on: windows-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ inputs.source-sha || github.sha }}
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: clippy, rustfmt
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: windows
|
|
save-if: ${{ matrix.mode == 'all' }}
|
|
workspaces: |
|
|
. -> target
|
|
windows/launcher -> target
|
|
- name: Clippy
|
|
if: matrix.mode != 'test'
|
|
run: cargo clippy --all-targets --locked -- -D warnings
|
|
- name: Format app launcher
|
|
if: matrix.mode != 'test'
|
|
run: cargo fmt --manifest-path windows/launcher/Cargo.toml --check
|
|
- name: Clippy (app launcher)
|
|
if: matrix.mode != 'test'
|
|
run: cargo clippy --manifest-path windows/launcher/Cargo.toml --locked -- -D warnings
|
|
- name: Build app launcher
|
|
if: matrix.mode != 'lint'
|
|
run: cargo build --manifest-path windows/launcher/Cargo.toml --locked
|
|
- name: Test
|
|
if: matrix.mode != 'lint'
|
|
run: cargo test --locked
|
|
|
|
check:
|
|
name: fmt, clippy, test
|
|
if: always()
|
|
needs: [changes, frontend, helpers, rust, linux-app, windows]
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ inputs.source-sha || github.sha }}
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- name: Verify all selected checks passed
|
|
env:
|
|
NEEDS_JSON: ${{ toJSON(needs) }}
|
|
FLAGS_JSON: ${{ toJSON(needs.changes.outputs) }}
|
|
run: node scripts/ci-check-result.mjs
|
|
|
|
# Guards the version-bump release flow (release-on-bump.yml): the version in
|
|
# Cargo.toml may only move forward, may not reuse an already-released tag,
|
|
# and a bump must come with a regenerated Cargo.lock. Catching these here
|
|
# means a malformed bump can't reach main, where merging it would be the
|
|
# release trigger.
|
|
version-guard:
|
|
name: version sanity
|
|
if: github.event_name == 'pull_request'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 1
|
|
|
|
- name: Version must move forward (with a fresh lockfile)
|
|
env:
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
pkg_version() { grep -m1 '^version = ' "$1" | sed -E 's/version = "(.*)"/\1/'; }
|
|
|
|
git fetch --no-tags --depth=1 origin "$BASE_SHA"
|
|
git show "${BASE_SHA}:Cargo.toml" > /tmp/base-Cargo.toml
|
|
base=$(pkg_version /tmp/base-Cargo.toml)
|
|
head=$(pkg_version Cargo.toml)
|
|
echo "base: ${base} pr: ${head}"
|
|
|
|
if [ "${head}" = "${base}" ]; then
|
|
echo "No version change — OK (merging this PR will not release)."
|
|
exit 0
|
|
fi
|
|
|
|
# Reject a version that sorts at or below the base (semver-aware sort).
|
|
if [ "$(printf '%s\n%s\n' "${base}" "${head}" | sort -V | head -1)" = "${head}" ]; then
|
|
echo "::error::Version went backwards: ${base} -> ${head}."
|
|
exit 1
|
|
fi
|
|
|
|
if git ls-remote --exit-code --tags origin "refs/tags/v${head}" >/dev/null 2>&1; then
|
|
echo "::error::v${head} is already a released tag; bump past it."
|
|
exit 1
|
|
fi
|
|
|
|
# A bump must carry a regenerated lockfile, or release builds
|
|
# (--locked) would fail.
|
|
if ! grep -A1 '^name = "openresearch-cli"$' Cargo.lock | grep -q "version = \"${head}\""; then
|
|
echo "::error::Cargo.toml says ${head} but Cargo.lock was not regenerated (run cargo build and commit the lockfile)."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Version bump ${base} -> ${head} looks good. Merging this PR WILL cut release v${head}."
|