Skip to content
Draft
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
103 changes: 103 additions & 0 deletions .github/actions/compute-matrix/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: 'Compute changed samples matrix'
description: >
Determines which sample directories from a given list have changed files
in the current push or pull_request event, and outputs a filtered JSON matrix.
Requires the calling job to have checked out the repository with fetch-depth: 0.

inputs:
all_samples:
description: >
Newline-separated list of sample directory paths to consider (the full matrix).
Paths should NOT include a trailing /** glob — the action matches by directory prefix.
Comment lines (starting with #) and blank lines are ignored.
required: true

outputs:
matrix:
description: >
Use this for single-dimension sample matrices.
JSON object {"sample":["path/a","path/b"]} - assign directly to the matrix: key using fromJson().
Returns the string "[]" when no samples changed (use in an if: guard to skip the job).
value: ${{ steps.filter.outputs.matrix }}
samples:
description: >
Use this for multi-dimensional matrices (e.g. os + sample, php-version + sample).
Plain JSON array ["path/a","path/b"] - assign to the sample: dimension only using fromJson().
Returns the string "[]" when no samples changed (use in an if: guard to skip the job).
value: ${{ steps.filter.outputs.samples }}

runs:
using: "composite"
steps:
- id: filter
shell: bash
env:
# For pull_request events, base.sha is the target branch tip (may be stale if base advanced).
# For push events, event.before is the previous HEAD (all-zeros for new branches).
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
HEAD_SHA: ${{ github.sha }}
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
# PR head SHA (only set for pull_request events). Used to isolate just the PR's changes
# via merge-base, avoiding false positives from unrelated base-branch advances.
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
ALL_SAMPLES: ${{ inputs.all_samples }}
run: |
RUN_ALL=false

# Resolve the base SHA — github.event.before is all zeros for brand-new branches
if [[ "$BASE_SHA" == "0000000000000000000000000000000000000000" ]] || [[ -z "$BASE_SHA" ]]; then
BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || echo "")
elif ! git cat-file -e "$BASE_SHA^{commit}" 2>/dev/null; then
# BASE_SHA is set but unreachable locally — happens after a force-push that rewrites
# history. git diff would fail and fall back to HEAD~1, which only sees the latest
# commit and can miss changes in earlier commits. Run all samples to be safe.
RUN_ALL=true
fi

# Get list of changed files relative to the base commit
if [[ "$RUN_ALL" == "false" ]]; then
if [[ -n "$PR_HEAD_SHA" ]]; then
# pull_request event: use merge-base to isolate only the PR's own changes.
# Diffing base.sha..merge_commit would include unrelated changes from the base
# branch that landed after the PR was last synchronised. Using merge-base gives
# only the commits that are in the PR branch but not in the base branch.
MERGE_BASE=$(git merge-base "$PR_HEAD_SHA" "$BASE_SHA" 2>/dev/null || echo "")
if [[ -n "$MERGE_BASE" ]]; then
CHANGED=$(git diff --name-only "$MERGE_BASE" "$PR_HEAD_SHA")
else
CHANGED=$(git diff --name-only "$BASE_SHA" "$PR_HEAD_SHA" 2>/dev/null || git diff --name-only HEAD~1 HEAD)
fi
elif [[ -n "$BASE_SHA" ]]; then
# push event: diff from the previous HEAD
CHANGED=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" 2>/dev/null || git diff --name-only HEAD~1 HEAD)
else
CHANGED=$(git diff --name-only HEAD~1 HEAD)
fi
fi

# Filter: keep only sample dirs where at least one changed file lives inside them
RESULT=()
while IFS= read -r sample; do
# Strip leading/trailing whitespace
sample="${sample#"${sample%%[![:space:]]*}"}"
sample="${sample%"${sample##*[![:space:]]}"}"
# Skip blank lines and comment lines
if [[ -z "$sample" ]] || [[ "$sample" == \#* ]]; then continue; fi
# Normalise: strip any accidental trailing slash (paths: uses /**, all_samples: should not)
sample="${sample%/}"

# A file belongs to a sample dir if its path starts with "<sample>/"
if [[ "$RUN_ALL" == "true" ]] || echo "$CHANGED" | grep -q "^${sample}/"; then
RESULT+=("$sample")
fi
done <<< "$ALL_SAMPLES"

# Emit both output formats
if [[ ${#RESULT[@]} -eq 0 ]]; then
echo 'matrix=[]' >> "$GITHUB_OUTPUT"
echo 'samples=[]' >> "$GITHUB_OUTPUT"
else
SAMPLES_ARRAY=$(printf '%s\n' "${RESULT[@]}" | jq -R . | jq -sc .)
echo "matrix={\"sample\":${SAMPLES_ARRAY}}" >> "$GITHUB_OUTPUT"
echo "samples=${SAMPLES_ARRAY}" >> "$GITHUB_OUTPUT"
fi

31 changes: 31 additions & 0 deletions .github/workflows/linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,40 @@ on:
- '[5-9]+.[0-9]+.x'

jobs:
setup:
name: Detect source changes
runs-on: ubuntu-latest
outputs:
source-changed: ${{ steps.check.outputs.source-changed }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: check
shell: bash
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
HEAD_SHA: ${{ github.sha }}
run: |
if [[ "$BASE_SHA" == "0000000000000000000000000000000000000000" ]] || [[ -z "$BASE_SHA" ]]; then
BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || echo "")
fi
if [[ -n "$BASE_SHA" ]]; then
CHANGED=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" 2>/dev/null || git diff --name-only HEAD~1 HEAD)
else
CHANGED=$(git diff --name-only HEAD~1 HEAD)
fi
if echo "$CHANGED" | grep -qE '^(modules/|pom\.xml|\.mvn/)'; then
echo "source-changed=true" >> "$GITHUB_OUTPUT"
else
echo "source-changed=false" >> "$GITHUB_OUTPUT"
fi

build:
name: 'Build: JDK ${{ matrix.java }} (${{ matrix.os }})'
runs-on: ${{ matrix.os }}
needs: setup
if: needs.setup.outputs.source-changed == 'true'
strategy:
matrix:
java: [11, 17]
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/openapi-generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,40 @@ on:
- '[5-9]+.[0-9]+.x'

jobs:
# Detect whether source files (modules/, pom.xml) changed.
# When only samples/ or bin/configs/ changed, the unit tests and doc checks are skipped —
# they are not affected by sample or config-only changes. The samples job still runs to
# verify freshness. Nothing in bin/ affects mvn test; those scripts are used by the
# documentation and samples jobs which run unconditionally.
setup:
name: Detect source changes
runs-on: ubuntu-latest
outputs:
source-changed: ${{ steps.check.outputs.source-changed }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: check
shell: bash
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
HEAD_SHA: ${{ github.sha }}
run: |
if [[ "$BASE_SHA" == "0000000000000000000000000000000000000000" ]] || [[ -z "$BASE_SHA" ]]; then
BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || echo "")
fi
if [[ -n "$BASE_SHA" ]]; then
CHANGED=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" 2>/dev/null || git diff --name-only HEAD~1 HEAD)
else
CHANGED=$(git diff --name-only HEAD~1 HEAD)
fi
if echo "$CHANGED" | grep -qE '^(modules/|pom\.xml|\.mvn/)'; then
echo "source-changed=true" >> "$GITHUB_OUTPUT"
else
echo "source-changed=false" >> "$GITHUB_OUTPUT"
fi

build:
name: Build
runs-on: ubuntu-latest
Expand Down Expand Up @@ -52,7 +86,10 @@ jobs:
name: Unit tests
runs-on: ubuntu-latest
needs:
- setup
- build
# Unit tests are not affected by sample-only changes — skip to save CI time.
if: needs.setup.outputs.source-changed == 'true'
steps:
- uses: actions/checkout@v5
- name: Set up JDK 11
Expand Down Expand Up @@ -90,7 +127,10 @@ jobs:
name: Docs up-to-date
runs-on: ubuntu-latest
needs:
- setup
- build
# Docs are generated from codegen metadata — skipped when only samples changed.
if: needs.setup.outputs.source-changed == 'true'
steps:
- uses: actions/checkout@v5
- name: Set up JDK 11
Expand Down
37 changes: 28 additions & 9 deletions .github/workflows/samples-aspnet-fastenpoints-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,47 @@ name: Samples C# .Net 8 FastEndpoints Server

on:
push:
# Determines whether this workflow fires at all. Keep in sync with all_samples: in the setup job below.
paths:
- samples/server/petstore/aspnet/fastendpoints/**
- samples/server/petstore/aspnet/fastendpoints-*/**
pull_request:
# Determines whether this workflow fires at all. Keep in sync with all_samples: in the setup job below.
paths:
- samples/server/petstore/aspnet/fastendpoints/**
- samples/server/petstore/aspnet/fastendpoints-*/**
jobs:
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.filter.outputs.matrix }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: filter
uses: ./.github/actions/compute-matrix
with:
# List of sample directories to consider building (one per line).
# Action inputs don't support arrays, so this is a newline-delimited string parsed in the action script.
# To add a new sample: add it here AND add a matching entry to the paths: trigger above.
all_samples: |
samples/server/petstore/aspnet/fastendpoints
samples/server/petstore/aspnet/fastendpoints-useApiVersioning
samples/server/petstore/aspnet/fastendpoints-useAuthentication
samples/server/petstore/aspnet/fastendpoints-useProblemDetails
samples/server/petstore/aspnet/fastendpoints-useRecords
samples/server/petstore/aspnet/fastendpoints-useResponseCaching
samples/server/petstore/aspnet/fastendpoints-useValidators

