Skip to content

Commit 3347df4

Browse files
committed
Update pipeline
1 parent dda7af9 commit 3347df4

10 files changed

Lines changed: 270 additions & 8 deletions

File tree

.github/scripts/generate-changelog.sh

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,30 @@ MISC=""
4444
for commit_hash in "${COMMITS[@]}"; do
4545
commit_msg=$(git log -1 --pretty=format:'%s' "$commit_hash")
4646
commit_body=$(git log -1 --pretty=format:'%b' "$commit_hash")
47-
# Extract changelog type using awk (case-insensitive, robust)
48-
changelog_type=$(echo "$commit_body" | awk 'BEGIN{IGNORECASE=1} /changelog[(: ]/ {if ($0 ~ /feature/) print "feature"; else if ($0 ~ /fix/) print "fix"; else if ($0 ~ /misc/) print "misc"; exit}')
47+
# Extract changelog type from subject or body (case-insensitive, robust)
48+
changelog_type=""
49+
# Check subject first
50+
if echo "$commit_msg" | grep -iqE 'changelog[(: ]'; then
51+
if echo "$commit_msg" | grep -iqE 'changelog\((feature|feat)\)'; then
52+
changelog_type="feature"
53+
elif echo "$commit_msg" | grep -iqE 'changelog\((fix)\)'; then
54+
changelog_type="fix"
55+
elif echo "$commit_msg" | grep -iqE 'changelog\((misc)\)'; then
56+
changelog_type="misc"
57+
fi
58+
fi
59+
# If not found in subject, check body
60+
if [ -z "$changelog_type" ]; then
61+
if echo "$commit_body" | grep -iqE 'changelog[(: ]'; then
62+
if echo "$commit_body" | grep -iqE 'changelog\((feature|feat)\)'; then
63+
changelog_type="feature"
64+
elif echo "$commit_body" | grep -iqE 'changelog\((fix)\)'; then
65+
changelog_type="fix"
66+
elif echo "$commit_body" | grep -iqE 'changelog\((misc)\)'; then
67+
changelog_type="misc"
68+
fi
69+
fi
70+
fi
4971
if [ -n "$changelog_type" ]; then
5072
body_content=$(echo "$commit_body" | awk 'BEGIN{IGNORECASE=1} !/changelog[(: ]/ && NF')
5173
entry="- $commit_msg"

