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
271 changes: 150 additions & 121 deletions .github/workflows/rust.yml → .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# CI pipeline for the Rust implementation
---
# yamllint disable rule:truthy rule:line-length
# CI pipeline for PRs (lint, test, coverage, sonar) and tag release builds.
name: CI Pipeline

on:
push:
pull_request:
branches:
- main
- master
- develop
push:
tags:
- "v*"

Expand All @@ -17,7 +20,6 @@ jobs:
dictionaries:
name: Prepare FIX specs
runs-on: ubuntu-latest
# Specs are needed for all flows.
steps:
- uses: actions/checkout@v4
- name: Download FIX XML dictionaries
Expand All @@ -29,119 +31,18 @@ jobs:
name: fix-specs
path: resources

build-matrix:
name: Build release (tags only)
strategy:
fail-fast: true
matrix:
include:
- os: macos-latest
target: aarch64-apple-darwin
artifact_path: target/aarch64-apple-darwin/release/fixdecoder
asset_suffix: darwin-arm64
ext: ""
- os: macos-15-intel
target: x86_64-apple-darwin
artifact_path: target/x86_64-apple-darwin/release/fixdecoder
asset_suffix: darwin-x86_64
ext: ""
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_path: target/x86_64-pc-windows-msvc/release/fixdecoder.exe
asset_suffix: windows-x86_64
ext: ".exe"
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_path: target/x86_64-unknown-linux-gnu/release/fixdecoder
asset_suffix: linux-gnu-x86_64
ext: ""
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
setup: sudo apt-get update && sudo apt-get install -y musl-tools
artifact_path: target/x86_64-unknown-linux-musl/release/fixdecoder
asset_suffix: linux-musl-x86_64
ext: ""
runs-on: ${{ matrix.os }}
needs: [dictionaries]
# Only build release artifacts when tagging; skips lint/coverage.
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
env:
FIXDECODER_BRANCH: ${{ github.ref_name }}
FIXDECODER_COMMIT: ${{ github.sha }}
FIXDECODER_GIT_URL: https://github.com/${{ github.repository }}
steps:
- uses: actions/checkout@v4
- name: Compute lockfile hash
id: lockfile-hash
shell: bash
run: |
if command -v python3 >/dev/null 2>&1; then
python3 ci/compute_lockfile_hash.py Cargo.lock
elif command -v python >/dev/null 2>&1; then
python ci/compute_lockfile_hash.py Cargo.lock
else
echo "Python is required to compute the lockfile hash." >&2
exit 1
fi
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy,rustfmt,llvm-tools-preview
targets: ${{ matrix.target }}
- name: Download FIX specs artifact
uses: actions/download-artifact@v4
with:
name: fix-specs
path: resources
- name: Cache cargo registry and target
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ steps.lockfile-hash.outputs.hash }}
restore-keys: |
${{ runner.os }}-${{ matrix.target }}-cargo-
${{ runner.os }}-cargo-
- name: Install target dependencies
if: ${{ matrix.setup != '' }}
run: ${{ matrix.setup }}
- name: Prepare build inputs
shell: bash
run: |
source ci/ci_helper.sh
ensure_build_metadata
cargo run --quiet --bin generate_sensitive_tags >/dev/null
- name: Build release
shell: bash
run: |
if [[ "${{ matrix.target }}" == "x86_64-unknown-linux-musl" ]]; then
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-C target-feature=+crt-static"
fi
cargo fmt --all
cargo build --release --locked --target ${{ matrix.target }}
env:
RUSTFLAGS: ""
- name: Stage artifact
shell: bash
run: |
mkdir -p dist
cp "${{ matrix.artifact_path }}" "dist/fixdecoder-${{ matrix.asset_suffix }}${{ matrix.ext }}"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: fixdecoder-${{ matrix.asset_suffix }}
path: dist/fixdecoder-${{ matrix.asset_suffix }}${{ matrix.ext }}

quality:
name: Lint & Coverage
runs-on: ubuntu-latest
needs: dictionaries
# Run on branch pushes for fast feedback (debug build + coverage); skip tags.
if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- name: Lint workflow YAML
run: |
python3 -m pip install --upgrade pip
python3 -m pip install yamllint
yamllint .github/workflows
- name: Compute lockfile hash
id: lockfile-hash
shell: bash
Expand Down Expand Up @@ -225,8 +126,7 @@ jobs:
name: Sonar (coverage import)
runs-on: ubuntu-latest
needs: [quality]
# Run for branch pushes (not tags) when a token is available.
if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- name: Determine toolchain channel
Expand All @@ -240,6 +140,9 @@ jobs:
toolchain=$(head -n1 rust-toolchain | tr -d '[:space:]')
fi
echo "toolchain=$toolchain" >> "$GITHUB_OUTPUT"
- name: Ensure cache directories exist
run: |
mkdir -p "$HOME/.cargo/bin" "$HOME/.rustup"
- name: Compute lockfile hash
id: lockfile-hash
run: echo "hash=$(sha256sum Cargo.lock | cut -d ' ' -f1)" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -287,11 +190,135 @@ jobs:
echo "[]" > target/clippy.json
fi
CLIPPY_REPORT="$(pwd)/target/clippy.json"
PR_OPTS=()
if [ "${{ github.event_name }}" = "pull_request" ]; then
PR_OPTS+=("-Dsonar.pullrequest.key=${{ github.event.pull_request.number }}")
PR_OPTS+=("-Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }}")
PR_OPTS+=("-Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }}")
PR_OPTS+=("-Dsonar.pullrequest.provider=github")
fi
sonar-scanner \
-Dsonar.host.url=https://sonarcloud.io \
-Dsonar.externalIssuesReportPaths=target/coverage/sonar-generic-issues.json \
-Dsonar.rust.clippy.reportPaths="${CLIPPY_REPORT}" \
-Dsonar.rust.clippy.enabled=false
-Dsonar.rust.clippy.enabled=false \
"${PR_OPTS[@]}"