build:
name: Build .Net 8 FastEndpoints servers
needs: setup
if: ${{ needs.setup.outputs.matrix != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
- samples/server/petstore/aspnet/fastendpoints
- samples/server/petstore/aspnet/fastendpoints-useApiVersioning
- samples/server/petstore/aspnet/fastendpoints-useAuthentication
- samples/server/petstore/aspnet/fastendpoints-useProblemDetails
- samples/server/petstore/aspnet/fastendpoints-useRecords
- samples/server/petstore/aspnet/fastendpoints-useResponseCaching
- samples/server/petstore/aspnet/fastendpoints-useValidators
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
steps:
- uses: actions/checkout@v5
- uses: actions/setup-dotnet@v5.3.0
Expand Down
29 changes: 24 additions & 5 deletions .github/workflows/samples-c-libcurl-client.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,46 @@ name: Samples c libcurl client

on:
push:
# Determines whether this workflow fires at all. Keep in sync with all_samples: in the setup job below.
paths:
- 'samples/client/petstore/c/**'
- 'samples/client/petstore/c-useJsonUnformatted/**'
- 'samples/client/others/c/bearerAuth/**'
pull_request:
# Determines whether this workflow fires at all. Keep in sync with all_samples: in the setup job below.
paths:
- 'samples/client/petstore/c/**'
- 'samples/client/petstore/c-useJsonUnformatted/**'
- 'samples/client/others/c/bearerAuth/**'

jobs:
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.filter.outputs.matrix }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: filter
uses: ./.github/actions/compute-matrix
with:
# List of sample directories to consider building (one per line).
# Action inputs don't support arrays, so this is a newline-delimited string parsed in the action script.
# To add a new sample: add it here AND add a matching entry to the paths: trigger above.
all_samples: |
samples/client/petstore/c
samples/client/petstore/c-useJsonUnformatted
samples/client/others/c/bearerAuth
build:
name: Build c libcurl client
needs: setup
if: ${{ needs.setup.outputs.matrix != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
- 'samples/client/petstore/c/'
- 'samples/client/petstore/c-useJsonUnformatted/'
- 'samples/client/others/c/bearerAuth/'
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}

steps:
- uses: actions/checkout@v5
Expand Down
25 changes: 22 additions & 3 deletions .github/workflows/samples-clojure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,39 @@ name: Samples Clojure Client

on:
push:
# Determines whether this workflow fires at all. Keep in sync with all_samples: in the setup job below.
paths:
- samples/client/petstore/clojure/**
pull_request:
# Determines whether this workflow fires at all. Keep in sync with all_samples: in the setup job below.
paths:
- samples/client/petstore/clojure/**
jobs:
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.filter.outputs.matrix }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: filter
uses: ./.github/actions/compute-matrix
with:
# List of sample directories to consider building (one per line).
# Action inputs don't support arrays, so this is a newline-delimited string parsed in the action script.
# To add a new sample: add it here AND add a matching entry to the paths: trigger above.
all_samples: |
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
samples/client/petstore/clojure

build:
name: Build Clojure Client (JDK11)
needs: setup
if: ${{ needs.setup.outputs.matrix != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
- samples/client/petstore/clojure/
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
services:
petstore-api:
image: swaggerapi/petstore
Expand Down
Loading
Loading