Skip to content

Commit eacfe87

Browse files
authored
Merge branch 'master' into Verify-Cargo-
2 parents 5096c52 + af5c521 commit eacfe87

137 files changed

Lines changed: 16132 additions & 626 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Normalise binding snapshot golden files to LF so the snapshot comparison
2+
# (which rejects CR characters) is stable across Windows and Linux checkouts.
3+
tests/fixtures/snapshots/bindings_rust.rs text eol=lf
4+
tests/fixtures/snapshots/bindings_typescript.ts text eol=lf
5+
tests/fixtures/snapshots/bindings_python.py text eol=lf
6+
tests/fixtures/snapshots/bindings_go.go text eol=lf
7+
*.rs text eol=lf
8+
*.ts text eol=lf
9+
*.py text eol=lf
10+
*.go text eol=lf
11+
*.toml text eol=lf
12+
*.md text eol=lf

.github/workflows/audit.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Security Audit
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
schedule:
9+
- cron: '0 0 * * 0' # Weekly on Sundays
10+
11+
jobs:
12+
audit:
13+
name: Cargo Audit
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: rustsec/audit-check@v1.4.1
18+
with:
19+
token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ jobs:
4040
command: check
4141
arguments: --all-features
4242

43+
secure-defaults:
44+
name: Secure Defaults Audit
45+
doctests:
46+
name: Documentation Tests
47+
runs-on: ubuntu-latest
48+
steps:
49+
- uses: actions/checkout@v4
50+
- uses: dtolnay/rust-toolchain@stable
51+
- name: Install system dependencies
52+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
53+
- name: Run secure defaults audit
54+
run: cargo test --test secure_defaults_audit --locked
55+
- name: Run doctests
56+
run: cargo test --doc --locked
57+
4358
build-and-test:
4459
name: Build and Test
4560
runs-on: ubuntu-latest
@@ -57,6 +72,19 @@ jobs:
5772
- name: Verify Cargo.lock immutability
5873
run: git diff --exit-code Cargo.lock
5974

