Pipelines
A pipeline builds termorq-cli, points it at the checkout with an absolute path, and passes each connection secret in from the forge’s secret store. The JUnit document is written to standard output. Warnings stay on standard error, so a skipped step does not corrupt the XML.
flowchart LR
checkout[("Checkout\n.ai-terminal/")]:::store
secrets[("Forge\nsecret store")]:::secret
build["cargo build\n--bin termorq-cli"]:::step
run["termorq-cli run\n--format junit"]:::run
report(["Publish the XML\neven if the run fails"]):::out
checkout --> build --> run
secrets --> run
run --> report
classDef store fill:#134e4a,stroke:#5eead4,stroke-width:2px,color:#f4fbfa
classDef secret fill:#FFC131,stroke:#b45309,stroke-width:2px,color:#1a1404
classDef step fill:#155e75,stroke:#67e8f9,stroke-width:2px,color:#f4fbfa
classDef run fill:#0f766e,stroke:#99f6e4,stroke-width:2px,color:#f4fbfa
classDef out fill:#166534,stroke:#86efac,stroke-width:2px,color:#f0fdf4
linkStyle 0,1 stroke:#5eead4,stroke-width:2.5px
linkStyle 2 stroke:#FFC131,stroke-width:2.5px
linkStyle 3 stroke:#86efac,stroke-width:2.5px
The commands below are the same ones in Run a collection. Swap Smoke and AIT_SECRET_USERS_API for your collection and connection. Add --allow-shell only when you have read the shell lines. Add --yes only when the plan calls a destructive tool.
Exit code 1 fails the job, which is what you want when a check fails. Exit code 2 fails it too, because the workspace or the secret is wrong. Publish the report anyway, or a failed run leaves you with no XML.
GitHub Actions
name: termorq-cli
on:
push:
workflow_dispatch:
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Build termorq-cli
run: cargo build --release --bin termorq-cli --manifest-path src-tauri/Cargo.toml
- name: Run Smoke
run: |
src-tauri/target/release/termorq-cli run Smoke \
--workspace "${{ github.workspace }}" \
--env Staging \
--format junit > "$RUNNER_TEMP/termorq-cli-results.xml"
env:
AIT_SECRET_USERS_API: ${{ secrets.USERS_API_KEY }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: termorq-cli-results
path: ${{ runner.temp }}/termorq-cli-results.xml${{ github.workspace }} is absolute, which --workspace requires. GitHub Actions does not publish JUnit on its own. The artifact is the report. A test-reporter action can turn that file into a check if you want one.
Linux runners need the Tauri build packages before cargo build, the same list as the app. The termorq-cli binary does not open a window.
GitLab CI
termorq-cli:
image: rust:1-bookworm
script:
- cargo build --release --bin termorq-cli --manifest-path src-tauri/Cargo.toml
- |
src-tauri/target/release/termorq-cli run Smoke \
--workspace "$CI_PROJECT_DIR" \
--env Staging \
--format junit > termorq-cli-results.xml
variables:
AIT_SECRET_USERS_API: $USERS_API_KEY
artifacts:
when: always
paths:
- termorq-cli-results.xml
reports:
junit: termorq-cli-results.xmlStore USERS_API_KEY as a masked CI variable. when: always uploads the report after a failed step. The reports.junit entry is what GitLab shows on the pipeline.
The rust image does not include the WebKit and GTK packages the app library needs to link. Install those first, or use an image that already has the Tauri Linux prerequisites.
Azure DevOps
steps:
- script: cargo build --release --bin termorq-cli --manifest-path src-tauri/Cargo.toml
displayName: Build termorq-cli
- script: >
src-tauri/target/release/termorq-cli run Smoke
--workspace "$(Build.SourcesDirectory)"
--env Staging
--format junit > "$(Build.ArtifactStagingDirectory)/termorq-cli.xml"
displayName: Run Smoke
env:
AIT_SECRET_USERS_API: $(USERS_API_KEY)
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: JUnit
testResultsFiles: $(Build.ArtifactStagingDirectory)/termorq-cli.xml
testRunTitle: termorq-cli SmokeMap USERS_API_KEY from a secret variable or a variable group. $(Build.SourcesDirectory) is the absolute checkout path. condition: always() publishes the results when the run exits 1.