Skip to content
Open
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
75 changes: 75 additions & 0 deletions .github/actions/build-contracts/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Build Rust Contracts
description: Setup Rust toolchain, install Soroban CLI, cache dependencies, build contracts, and optionally upload artifacts

inputs:
rust-version:
description: Rust toolchain version
required: false
default: '1.88'
rust-components:
description: Comma-separated extra Rust components to install
required: false
default: ''
cargo-command:
description: Cargo command to run inside ./contracts
required: false
default: build --release
soroban-cli-version:
description: Soroban CLI version to install
required: false
default: latest
upload-artifact:
description: Whether to upload the build artifact
required: false
default: 'false'
artifact-name:
description: Name of the uploaded artifact
required: false
default: wasm-contracts
artifact-path:
description: Path to upload as artifact
required: false
default: contracts/target/wasm32-unknown-unknown/release/*.wasm

runs:
using: composite
steps:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ inputs.rust-version }}
components: ${{ inputs.rust-components }}

- name: Install Soroban CLI
shell: bash
run: |
if command -v soroban >/dev/null 2>&1; then
soroban --version
exit 0
fi
cargo install --locked --version "${{ inputs.soroban-cli-version }}" soroban-cli || cargo install --locked soroban-cli

- name: Cache Rust dependencies and target
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
contracts/target/
key: ${{ runner.os }}-cargo-${{ inputs.rust-version }}-${{ hashFiles('contracts/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ inputs.rust-version }}-

- name: Run cargo command
shell: bash
working-directory: ./contracts
run: cargo ${{ inputs.cargo-command }}

- name: Upload WASM artifact
if: inputs.upload-artifact == 'true'
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact-name }}
path: ${{ inputs.artifact-path }}
retention-days: 7
97 changes: 97 additions & 0 deletions .github/actions/deploy-service/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Deploy Service
description: Docker build, image push to registry, and Helm deploy with rollback on failure

inputs:
image-name:
description: Docker image name
required: true
image-tag:
description: Docker image tag
required: false
default: ${{ github.sha }}
registry:
description: Container registry host
required: false
default: ghcr.io
registry-username:
description: Registry login username
required: true
registry-password:
description: Registry login password / token
required: true
dockerfile:
description: Path to Dockerfile
required: false
default: Dockerfile
helm-chart:
description: Helm chart name or path
required: false
default: ''
helm-release:
description: Helm release name
required: false
default: ''
helm-namespace:
description: Kubernetes namespace
required: false
default: default
helm-values:
description: Extra --set flags for Helm deploy
required: false
default: ''
kubeconfig:
description: Base64-encoded kubeconfig
required: false
default: ''
rollback-on-failure:
description: Roll back Helm release when deploy fails
required: false
default: 'true'

runs:
using: composite
steps:
- name: Log in to container registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registry }}
username: ${{ inputs.registry-username }}
password: ${{ inputs.registry-password }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ${{ inputs.dockerfile }}
push: true
tags: |
${{ inputs.registry }}/${{ inputs.image-name }}:${{ inputs.image-tag }}
${{ inputs.registry }}/${{ inputs.image-name }}:latest

- name: Write kubeconfig
if: inputs.kubeconfig != ''
shell: bash
run: |
mkdir -p ~/.kube
printf '%s' "${{ inputs.kubeconfig }}" | base64 -d > ~/.kube/config
chmod 600 ~/.kube/config

- name: Helm deploy
if: inputs.helm-chart != '' && inputs.helm-release != ''
id: helm_deploy
shell: bash
run: |
set -euo pipefail
helm upgrade --install "${{ inputs.helm-release }}" "${{ inputs.helm-chart }}" \
--namespace "${{ inputs.helm-namespace }}" \
--set image.repository="${{ inputs.registry }}/${{ inputs.image-name }}" \
--set image.tag="${{ inputs.image-tag }}" \
${{ inputs.helm-values }} \
--atomic --timeout 5m \
--history-max 3

- name: Roll back Helm release
if: failure() && inputs.rollback-on-failure == 'true' && inputs.helm-chart != '' && inputs.helm-release != ''
shell: bash
run: |
helm rollback "${{ inputs.helm-release }}" --namespace "${{ inputs.helm-namespace }}" --wait || true
85 changes: 85 additions & 0 deletions .github/actions/run-tests/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Run Tests
description: Run test commands with optional coverage, JUnit report output, and artifact upload

inputs:
test-command:
description: Command to run tests
required: false
default: npm run test:shard
coverage:
description: Whether to collect coverage
required: false
default: 'true'
coverage-check:
description: Command that enforces coverage thresholds
required: false
default: npm run test:coverage
junit-report:
description: Whether to output a JUnit XML report
required: false
default: 'true'
junit-command:
description: Command used when JUnit output is requested
required: false
default: npx jest --ci --runInBand --reporters=default --reporters=jest-junit
upload-coverage:
description: Whether to upload coverage artifact
required: false
default: 'true'
coverage-artifact-name:
description: Artifact name for coverage report
required: false
default: coverage-report
coverage-path:
description: Path to the coverage report file
required: false
default: coverage/lcov.info
junit-path:
description: Path to the JUnit report file
required: false
default: test-results/junit.xml
upload-junit:
description: Whether to upload JUnit artifact
required: false
default: 'false'
junit-artifact-name:
description: Artifact name for JUnit report
required: false
default: junit-report

runs:
using: composite
steps:
- name: Run tests
shell: bash
env:
JEST_JUNIT_OUTPUT: ${{ inputs.junit-path }}
run: ${{ inputs.test-command }}

- name: Enforce coverage thresholds
if: inputs.coverage == 'true'
shell: bash
run: ${{ inputs.coverage-check }}

- name: Run JUnit report command
if: inputs.junit-report == 'true'
shell: bash
env:
JEST_JUNIT_OUTPUT: ${{ inputs.junit-path }}
run: ${{ inputs.junit-command }}

- name: Upload coverage report
if: inputs.upload-coverage == 'true' && always()
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.coverage-artifact-name }}
path: ${{ inputs.coverage-path }}
if-no-files-found: ignore

- name: Upload JUnit report
if: inputs.upload-junit == 'true' && always()
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.junit-artifact-name }}
path: ${{ inputs.junit-path }}
if-no-files-found: ignore
71 changes: 71 additions & 0 deletions .github/actions/setup-node/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Setup Node.js Environment
description: Checkout, setup Node.js with caching, install dependencies, and optionally generate .env from secrets

inputs:
node-version:
description: Node.js version to use
required: false
default: '20'
fetch-depth:
description: Number of commits to fetch (0 = full history)
required: false
default: '1'
github-token:
description: GitHub token for checkout
required: false
default: ''
registry-url:
description: npm registry URL (for publish jobs)
required: false
default: ''
env-file:
description: Path to write generated env content
required: false
default: .env
env-vars:
description: Newline-separated KEY=VALUE pairs to write into the env file
required: false
default: ''
install-command:
description: Dependency install command
required: false
default: npm ci --legacy-peer-deps

runs:
using: composite
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: ${{ inputs.fetch-depth }}
token: ${{ inputs.github-token != '' && inputs.github-token || github.token }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: npm
registry-url: ${{ inputs.registry-url }}

- name: Cache node modules
uses: actions/cache@v4
id: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-node-${{ inputs.node-version }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-${{ inputs.node-version }}-

- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
shell: bash
run: ${{ inputs.install-command }}

- name: Generate env file
if: inputs.env-vars != ''
shell: bash
env:
ACTION_ENV_FILE: ${{ inputs.env-file }}
run: |
mkdir -p "$(dirname "$ACTION_ENV_FILE")"
printf '%s\n' "${{ inputs.env-vars }}" > "$ACTION_ENV_FILE"
15 changes: 15 additions & 0 deletions .github/workflows/chaos-core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Chaos Core
on:
workflow_call:
jobs:
chaos-tests:
runs-on: ubuntu-latest
steps:
- uses: ./.github/actions/setup-node
- uses: ./.github/actions/run-tests
with:
test-command: npx jest --testPathPattern=chaos --no-coverage --ci
upload-coverage: 'false'
upload-junit: 'true'
junit-artifact-name: chaos-results
junit-path: chaos/
33 changes: 3 additions & 30 deletions .github/workflows/chaos.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,10 @@
name: Chaos Engineering

on:
push:
branches: [main, dev, develop, 'feature/*']
pull_request:
branches: [main, dev, develop, 'feature/*']

env:
NODE_VERSION: '20'

jobs:
chaos-tests:
name: Chaos Experiments
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'

- name: Install dependencies
run: npm ci --legacy-peer-deps

- name: Run chaos experiments
run: npx jest --testPathPattern=chaos --no-coverage --ci

- name: Upload chaos results
if: always()
uses: actions/upload-artifact@v4
with:
name: chaos-results
path: chaos/
chaos:
uses: ./.github/workflows/chaos-core.yml
secrets: inherit
Loading