build-matrix:
name: Build release (tags only)
strategy:
fail-fast: true
matrix:
include:
- os: macos-latest
target: aarch64-apple-darwin
artifact_path: target/aarch64-apple-darwin/release/fixdecoder
asset_suffix: darwin-arm64
ext: ""
- os: macos-15-intel
target: x86_64-apple-darwin
artifact_path: target/x86_64-apple-darwin/release/fixdecoder
asset_suffix: darwin-x86_64
ext: ""
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact_path: target/x86_64-pc-windows-msvc/release/fixdecoder.exe
asset_suffix: windows-x86_64
ext: ".exe"
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact_path: target/x86_64-unknown-linux-gnu/release/fixdecoder
asset_suffix: linux-gnu-x86_64
ext: ""
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
setup: sudo apt-get update && sudo apt-get install -y musl-tools
artifact_path: target/x86_64-unknown-linux-musl/release/fixdecoder
asset_suffix: linux-musl-x86_64
ext: ""
runs-on: ${{ matrix.os }}
needs: [dictionaries]
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
env:
FIXDECODER_BRANCH: ${{ github.ref_name }}
FIXDECODER_COMMIT: ${{ github.sha }}
FIXDECODER_GIT_URL: https://github.com/${{ github.repository }}
steps:
- uses: actions/checkout@v4
- name: Compute lockfile hash
id: lockfile-hash
shell: bash
run: |
if command -v python3 >/dev/null 2>&1; then
python3 ci/compute_lockfile_hash.py Cargo.lock
elif command -v python >/dev/null 2>&1; then
python ci/compute_lockfile_hash.py Cargo.lock
else
echo "Python is required to compute the lockfile hash." >&2
exit 1
fi
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy,rustfmt,llvm-tools-preview
targets: ${{ matrix.target }}
- name: Download FIX specs artifact
uses: actions/download-artifact@v4
with:
name: fix-specs
path: resources
- name: Cache cargo registry and target
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ steps.lockfile-hash.outputs.hash }}
restore-keys: |
${{ runner.os }}-${{ matrix.target }}-cargo-
${{ runner.os }}-cargo-
- name: Install target dependencies
if: ${{ matrix.setup != '' }}
run: ${{ matrix.setup }}
- name: Prepare build inputs
shell: bash
run: |
source ci/ci_helper.sh
ensure_build_metadata
cargo run --quiet --bin generate_sensitive_tags >/dev/null
- name: Build release
shell: bash
run: |
if [[ "${{ matrix.target }}" == "x86_64-unknown-linux-musl" ]]; then
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-C target-feature=+crt-static"
fi
cargo fmt --all
cargo build --release --locked --workspace --target ${{ matrix.target }}
env:
RUSTFLAGS: ""
- name: Stage artifact
shell: bash
run: |
mkdir -p dist
cp "${{ matrix.artifact_path }}" "dist/fixdecoder-${{ matrix.asset_suffix }}${{ matrix.ext }}"
pcap_path="target/${{ matrix.target }}/release/pcap2fix${{ matrix.ext }}"
if [ -f "$pcap_path" ]; then
cp "$pcap_path" "dist/pcap2fix-${{ matrix.asset_suffix }}${{ matrix.ext }}"
else
echo "pcap2fix binary not found at $pcap_path" >&2
exit 1
fi
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: fixdecoder-${{ matrix.asset_suffix }}
path: dist/fixdecoder-${{ matrix.asset_suffix }}${{ matrix.ext }}
- name: Upload pcap2fix artifact
uses: actions/upload-artifact@v4
with:
name: pcap2fix-${{ matrix.asset_suffix }}
path: dist/pcap2fix-${{ matrix.asset_suffix }}${{ matrix.ext }}

release:
name: Publish Release
Expand Down Expand Up @@ -321,24 +348,26 @@ jobs:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
pattern: fixdecoder-*
pattern: "*"
path: dist
merge-multiple: true
- name: Rename artifacts with version
run: |
ver="${{ steps.version.outputs.version }}"
shopt -s nullglob
for f in dist/fixdecoder-*; do
for f in dist/fixdecoder-* dist/pcap2fix-*; do
base="${f##*/}"
case "$base" in
fixdecoder-*.exe)
suffix="${base#fixdecoder-}"
fixdecoder-*.exe|pcap2fix-*.exe)
prefix="${base%%-*}"
suffix="${base#${prefix}-}"
suffix="${suffix%.exe}"
mv "$f" "dist/fixdecoder-${ver}.${suffix}.exe"
mv "$f" "dist/${prefix}-${ver}.${suffix}.exe"
;;
fixdecoder-*)
suffix="${base#fixdecoder-}"
mv "$f" "dist/fixdecoder-${ver}.${suffix}"
fixdecoder-*|pcap2fix-*)
prefix="${base%%-*}"
suffix="${base#${prefix}-}"
mv "$f" "dist/${prefix}-${ver}.${suffix}"
;;
esac
done
Expand Down
Loading