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
90 changes: 90 additions & 0 deletions .github/workflows/lsp-public-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Public LSP workspace
on:
pull_request:
paths:
- 'crates/terraphim_lsp/**'
- 'crates/terraphim_lsp_core/**'
- 'scripts/lsp_crates_release.py'
- 'tests/test_lsp_crates_release.py'
- 'release/lsp-crates.json'
- '.github/workflows/lsp-public-ci.yml'
- 'Cargo.toml'
- '.cargo/**'
push:
branches: [main, 'codex/**']
paths:
- 'crates/terraphim_lsp/**'
- 'crates/terraphim_lsp_core/**'
- 'scripts/lsp_crates_release.py'
- 'tests/test_lsp_crates_release.py'
- 'release/lsp-crates.json'
- '.github/workflows/lsp-public-ci.yml'
- 'Cargo.toml'
- '.cargo/**'
permissions:
contents: read
concurrency:
group: public-lsp-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PYTHONDONTWRITEBYTECODE: '1'
CARGO_TERM_COLOR: never
jobs:
qualify:
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.12'
- name: Verify standalone workspace and public registry lock
id: source
run: python3 scripts/lsp_crates_release.py check-source --receipt "$RUNNER_TEMP/source-contract.json"
- name: Install reviewed Rust toolchain
env:
TOOLCHAIN: ${{ steps.source.outputs.toolchain }}
run: |
rustup toolchain install "$TOOLCHAIN" --profile minimal --component rustfmt --component clippy
rustup target add wasm32-unknown-unknown --toolchain "$TOOLCHAIN"
- name: Qualify native server, shared core and WASM
env:
TOOLCHAIN: ${{ steps.source.outputs.toolchain }}
MANIFEST: ${{ steps.source.outputs.manifest }}
CARGO_HOME: ${{ runner.temp }}/lsp-cargo
CARGO_TARGET_DIR: ${{ runner.temp }}/lsp-target
CARGO_BUILD_BUILD_DIR: ${{ runner.temp }}/lsp-build
RUSTC_WRAPPER: ''
RUSTC_WORKSPACE_WRAPPER: ''
run: |
set -euo pipefail
cargo +"$TOOLCHAIN" fmt --manifest-path "$MANIFEST" --all --check
cargo +"$TOOLCHAIN" clippy --locked --manifest-path "$MANIFEST" --workspace --all-targets -- -D warnings
cargo +"$TOOLCHAIN" test --locked --manifest-path "$MANIFEST" --workspace --all-targets
cargo +"$TOOLCHAIN" test --locked --manifest-path "$MANIFEST" --workspace --doc
cargo +"$TOOLCHAIN" check --locked --manifest-path "$MANIFEST" -p terraphim_lsp_core --target wasm32-unknown-unknown --lib
cargo +"$TOOLCHAIN" package --locked --manifest-path "$MANIFEST" -p terraphim_lsp_core
cargo +"$TOOLCHAIN" package --locked --manifest-path "$MANIFEST" -p terraphim_lsp --list > "$RUNNER_TEMP/server-package-files.txt"
python3 - <<'PYCODE'
import importlib.util, os
from pathlib import Path
spec = importlib.util.spec_from_file_location("release", "scripts/lsp_crates_release.py")
r = importlib.util.module_from_spec(spec); spec.loader.exec_module(r)
root = Path.cwd(); plan = r.load_plan(root); core = plan["packages"][0]
archive = r.package_archive(root, core, os.environ)
r.unpack_package(archive, core, r.git(root, "rev-parse", "HEAD"), Path(os.environ["RUNNER_TEMP"]) / "unpacked", root)
PYCODE
core_version="$(python3 -c 'import json; print(json.load(open("release/lsp-crates.json"))["packages"][0]["version"])')"
cd "$RUNNER_TEMP/unpacked/terraphim_lsp_core-$core_version"
cargo +"$TOOLCHAIN" test --locked --all-targets
cargo +"$TOOLCHAIN" test --locked --doc
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
if: always()
with:
name: lsp-source-contract-${{ github.sha }}
path: |
${{ runner.temp }}/source-contract.json
${{ runner.temp }}/server-package-files.txt
if-no-files-found: error
198 changes: 180 additions & 18 deletions .github/workflows/lsp-publish.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,171 @@
name: Publish reviewed LSP handoff

name: Build and publish public-registry LSP binaries
on:
push:
tags:
- 'terraphim_lsp-v*'

workflow_call:
inputs:
tag:
required: true
type: string
source-sha:
required: true
type: string
toolchain:
required: true
type: string
permissions:
contents: read

concurrency:
group: lsp-publish-${{ github.ref_name }}
group: lsp-public-binaries-${{ inputs.tag }}
cancel-in-progress: false