.github/workflows/clients_ci.yml

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
name: SDK CI
2+
3+
on:
4+
pull_request:
5+
branches: ["**"]
6+
workflow_call:
7+
inputs:
8+
artifact_suffix:
9+
required: false
10+
type: string
11+
default: ""
12+
description: "Suffix to add to artifact names"
13+
upload_artifacts:
14+
required: false
15+
type: boolean
16+
default: false
17+
description: "Whether to upload SDK artifacts"
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
sdk:
24+
name: Codegen and smoke builds
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@v4
29+
30+
- name: Set up Go
31+
uses: actions/setup-go@v5
32+
with:
33+
go-version: stable
34+
cache: true
35+
cache-dependency-path: |
36+
viiper/go.sum
37+
38+
- name: Run code generation
39+
working-directory: viiper
40+
run: go run ./cmd/viiper codegen
41+
42+
- name: Set up Node.js
43+
uses: actions/setup-node@v4
44+
with:
45+
node-version: '24'
46+
cache: 'npm'
47+
cache-dependency-path: |
48+
clients/typescript/package-lock.json
49+
examples/typescript/package-lock.json
50+
51+
- name: Build TypeScript SDK
52+
working-directory: clients/typescript
53+
run: |
54+
npm install
55+
npm run build
56+
npm pack
57+
58+
- name: Build TypeScript examples (smoke)
59+
working-directory: examples/typescript
60+
run: |
61+
npm install
62+
npm run build
63+
64+
- name: Set up .NET SDK
65+
uses: actions/setup-dotnet@v4
66+
with:
67+
dotnet-version: '8.0.x'
68+
69+
- name: Pack C# SDK (smoke)
70+
run: dotnet pack clients/csharp/Viiper.Client/Viiper.Client.csproj -c Release -o artifacts/nuget
71+
72+
- name: Build C# examples (smoke)
73+
run: |
74+
dotnet build examples/csharp/virtual_keyboard/VirtualKeyboard.csproj -c Release
75+
dotnet build examples/csharp/virtual_mouse/VirtualMouse.csproj -c Release
76+
dotnet build examples/csharp/virtual_x360_pad/VirtualX360Pad.csproj -c Release
77+
78+
- name: Set up CMake
79+
uses: jwlawson/actions-setup-cmake@v2
80+
with:
81+
cmake-version: '3.26.x'
82+
83+
- name: Build C SDK (smoke)
84+
run: |
85+
cmake -S clients/c -B clients/c/build
86+
cmake --build clients/c/build --config Release --parallel
87+
88+
- name: Rename TypeScript SDK tarball
89+
if: ${{ inputs.upload_artifacts }}
90+
working-directory: clients/typescript
91+
run: |
92+
for file in viiperclient-*.tgz; do
93+
if [ -f "$file" ]; then
94+
mv "$file" "viiperclient-typescript-sdk${{ inputs.artifact_suffix }}.tgz"
95+
fi
96+
done
97+
98+
- name: Upload TypeScript SDK tarball
99+
if: ${{ inputs.upload_artifacts }}
100+
uses: actions/upload-artifact@v4
101+
with:
102+
name: typescript-sdk${{ inputs.artifact_suffix }}
103+
path: clients/typescript/viiperclient-typescript-sdk${{ inputs.artifact_suffix }}.tgz
104+
if-no-files-found: error
105+
106+
- name: Upload C# SDK nupkg
107+
if: ${{ inputs.upload_artifacts }}
108+
uses: actions/upload-artifact@v4
109+
with:
110+
name: csharp-sdk-nupkg${{ inputs.artifact_suffix }}
111+
path: artifacts/nuget/*.nupkg
112+
if-no-files-found: error
113+
114+
- name: Archive C SDK source
115+
if: ${{ inputs.upload_artifacts }}
116+
run: tar -czf c-sdk-source${{ inputs.artifact_suffix }}.tar.gz -C clients/c .
117+
118+
- name: Upload C SDK source
119+
if: ${{ inputs.upload_artifacts }}
120+
uses: actions/upload-artifact@v4
121+
with:
122+
name: c-sdk-source${{ inputs.artifact_suffix }}
123+
path: c-sdk-source${{ inputs.artifact_suffix }}.tar.gz
124+
if-no-files-found: error

.github/workflows/release.yml

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77

88
permissions:
99
contents: write
10+
id-token: write
1011

1112
jobs:
1213
build:
@@ -23,9 +24,16 @@ jobs:
2324
mode: release
2425
tag_name: ${{ github.ref_name }}
2526

27+
client-sdks:
28+
name: SDK smoke builds and pack
29+
uses: ./.github/workflows/clients_ci.yml
30+
with:
31+
artifact_suffix: "-Release"
32+
upload_artifacts: true
33+
2634
create-release:
2735
name: Create Release
28-
needs: [build, generate-changelog]
36+
needs: [build, generate-changelog, client-sdks]
2937
runs-on: ubuntu-latest
3038
steps:
3139
- name: Checkout code
@@ -50,10 +58,15 @@ jobs:
5058
name_no_suffix="${base%-Release}"
5159
for file in "$dir"/*; do
5260
if [ -f "$file" ]; then
53-
ext="${file##*.}"
61+
filename="$(basename "$file")"
62+
if [[ "$filename" == *.tar.gz ]]; then
63+
ext="tar.gz"
64+
else
65+
ext="${filename##*.}"
66+
fi
5467
fname="viiper-${name_no_suffix#VIIPER-}"
5568
# Preserve extension (avoid duplicating extension for non-dot cases)
56-
if [[ "$file" == *.* ]]; then
69+
if [[ "$filename" == *.* ]]; then
5770
cp "$file" "release_files/${fname}.${ext}"
5871
else
5972
cp "$file" "release_files/${fname}"
@@ -64,6 +77,44 @@ jobs:
6477
done
6578
ls -la release_files/
6679
80+
- name: Set up Node.js (for npm publish)
81+
uses: actions/setup-node@v4
82+
with:
83+
node-version: '24'
84+
registry-url: 'https://registry.npmjs.org/'
85+
86+
- name: Set up .NET SDK (for NuGet publish)
87+
uses: actions/setup-dotnet@v4
88+
with:
89+
dotnet-version: '8.0.x'
90+
91+
# Publish SDKs to npm and NuGet using OIDC trusted publishing
92+
- name: Publish TypeScript SDK to npm
93+
working-directory: release_files
94+
shell: bash
95+
run: |
96+
set -euo pipefail
97+
TS_TARBALL="viiper-typescript-sdk.tgz"
98+
if [ ! -f "$TS_TARBALL" ]; then
99+
echo "ERROR: Missing TypeScript SDK tarball: $TS_TARBALL" >&2
100+
ls -la
101+
exit 1
102+
fi
103+
npm publish "$TS_TARBALL" --provenance --access public
104+
105+
- name: Publish C# SDK to NuGet
106+
working-directory: release_files
107+
shell: bash
108+
run: |
109+
set -euo pipefail
110+
NUPKG="viiper-csharp-sdk-nupkg.nupkg"
111+
if [ ! -f "$NUPKG" ]; then
112+
echo "ERROR: Missing C# SDK package: $NUPKG" >&2
113+
ls -la
114+
exit 1
115+
fi
116+
dotnet nuget push "$NUPKG" --source https://api.nuget.org/v3/index.json --skip-duplicate
117+
67118
- name: Extract build info
68119
id: build_info
69120
shell: bash
@@ -94,7 +145,7 @@ jobs:
94145
95146
### Changes
96147
${{ needs.generate-changelog.outputs.changelog }}
97-
files: release_files/**/*
148+
files: release_files/*
98149
prerelease: false
99150
draft: true
100151
env:

.github/workflows/snapshots.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,16 @@ jobs:
2121
with:
2222
mode: snapshot
2323

24+
client-sdks:
25+
name: SDK smoke builds and pack
26+
uses: ./.github/workflows/clients_ci.yml
27+
with:
28+
artifact_suffix: "-Snapshot"
29+
upload_artifacts: true
30+
2431
create-pre-release:
2532
name: Create Pre-Release
26-
needs: [build, generate-changelog]
33+
needs: [build, generate-changelog, client-sdks]
2734
runs-on: ubuntu-latest
2835
if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/main')
2936
steps:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package common
2+
3+
import (
4+
"fmt"
5+
"log/slog"
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
const readmeTemplate = `# VIIPER Client SDK
11+
12+
This is an automatically generated client SDK for [VIIPER](https://github.com/Alia5/VIIPER) - **Virtual** **I**nput over **IP** **E**mulato**R**
13+
14+
## Documentation
15+
16+
- **Project Repository**: https://github.com/Alia5/VIIPER
17+
- **Documentation**: https://alia5.github.io/VIIPER/
18+
19+
## About VIIPER
20+
21+
VIIPER creates virtual USB input devices using the USBIP protocol.
22+
These virtual devices appear as real hardware to the operating system and applications, allowing you to emulate controllers, keyboards, and other input devices without physical hardware.
23+
24+
## License
25+
26+
MIT License - See LICENSE.txt for details.
27+
`
28+
29+
func GenerateReadme(logger *slog.Logger, outputDir string) error {
30+
readmePath := filepath.Join(outputDir, "README.md")
31+
32+
if err := os.WriteFile(readmePath, []byte(readmeTemplate), 0644); err != nil {
33+
return fmt.Errorf("write README.md: %w", err)
34+
}
35+
36+
logger.Debug("Generated README.md", "path", readmePath)
37+
return nil
38+
}

viiper/internal/codegen/generator/c/gen.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ func Generate(logger *slog.Logger, outputDir string, md *meta.Metadata) error {
6262
return err
6363
}
6464

65+
if err := common.GenerateReadme(logger, outputDir); err != nil {
66+
return err
67+
}
68+
6569
logger.Info("Generated C SDK", "dir", outputDir)
6670
return nil
6771
}

viiper/internal/codegen/generator/csharp/gen.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ func Generate(logger *slog.Logger, outputDir string, md *meta.Metadata) error {
6868
return err
6969
}
7070

71+
if err := common.GenerateReadme(logger, outputDir); err != nil {
72+
return err
73+
}
74+
7175
logger.Info("Generated C# SDK", "dir", outputDir)
7276
return nil
7377
}

viiper/internal/codegen/generator/csharp/project.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,13 @@ const projectTemplate = `<Project Sdk="Microsoft.NET.Sdk">
2727
<RepositoryUrl>https://github.com/Alia5/VIIPER</RepositoryUrl>
2828
<RepositoryType>git</RepositoryType>
2929
<PackageTags>viiper;usbip;virtual-device;input-emulation;hid</PackageTags>
30+
<PackageReadmeFile>README.md</PackageReadmeFile>
3031
</PropertyGroup>
3132
33+
<ItemGroup>
34+
<None Include="../README.md" Pack="true" PackagePath="/"/>
35+
</ItemGroup>
36+
3237
</Project>
3338
`
3439

viiper/internal/codegen/generator/typescript/gen.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ func Generate(logger *slog.Logger, outputDir string, md *meta.Metadata) error {
7474
return err
7575
}
7676

77+
if err := common.GenerateReadme(logger, projectDir); err != nil {
78+
return err
79+
}
80+
7781
logger.Info("Generated TypeScript SDK", "dir", projectDir)
7882
return nil
7983
}

viiper/internal/codegen/generator/typescript/project.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const packageTemplate = `{
1616
"license": "MIT",
1717
"repository": {
1818
"type": "git",
19-
"url": "https://github.com/Alia5/VIIPER"
19+
"url": "git+https://github.com/Alia5/VIIPER.git"
2020
},
2121
"main": "dist/index.js",
2222
"types": "dist/index.d.ts",
@@ -35,6 +35,9 @@ const packageTemplate = `{
3535
"build": "tsc -p .",
3636
"clean": "rimraf dist"
3737
},
38+
"publishConfig": {
39+
"access": "public"
40+
},
3841
"devDependencies": {
3942
"@types/node": "24.10.1",
4043
"rimraf": "6.1.0",

0 commit comments

Comments
 (0)