Skip to content

Commit 9bd1c7d

Browse files
authored
Merge pull request #6 from gragra33/feature/github-actions
feat: add GitHub Actions CI/CD workflows and local test runner
2 parents 573be75 + 23170af commit 9bd1c7d

6 files changed

Lines changed: 510 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
- "feature/**"
8+
- "fix/**"
9+
- "hotfix/**"
10+
pull_request:
11+
branches:
12+
- develop
13+
- master
14+
15+
# Declared here so actionlint can validate env.RUNNING_LOCALLY references below.
16+
# ci-cd-test-run.ps1 passes --env RUNNING_LOCALLY=true to act; on real GitHub Actions
17+
# the variable is empty so upload-artifact runs and failures are fatal.
18+
env:
19+
RUNNING_LOCALLY: ""
20+
21+
jobs:
22+
validate-branch:
23+
name: Validate Branch Name
24+
runs-on: ubuntu-latest
25+
if: github.event_name == 'pull_request'
26+
steps:
27+
- name: Check branch naming convention
28+
env:
29+
BRANCH: ${{ github.head_ref }}
30+
run: |
31+
if [[ ! "$BRANCH" =~ ^(feature|fix|hotfix)/.+ ]] && [[ "$BRANCH" != "develop" ]]; then
32+
echo "::error::Branch '$BRANCH' does not follow naming conventions."
33+
echo "::error::PR source branches must be 'develop' or prefixed with 'feature/', 'fix/', or 'hotfix/'."
34+
exit 1
35+
fi
36+
echo "Branch '$BRANCH' follows naming conventions."
37+
38+
build-and-test:
39+
name: Build & Test
40+
needs: validate-branch
41+
# Run on push events (validate-branch skipped) OR on valid PRs (validate-branch succeeded)
42+
if: always() && (needs.validate-branch.result == 'success' || needs.validate-branch.result == 'skipped')
43+
runs-on: ubuntu-latest
44+
steps:
45+
- uses: actions/checkout@v5
46+
47+
- name: Setup .NET
48+
uses: actions/setup-dotnet@v5
49+
with:
50+
dotnet-version: |
51+
10.0.x
52+
53+
- name: Restore
54+
run: dotnet restore Blazing.Json.Queryable.slnx
55+
56+
- name: Build
57+
run: dotnet build Blazing.Json.Queryable.slnx --no-restore --configuration Release -p:GeneratePackageOnBuild=false
58+
59+
- name: Test
60+
run: |
61+
dotnet test tests/Blazing.Json.Queryable.Tests/Blazing.Json.Queryable.Tests.csproj \
62+
--no-build --no-restore \
63+
--configuration Release \
64+
--logger "trx;LogFileName=test-results.trx"
65+
66+
- name: Upload test results
67+
uses: actions/upload-artifact@v7
68+
# Skipped when running locally (ci-cd-test-run.ps1 passes --env RUNNING_LOCALLY=true to act).
69+
# On real GitHub Actions RUNNING_LOCALLY is empty → step runs; upload failures are fatal.
70+
if: always() && env.RUNNING_LOCALLY == ''
71+
with:
72+
name: test-results
73+
path: "**/*.trx"

.github/workflows/release.yml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
release:
10+
name: Build, Test & Publish to NuGet
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
steps:
15+
- uses: actions/checkout@v5
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Setup .NET
20+
uses: actions/setup-dotnet@v5
21+
with:
22+
dotnet-version: |
23+
10.0.x
24+
25+
- name: Restore
26+
run: dotnet restore Blazing.Json.Queryable.slnx
27+
28+
- name: Build
29+
run: dotnet build Blazing.Json.Queryable.slnx --no-restore --configuration Release -p:GeneratePackageOnBuild=false
30+
31+
- name: Test
32+
run: |
33+
dotnet test tests/Blazing.Json.Queryable.Tests/Blazing.Json.Queryable.Tests.csproj \
34+
--no-build --no-restore \
35+
--configuration Release
36+
37+
- name: Extract version from project file
38+
id: version
39+
run: |
40+
VERSION=$(grep -m1 '<Version>' src/Blazing.Json.Queryable/Blazing.Json.Queryable.csproj \
41+
| sed 's/.*<Version>//;s/<\/Version>.*//' \
42+
| tr -d '[:space:]')
43+
echo "version=$VERSION" >> $GITHUB_OUTPUT
44+
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
45+
echo "Resolved version: $VERSION"
46+
47+
- name: Check if this version was already released
48+
id: tag_check
49+
run: |
50+
if git ls-remote --tags origin "refs/tags/v${{ steps.version.outputs.version }}" | grep -q .; then
51+
echo "exists=true" >> $GITHUB_OUTPUT
52+
else
53+
echo "exists=false" >> $GITHUB_OUTPUT
54+
fi
55+
56+
- name: Pack NuGet package
57+
if: steps.tag_check.outputs.exists == 'false'
58+
run: |
59+
dotnet pack src/Blazing.Json.Queryable/Blazing.Json.Queryable.csproj \
60+
--no-build --no-restore --configuration Release --output ./artifacts
61+
62+
- name: Create GitHub Release
63+
if: steps.tag_check.outputs.exists == 'false'
64+
env:
65+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
66+
run: |
67+
gh release create "${{ steps.version.outputs.tag }}" \
68+
--title "Release ${{ steps.version.outputs.tag }}" \
69+
--generate-notes \
70+
./artifacts/Blazing.Json.Queryable.${{ steps.version.outputs.version }}.nupkg \
71+
./artifacts/Blazing.Json.Queryable.${{ steps.version.outputs.version }}.snupkg
72+
73+
- name: Push Blazing.Json.Queryable to NuGet.org
74+
if: steps.tag_check.outputs.exists == 'false'
75+
run: |
76+
dotnet nuget push \
77+
"./artifacts/Blazing.Json.Queryable.${{ steps.version.outputs.version }}.nupkg" \
78+
--api-key ${{ secrets.NUGET_API_KEY }} \
79+
--source https://api.nuget.org/v3/index.json \
80+
--skip-duplicate
81+
82+
- name: Push Blazing.Json.Queryable symbols to NuGet.org
83+
if: steps.tag_check.outputs.exists == 'false'
84+
run: |
85+
dotnet nuget push \
86+
"./artifacts/Blazing.Json.Queryable.${{ steps.version.outputs.version }}.snupkg" \
87+
--api-key ${{ secrets.NUGET_API_KEY }} \
88+
--source https://api.nuget.org/v3/index.json \
89+
--skip-duplicate

0 commit comments

Comments
 (0)