75+
docs-cheatsheet:
76+
name: Docs Cheat Sheet (anti-drift)
77+
runs-on: ubuntu-latest
78+
steps:
79+
- uses: actions/checkout@v4
80+
- uses: dtolnay/rust-toolchain@stable
81+
- name: Install system dependencies
82+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
83+
- name: Build (regenerates cheat sheet from clap metadata)
84+
run: cargo build --locked
85+
- name: Fail when cheat sheet is stale
86+
run: git diff --exit-code -- docs/COMMAND_CHEATSHEET.md
87+
6088
clippy:
6189
name: Clippy Lint
6290
runs-on: ubuntu-latest
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Contract Monitoring
2+
3+
on:
4+
schedule:
5+
# Run every 30 minutes
6+
- cron: '*/30 * * * *'
7+
workflow_dispatch:
8+
inputs:
9+
contract_id:
10+
description: Soroban contract ID to monitor
11+
required: true
12+
type: string
13+
network:
14+
description: Network
15+
required: false
16+
default: testnet
17+
type: choice
18+
options: [testnet, mainnet]
19+
20+
permissions:
21+
contents: read
22+
23+
jobs:
24+
monitor:
25+
name: Monitor Contract Health
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
- uses: dtolnay/rust-toolchain@stable
30+
- name: Install system dependencies
31+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
32+
- name: Build starforge
33+
run: cargo build --locked --release && cp target/release/starforge /usr/local/bin/starforge
34+
- name: Inspect contract state
35+
id: inspect
36+
run: |
37+
CONTRACT_ID="${{ inputs.contract_id || secrets.STARFORGE_CONTRACT_ID }}"
38+
NETWORK="${{ inputs.network || 'testnet' }}"
39+
if [ -n "$CONTRACT_ID" ]; then
40+
starforge inspect state "$CONTRACT_ID" --network "$NETWORK" --json > monitor-output.json 2>&1 || echo '{"error": true}' > monitor-output.json
41+
echo "contract_id=$CONTRACT_ID" >> "$GITHUB_OUTPUT"
42+
echo "network=$NETWORK" >> "$GITHUB_OUTPUT"
43+
else
44+
echo "No contract ID configured — skipping inspection"
45+
fi
46+
continue-on-error: true
47+
- name: Upload monitoring snapshot
48+
if: always()
49+
uses: actions/upload-artifact@v4
50+
with:
51+
name: monitor-snapshot-${{ github.run_number }}
52+
path: monitor-output.json
53+
if-no-files-found: ignore
54+
retention-days: 30
55+
- name: Notify on anomaly
56+
if: ${{ failure() && secrets.SLACK_WEBHOOK_URL != '' }}
57+
uses: slackapi/slack-github-action@v1
58+
with:
59+
payload: |
60+
{
61+
"text": "⚠️ Contract monitoring alert",
62+
"attachments": [{
63+
"color": "warning",
64+
"fields": [
65+
{ "title": "Contract ID", "value": "${{ steps.inspect.outputs.contract_id }}", "short": true },
66+
{ "title": "Network", "value": "${{ steps.inspect.outputs.network }}", "short": true },
67+
{ "title": "Details", "value": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "short": false }
68+
]
69+
}]
70+
}
71+
env:
72+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
73+
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
name: Contract Test Pipeline
2+
3+
on:
4+
push:
5+
paths:
6+
- '**.wasm'
7+
- 'src/**'
8+
- 'tests/**'
9+
- 'Cargo.toml'
10+
- 'Cargo.lock'
11+
pull_request:
12+
paths:
13+
- '**.wasm'
14+
- 'src/**'
15+
- 'tests/**'
16+
- 'Cargo.toml'
17+
- 'Cargo.lock'
18+
workflow_dispatch:
19+
inputs:
20+
network:
21+
description: Target network for integration tests
22+
required: false
23+
default: testnet
24+
type: choice
25+
options: [testnet, mainnet]
26+
wasm_path:
27+
description: Path to compiled WASM file (optional)
28+
required: false
29+
type: string
30+
31+
permissions:
32+
contents: read
33+
34+
jobs:
35+
unit-tests:
36+
name: Unit Tests
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
- uses: dtolnay/rust-toolchain@stable
41+
- name: Install system dependencies
42+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
43+
- name: Run unit tests
44+
run: cargo test --locked -- --test-threads=1
45+
46+
lint-contract:
47+
name: Contract Lint
48+
runs-on: ubuntu-latest
49+
needs: unit-tests
50+
steps:
51+
- uses: actions/checkout@v4
52+
- uses: dtolnay/rust-toolchain@stable
53+
with:
54+
components: clippy
55+
- name: Install system dependencies
56+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
57+
- name: Install starforge
58+
run: cargo build --locked --release && cp target/release/starforge /usr/local/bin/starforge
59+
- name: Lint contract (if WASM available)
60+
if: ${{ inputs.wasm_path != '' }}
61+
run: starforge lint --wasm "${{ inputs.wasm_path }}"
62+
continue-on-error: true
63+
64+
gas-analysis:
65+
name: Gas Analysis
66+
runs-on: ubuntu-latest
67+
needs: unit-tests
68+
steps:
69+
- uses: actions/checkout@v4
70+
- uses: dtolnay/rust-toolchain@stable
71+
- name: Install system dependencies
72+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
73+
- name: Build
74+
run: cargo build --locked --release
75+
- name: Install starforge
76+
run: cp target/release/starforge /usr/local/bin/starforge
77+
- name: Run gas analysis (if WASM available)
78+
if: ${{ inputs.wasm_path != '' }}
79+
run: starforge gas analyze --wasm "${{ inputs.wasm_path }}" --network "${{ inputs.network || 'testnet' }}"
80+
continue-on-error: true
81+
82+
security-audit:
83+
name: Security Audit
84+
runs-on: ubuntu-latest
85+
needs: unit-tests
86+
steps:
87+
- uses: actions/checkout@v4
88+
- uses: dtolnay/rust-toolchain@stable
89+
- name: Install system dependencies
90+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
91+
- name: Build
92+
run: cargo build --locked --release
93+
- name: Install starforge
94+
run: cp target/release/starforge /usr/local/bin/starforge
95+
- name: Run security audit (if WASM available)
96+
if: ${{ inputs.wasm_path != '' }}
97+
run: starforge audit --wasm "${{ inputs.wasm_path }}" --output json > audit-results.json
98+
continue-on-error: true
99+
- name: Upload audit results
100+
if: always()
101+
uses: actions/upload-artifact@v4
102+
with:
103+
name: audit-results
104+
path: audit-results.json
105+
if-no-files-found: ignore
106+
107+
notify:
108+
name: Notify Results
109+
runs-on: ubuntu-latest
110+
needs: [unit-tests, lint-contract, gas-analysis, security-audit]
111+
if: always()
112+
steps:
113+
- name: Notify on failure
114+
if: ${{ contains(needs.*.result, 'failure') && secrets.SLACK_WEBHOOK_URL != '' }}
115+
uses: slackapi/slack-github-action@v1
116+
with:
117+
payload: |
118+
{
119+
"text": "❌ Contract test pipeline failed",
120+
"attachments": [{
121+
"color": "danger",
122+
"fields": [
123+
{ "title": "Repository", "value": "${{ github.repository }}", "short": true },
124+
{ "title": "Branch", "value": "${{ github.ref_name }}", "short": true },
125+
{ "title": "Commit", "value": "${{ github.sha }}", "short": false },
126+
{ "title": "Details", "value": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "short": false }
127+
]
128+
}]
129+
}
130+
env:
131+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
132+
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
133+
- name: Notify on success
134+
if: ${{ !contains(needs.*.result, 'failure') && secrets.SLACK_WEBHOOK_URL != '' }}
135+
uses: slackapi/slack-github-action@v1
136+
with:
137+
payload: |
138+
{
139+
"text": "✅ Contract test pipeline passed",
140+
"attachments": [{
141+
"color": "good",
142+
"fields": [
143+
{ "title": "Repository", "value": "${{ github.repository }}", "short": true },
144+
{ "title": "Branch", "value": "${{ github.ref_name }}", "short": true }
145+
]
146+
}]
147+
}
148+
env:
149+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
150+
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

