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.xml

Store 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 Smoke

Map 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.