env:
PYTHONDONTWRITEBYTECODE: '1'
jobs:
qualify:
if: github.repository == 'terraphim/terraphim-ai' && github.ref == format('refs/tags/{0}', inputs.tag) && github.sha == inputs.source-sha
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
ref: ${{ github.sha }}
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.12'
- name: Install exact Rust toolchain
env:
TOOLCHAIN: ${{ inputs.toolchain }}
run: rustup toolchain install "$TOOLCHAIN" --profile minimal --component clippy
- name: Test the actual published crate and registry lock
env:
TAG: ${{ inputs.tag }}
SOURCE: ${{ inputs.source-sha }}
TOOLCHAIN: ${{ inputs.toolchain }}
run: |
set -euo pipefail
python3 scripts/lsp_public_binary.py prepare --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --lane "$RUNNER_TEMP/qualification"
python3 scripts/lsp_public_binary.py qualify --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --lane "$RUNNER_TEMP/qualification"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
if: always()
with:
name: lsp-public-qualification-${{ github.run_attempt }}
path: |
${{ runner.temp }}/qualification/qualification.json
${{ runner.temp }}/qualification/source.json
${{ runner.temp }}/qualification/failure.json
${{ runner.temp }}/qualification/logs/*
if-no-files-found: error
linux:
needs: qualify
runs-on: ubuntu-latest
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
target: [x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, aarch64-unknown-linux-musl]
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
ref: ${{ github.sha }}
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.12'
- name: Install exact Rust toolchain
env:
TOOLCHAIN: ${{ inputs.toolchain }}
TARGET: ${{ matrix.target }}
run: rustup toolchain install "$TOOLCHAIN" --profile minimal --target "$TARGET"
- name: Install reviewed cross compiler wrapper
if: endsWith(matrix.target, '-musl')
env:
TOOLCHAIN: ${{ inputs.toolchain }}
CARGO_HOME: ${{ runner.temp }}/cross-cargo
run: |
rustup run "$TOOLCHAIN" cargo install cross --locked --git https://github.com/cross-rs/cross --rev 29d00c7803f221f1b3f35e561b03792368fb8339 --root "$RUNNER_TEMP/cross-tool"
echo "$RUNNER_TEMP/cross-tool/bin" >> "$GITHUB_PATH"
- name: Build exact published registry bytes
env:
TAG: ${{ inputs.tag }}
SOURCE: ${{ inputs.source-sha }}
TOOLCHAIN: ${{ inputs.toolchain }}
TARGET: ${{ matrix.target }}
run: |
set -euo pipefail
python3 scripts/lsp_public_binary.py prepare --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --lane "$RUNNER_TEMP/lane"
args=()
if [[ "$TARGET" == *-musl ]]; then
image="ghcr.io/cross-rs/$TARGET:0.2.5"
docker pull "$image"
digest="$(docker image inspect "$image" --format '{{index .RepoDigests 0}}')"
args+=(--cross-image "$digest")
fi
python3 scripts/lsp_public_binary.py build --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --lane "$RUNNER_TEMP/lane" --target "$TARGET" "${args[@]}"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: lsp-public-${{ matrix.target }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/lane/dist/**
if-no-files-found: error
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
if: failure()
with:
name: lsp-build-failure-${{ matrix.target }}-${{ github.run_attempt }}
path: |
${{ runner.temp }}/lane/source.json
${{ runner.temp }}/lane/failure.json
${{ runner.temp }}/lane/logs/*
if-no-files-found: warn
macos:
needs: qualify
runs-on: macos-14
timeout-minutes: 90
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
ref: ${{ github.sha }}
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.12'
- name: Install exact Rust toolchain
env:
TOOLCHAIN: ${{ inputs.toolchain }}
run: rustup toolchain install "$TOOLCHAIN" --profile minimal --target aarch64-apple-darwin --target x86_64-apple-darwin
- name: Build both architectures and universal binary from registry bytes
env:
TAG: ${{ inputs.tag }}
SOURCE: ${{ inputs.source-sha }}
TOOLCHAIN: ${{ inputs.toolchain }}
run: |
set -euo pipefail
python3 scripts/lsp_public_binary.py prepare --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --lane "$RUNNER_TEMP/lane"
for target in aarch64-apple-darwin x86_64-apple-darwin; do
python3 scripts/lsp_public_binary.py build --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --lane "$RUNNER_TEMP/lane" --target "$target"
done
python3 scripts/lsp_public_binary.py universal --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --lane "$RUNNER_TEMP/lane"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: lsp-public-macos-${{ github.run_attempt }}
path: ${{ runner.temp }}/lane/dist/**
if-no-files-found: error
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
if: failure()
with:
name: lsp-build-failure-macos-${{ github.run_attempt }}
path: |
${{ runner.temp }}/lane/source.json
${{ runner.temp }}/lane/failure.json
${{ runner.temp }}/lane/logs/*
if-no-files-found: warn
publish:
if: github.repository == 'terraphim/terraphim-ai' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/terraphim_lsp-v')
needs: [qualify, linux, macos]
environment: lsp-releases
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
actions: read
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
Expand All @@ -29,16 +174,33 @@ jobs:
persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: '3.11'
- name: Verify provenance and publish immutable frozen bytes
python-version: '3.12'
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: lsp-public-qualification-${{ github.run_attempt }}
path: ${{ runner.temp }}/qualification
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
pattern: lsp-public-*-unknown-linux-*-${{ github.run_attempt }}
path: ${{ runner.temp }}/dist
merge-multiple: true
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: lsp-public-macos-${{ github.run_attempt }}
path: ${{ runner.temp }}/dist
- name: Verify six assets and publish immutable frozen bytes
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
run: python3 .github/scripts/release/lsp_handoff.py publish --tag "$TAG" --receipt publication-receipt.json
- name: Preserve publication or fixed-code failure receipt
TAG: ${{ inputs.tag }}
SOURCE: ${{ inputs.source-sha }}
TOOLCHAIN: ${{ inputs.toolchain }}
run: |
set -euo pipefail
python3 scripts/lsp_public_binary.py assemble --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --assets "$RUNNER_TEMP/dist" --qualification "$RUNNER_TEMP/qualification" --receipt "$RUNNER_TEMP/publication-receipt.json"
python3 scripts/lsp_public_binary.py publish --tag "$TAG" --source "$SOURCE" --toolchain "$TOOLCHAIN" --assets "$RUNNER_TEMP/dist" --qualification "$RUNNER_TEMP/qualification" --receipt "$RUNNER_TEMP/publication-receipt.json"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: lsp-publication-${{ github.run_id }}-${{ github.run_attempt }}
path: publication-receipt.json
path: ${{ runner.temp }}/publication-receipt.json
if-no-files-found: error
51 changes: 42 additions & 9 deletions .github/workflows/publish-crates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,29 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v6

- name: Refuse packages owned by the reviewed LSP publisher
env:
REQUESTED_CRATES: ${{ inputs.crate_list }}
REQUESTED_CRATE: ${{ inputs.crate }}
shell: bash
run: |
set -euo pipefail
set -f
for crate in $REQUESTED_CRATES $REQUESTED_CRATE; do
case "$crate" in
terraphim_lsp|terraphim_lsp_core)
echo "::error::LSP packages are owned by publish-lsp-crates.yml; use an exact reviewed package tag."
exit 1
;;
terraphim_update|terraphim_github_runner|terraphim_gitea_runner|terraphim_rlm)
;;
*)
echo "::error::Unsupported legacy package; use an exact allowed package name."
exit 1
;;
esac
done

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
Expand All @@ -56,18 +79,28 @@ jobs:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
run: |
TOKEN=$(op read "op://TerraphimPlatform/crates.io.token/token")
echo "token=$TOKEN" >> $GITHUB_OUTPUT
echo "token=$TOKEN" >> "$GITHUB_OUTPUT"

- name: Resolve crate list
id: crates
env:
REQUESTED_CRATES: ${{ inputs.crate_list }}
REQUESTED_CRATE: ${{ inputs.crate }}
run: |
if [ -n "${{ inputs.crate_list }}" ]; then
echo "list=${{ inputs.crate_list }}" >> $GITHUB_OUTPUT
elif [ -n "${{ inputs.crate }}" ]; then
echo "list=${{ inputs.crate }}" >> $GITHUB_OUTPUT
set -euo pipefail
set -f
if [ -n "$REQUESTED_CRATES" ]; then
selected="$REQUESTED_CRATES"
elif [ -n "$REQUESTED_CRATE" ]; then
selected="$REQUESTED_CRATE"
else
echo "list=terraphim_update terraphim_github_runner terraphim_gitea_runner terraphim_rlm terraphim_lsp" >> $GITHUB_OUTPUT
selected='terraphim_update terraphim_github_runner terraphim_gitea_runner terraphim_rlm'
fi
normalized=""
for crate in $selected; do
normalized="${normalized:+$normalized }$crate"
done
printf 'list=%s\n' "$normalized" >> "$GITHUB_OUTPUT"

- name: Publish crates in dependency order
env:
Expand All @@ -79,12 +112,12 @@ jobs:
chmod +x ./scripts/publish-crates.sh

for crate in $CRATE_LIST; do
ARGS="--crate $crate"
ARGS=(--crate "$crate")
if [ "$DRY_RUN" = "true" ]; then
ARGS="$ARGS --dry-run"
ARGS+=(--dry-run)
fi
VERSION=$(grep -m1 '^version' Cargo.toml | sed 's/version = "//; s/"//')
./scripts/publish-crates.sh $ARGS --version "$VERSION"
./scripts/publish-crates.sh "${ARGS[@]}" --version "$VERSION"
done

- name: Verify published packages
Expand Down
Loading
Loading