.github/workflows/installer-tests.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,35 @@ jobs:
4646

4747
- name: Lint installer tests
4848
run: shellcheck -S warning tests/installer/test_install.sh
49+
50+
installer-windows:
51+
name: Installer Smoke Tests (Windows)
52+
runs-on: windows-latest
53+
steps:
54+
- uses: actions/checkout@v4
55+
56+
- name: Install Rust toolchain
57+
uses: dtolnay/rust-toolchain@stable
58+
59+
# Windows is distributed as a .zip release artifact (see release.yml), so
60+
# there is no shell installer to stub like install.sh. Instead we build
61+
# the exact release binary that ships in that .zip and smoke test its
62+
# startup plus core help/doctor commands.
63+
- name: Build release binary
64+
run: cargo build --release --locked
65+
66+
# Release-blocking: the shipped Windows .zip (release.yml) contains
67+
# exactly this binary. If it cannot start or its --help/doctor surface is
68+
# broken, the release must not proceed.
69+
- name: Run Windows smoke tests
70+
shell: pwsh
71+
run: pwsh -NoProfile -ExecutionPolicy Bypass -File tests/installer/windows_smoke.ps1 -Binary "target\release\starforge.exe"
72+
73+
- name: Upload Windows smoke logs
74+
if: failure()
75+
uses: actions/upload-artifact@v4
76+
with:
77+
name: windows-installer-smoke-logs
78+
path: windows-smoke.log
79+
retention-days: 14
80+
if-no-files-found: ignore

.github/workflows/release.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@ permissions:
1111
attestations: write
1212

1313
jobs:
14+
secure-defaults:
15+
name: Secure Defaults Audit
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: dtolnay/rust-toolchain@stable
20+
- name: Install system dependencies
21+
run: sudo apt-get update && sudo apt-get install -y libudev-dev
22+
- name: Run secure defaults audit
23+
run: cargo test --test secure_defaults_audit --locked
24+
1425
build:
1526
name: Build (${{ matrix.archive_name }}.${{ matrix.archive_ext }})
27+
needs: secure-defaults
1628
runs-on: ${{ matrix.os }}
1729
strategy:
1830
fail-fast: false
@@ -79,6 +91,23 @@ jobs:
7991
- name: Build
8092
run: cargo build --release --locked --target ${{ matrix.target }}
8193

94+
# RELEASE-BLOCKING for Windows: the publish job depends on this build
95+
# job, so a Windows binary that cannot start or whose --help/doctor
96+
# surface is broken stops the release here, before packaging.
97+
- name: Smoke test Windows binary
98+
if: runner.os == 'Windows'
99+
shell: pwsh
100+
run: pwsh -NoProfile -ExecutionPolicy Bypass -File tests/installer/windows_smoke.ps1 -Binary "target\${{ matrix.target }}\release\${{ matrix.binary_name }}"
101+
102+
- name: Upload Windows smoke logs
103+
if: failure() && runner.os == 'Windows'
104+
uses: actions/upload-artifact@v4
105+
with:
106+
name: windows-release-smoke-logs-${{ matrix.target }}
107+
path: windows-smoke.log
108+
retention-days: 14
109+
if-no-files-found: ignore
110+
82111
# Linux and macOS produce .tar.gz
83112
- name: Package binary (Linux / macOS)
84113
if: runner.os != 'Windows'

0 commit comments

Comments
 (0)