1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
name: CI
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [master, windows]
paths-ignore:
- "website/**"
- ".github/APPROVED_CONTRIBUTORS"
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
conventional-commits:
if: github.event_name != 'push' || github.ref_name == 'master'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
- name: Validate commit subjects
if: github.event_name == 'push'
run: python3 scripts/conventional_commits.py --range "${{ github.event.before }}..${{ github.event.after }}"
- name: Validate PR title
if: github.event_name == 'pull_request'
run: python3 scripts/conventional_commits.py "${{ github.event.pull_request.title }}"
check:
name: check (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
nextest_filter: all()
- os: macos-latest
nextest_filter: not binary(live_handoff)
runs-on: ${{ matrix.os }}
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install Rust tools
uses: taiki-e/install-action@b550161ef8a7bc4f2a671c0b03a18ac9ccedea1e # v2
with:
tool: just,cargo-nextest
- name: Install Zig
uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
with:
version: 0.15.2
- name: Install macOS build tools
if: runner.os == 'macOS'
run: brew install cmake ninja
- name: Restore cargo cache
uses: Swatinem/rust-cache@v2
with:
cache-bin: false
- name: Run checks
run: just ci '${{ matrix.nextest_filter }}'
check-windows:
name: check (windows)
runs-on: windows-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-pc-windows-msvc
- name: Install Zig
uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
with:
version: 0.15.2
- name: Restore cargo cache
uses: Swatinem/rust-cache@v2
with:
cache-bin: false
key: windows-x86_64-pc-windows-msvc
- name: Run Windows checks
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
function Invoke-Checked {
param([string]$Command, [string[]]$Arguments)
& $Command @Arguments
if ($LASTEXITCODE -ne 0) {
throw "command failed with exit code $LASTEXITCODE`: $Command $($Arguments -join ' ')"
}
}
Invoke-Checked cargo @("fmt", "--check")
Invoke-Checked cargo @("clippy", "--bin", "herdr", "--locked", "--target", "x86_64-pc-windows-msvc", "--", "-D", "warnings")
Invoke-Checked cargo @("test", "--locked", "--target", "x86_64-pc-windows-msvc", "--bin", "herdr", "windows_")
Invoke-Checked cargo @("test", "--locked", "--target", "x86_64-pc-windows-msvc", "--bin", "herdr", "server::client_transport::tests")
Invoke-Checked cargo @("build", "--locked", "--target", "x86_64-pc-windows-msvc")
- name: Smoke ConPTY pane
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$env:HERDR_SESSION = "ci-windows-$env:GITHUB_RUN_ID-$env:GITHUB_RUN_ATTEMPT"
$exe = Join-Path $PWD "target\x86_64-pc-windows-msvc\debug\herdr.exe"
& $exe --version
& $exe --default-config | Out-Null
$server = Start-Process -FilePath $exe -ArgumentList "server" -PassThru -WindowStyle Hidden
try {
$deadline = (Get-Date).AddSeconds(10)
do {
Start-Sleep -Milliseconds 250
$status = & $exe status server 2>&1
if ($LASTEXITCODE -eq 0 -and (($status -join "`n") -match "status: running")) {
break
}
} while ((Get-Date) -lt $deadline)
if ((Get-Date) -ge $deadline) {
throw "server did not become ready"
}
& $exe agent start smoke -- "$env:ComSpec" /K dir
Start-Sleep -Seconds 2
$read = & $exe agent read smoke --source recent --lines 40 --format text
$text = $read -join "`n"
if ($text -notmatch "Directory of") {
throw "pane read did not include cmd.exe directory output: $text"
}
} finally {
& $exe server stop 2>$null
Wait-Process -Id $server.Id -Timeout 10 -ErrorAction SilentlyContinue
}
|