Skip to content

Commit a530650

Browse files
GvieveGenevieve Nuebel
andauthored
Multi-Version SDK Generation POC (#66)
* Create version specific static config fies * Create new workflows to test multi version POC support * Update the config/workflows since must merge to master to test * Update config files to latest version --------- Co-authored-by: Genevieve Nuebel <genevieve.nuebel@mx.com>
1 parent da3bb50 commit a530650

8 files changed

Lines changed: 332 additions & 2 deletions

File tree

.github/clean.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
::Dir.each_child(::Dir.pwd) do |source|
1313
next if ALLOW_LIST.include?(source)
14+
15+
# Preserve test-output directories for multi-version POC testing
16+
next if source.start_with?("test-output-")
1417

1518
::FileUtils.rm_rf("#{::Dir.pwd}/#{source}")
1619
end

.github/version.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
require "yaml"
2-
config = ::YAML.load(::File.read("openapi/config.yml"))
2+
3+
# Support both single config and multi-version config approaches
4+
# For multi-version POC, we can specify which config file to use
5+
config_file = ARGV[1] || "openapi/config.yml"
6+
7+
config = ::YAML.load(::File.read(config_file))
38
major, minor, patch = config["npmVersion"].split(".")
49

510
case ARGV[0]
@@ -15,5 +20,5 @@
1520
end
1621

1722
config["npmVersion"] = "#{major}.#{minor}.#{patch}"
18-
::File.open("openapi/config.yml", 'w') { |file| ::YAML.dump(config, file) }
23+
::File.open(config_file, 'w') { |file| ::YAML.dump(config, file) }
1924
puts config["npmVersion"]
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Generate Multi-Version SDK
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
api_version:
7+
description: 'API Version to generate'
8+
required: true
9+
default: 'v20111101'
10+
type: choice
11+
options:
12+
- 'v20111101'
13+
- 'v20250224'
14+
- 'latest'
15+
version_level:
16+
description: "Bump version"
17+
required: true
18+
default: "patch"
19+
type: choice
20+
options:
21+
- major
22+
- minor
23+
- patch
24+
25+
jobs:
26+
Generate:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v3
30+
- uses: actions/setup-node@v3
31+
with:
32+
node-version: "20"
33+
- uses: ruby/setup-ruby@v1
34+
with:
35+
ruby-version: 3.1
36+
37+
# Determine configuration based on API version
38+
- name: Set version configuration
39+
id: config
40+
run: |
41+
API_VERSION="${{ github.event.inputs.api_version }}"
42+
43+
echo "config_file=./openapi/config-$API_VERSION.yml" >> $GITHUB_OUTPUT
44+
45+
if [ "$API_VERSION" = "latest" ]; then
46+
echo "spec_url=https://raw.githubusercontent.com/mxenabled/openapi/master/openapi/v20111101.yml" >> $GITHUB_OUTPUT
47+
echo "output_dir=." >> $GITHUB_OUTPUT
48+
else
49+
echo "spec_url=https://raw.githubusercontent.com/mxenabled/openapi/master/openapi/$API_VERSION.yml" >> $GITHUB_OUTPUT
50+
echo "output_dir=./$API_VERSION" >> $GITHUB_OUTPUT
51+
fi
52+
53+
echo "branch_suffix=-$API_VERSION" >> $GITHUB_OUTPUT
54+
55+
- name: Bump version
56+
id: bump_version
57+
run: echo "version=$(ruby .github/version.rb ${{ github.event.inputs.version_level }} ${{ steps.config.outputs.config_file }})" >> $GITHUB_OUTPUT
58+
59+
# Note: Do NOT clean repo for multi-version - we want to preserve existing version directories
60+
# The clean.rb script already protects version directories (v20111101, v20250224)
61+
62+
- name: Install openapi-generator-cli
63+
run: |
64+
npm install @openapitools/openapi-generator-cli -g
65+
66+
# Validate config file exists
67+
- name: Validate config file
68+
run: |
69+
if [ ! -f "${{ steps.config.outputs.config_file }}" ]; then
70+
echo "❌ Config file ${{ steps.config.outputs.config_file }} not found"
71+
echo "Available config files:"
72+
ls -la ./openapi/config*.yml || echo "No config files found"
73+
exit 1
74+
fi
75+
echo "✅ Using config file: ${{ steps.config.outputs.config_file }}"
76+
77+
- name: Generate SDK
78+
run: |
79+
echo "🔧 Generating SDK for version: ${{ github.event.inputs.api_version }}"
80+
echo "📄 Config: ${{ steps.config.outputs.config_file }}"
81+
echo "🌐 Spec: ${{ steps.config.outputs.spec_url }}"
82+
echo "📁 Output: ${{ steps.config.outputs.output_dir }}"
83+
84+
openapi-generator-cli generate \
85+
-i ${{ steps.config.outputs.spec_url }} \
86+
-g typescript-axios \
87+
-c ${{ steps.config.outputs.config_file }} \
88+
-t ./openapi/templates \
89+
-o ${{ steps.config.outputs.output_dir }}
90+
91+
# Test TypeScript compilation
92+
- name: Test TypeScript compilation
93+
run: |
94+
cd ${{ steps.config.outputs.output_dir }}
95+
npm install
96+
npm run build
97+
echo "✅ TypeScript compilation successful"
98+
99+
- name: Get package info
100+
id: package_info
101+
run: |
102+
PACKAGE_NAME=$(cat ${{ steps.config.outputs.output_dir }}/package.json | grep '"name"' | cut -d'"' -f4)
103+
echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT
104+
105+
- name: Create branch
106+
run: git checkout -b "openapi-generator-${{ steps.bump_version.outputs.version }}${{ steps.config.outputs.branch_suffix }}"
107+
108+
- name: Create commit
109+
run: |
110+
git config user.name "devexperience"
111+
git config user.email "devexperience@mx.com"
112+
git add .
113+
git commit -m "Generated version ${{ steps.bump_version.outputs.version }} (${{ github.event.inputs.api_version }})
114+
115+
This pull request was automatically generated by a GitHub Action to generate version ${{ steps.bump_version.outputs.version }} of this library using API version ${{ github.event.inputs.api_version }}."
116+
git push -u origin "openapi-generator-${{ steps.bump_version.outputs.version }}${{ steps.config.outputs.branch_suffix }}"
117+
118+
- name: Create PR
119+
run: |
120+
gh pr create \
121+
--title "Generated version ${{ steps.bump_version.outputs.version }} (${{ github.event.inputs.api_version }})" \
122+
--body "This pull request was automatically generated using API version **${{ github.event.inputs.api_version }}**.
123+
124+
## Generation Details
125+
- 📄 **Config**: \`${{ steps.config.outputs.config_file }}\`
126+
- 🌐 **Spec**: \`${{ steps.config.outputs.spec_url }}\`
127+
- 🔢 **Version**: ${{ steps.bump_version.outputs.version }}
128+
- 📦 **Package name**: ${{ steps.package_info.outputs.package_name }}
129+
- ✅ **TypeScript compilation**: Passed
130+
131+
## Testing Notes
132+
This is a multi-version SDK generation for testing purposes. The generated package uses a version-specific name to avoid conflicts with the production package.
133+
134+
Please review the generated changes before merging."
135+
env:
136+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
137+
138+
- name: Slack notification
139+
uses: ravsamhq/notify-slack-action@v2
140+
if: always()
141+
with:
142+
status: ${{ job.status }}
143+
token: ${{ secrets.GITHUB_TOKEN }}
144+
notification_title: "{repo}: {workflow} workflow"
145+
message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>"
146+
footer: "<{workflow_url}|View Workflow>"
147+
notify_when: "failure"
148+
env:
149+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
name: Test Multi-Version SDK
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
api_version:
7+
description: 'API Version to generate'
8+
required: true
9+
default: 'v20111101'
10+
type: choice
11+
options:
12+
- 'v20111101'
13+
- 'v20250224'
14+
- 'latest'
15+
test_level:
16+
description: 'Testing level'
17+
required: true
18+
default: 'generate_only'
19+
type: choice
20+
options:
21+
- 'generate_only' # No commits, no publishing
22+
- 'github_packages' # Publish to GitHub Packages (safe staging)
23+
24+
jobs:
25+
Test:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v3
29+
- uses: actions/setup-node@v3
30+
with:
31+
node-version: "20"
32+
- uses: ruby/setup-ruby@v1
33+
with:
34+
ruby-version: 3.1
35+
36+
# Determine configuration based on API version
37+
- name: Set version configuration
38+
id: config
39+
run: |
40+
API_VERSION="${{ github.event.inputs.api_version }}"
41+
42+
echo "config_file=./openapi/config-$API_VERSION.yml" >> $GITHUB_OUTPUT
43+
echo "output_dir=./test-output-$API_VERSION" >> $GITHUB_OUTPUT
44+
45+
if [ "$API_VERSION" = "latest" ]; then
46+
echo "spec_url=https://raw.githubusercontent.com/mxenabled/openapi/master/openapi/v20111101.yml" >> $GITHUB_OUTPUT
47+
else
48+
echo "spec_url=https://raw.githubusercontent.com/mxenabled/openapi/master/openapi/$API_VERSION.yml" >> $GITHUB_OUTPUT
49+
fi
50+
51+
# Create output directory for testing versions
52+
- name: Prepare test output directory
53+
run: mkdir -p ${{ steps.config.outputs.output_dir }}
54+
55+
# Install OpenAPI Generator
56+
- name: Install openapi-generator-cli
57+
run: |
58+
npm install @openapitools/openapi-generator-cli -g
59+
60+
# Validate config file exists
61+
- name: Validate config file
62+
run: |
63+
if [ ! -f "${{ steps.config.outputs.config_file }}" ]; then
64+
echo "❌ Config file ${{ steps.config.outputs.config_file }} not found"
65+
echo "Available config files:"
66+
ls -la ./openapi/config*.yml || echo "No config files found"
67+
exit 1
68+
fi
69+
echo "✅ Using config file: ${{ steps.config.outputs.config_file }}"
70+
71+
# Generate SDK
72+
- name: Generate SDK
73+
run: |
74+
echo "🔧 Generating SDK for version: ${{ github.event.inputs.api_version }}"
75+
echo "📄 Config: ${{ steps.config.outputs.config_file }}"
76+
echo "🌐 Spec: ${{ steps.config.outputs.spec_url }}"
77+
echo "📁 Output: ${{ steps.config.outputs.output_dir }}"
78+
79+
openapi-generator-cli generate \
80+
-i ${{ steps.config.outputs.spec_url }} \
81+
-g typescript-axios \
82+
-c ${{ steps.config.outputs.config_file }} \
83+
-t ./openapi/templates \
84+
-o ${{ steps.config.outputs.output_dir }}
85+
86+
# Test TypeScript compilation
87+
- name: Test TypeScript compilation
88+
run: |
89+
cd ${{ steps.config.outputs.output_dir }}
90+
npm install
91+
npm run build
92+
echo "✅ TypeScript compilation successful"
93+
94+
# Archive generated code as artifact for inspection
95+
- name: Archive generated code
96+
uses: actions/upload-artifact@v3
97+
with:
98+
name: generated-sdk-${{ github.event.inputs.api_version }}
99+
path: ${{ steps.config.outputs.output_dir }}
100+
retention-days: 7
101+
102+
# Validation summary
103+
- name: Validation summary
104+
run: |
105+
echo "🎉 Generation successful for ${{ github.event.inputs.api_version }}!"
106+
107+
# Show package.json name for verification
108+
PACKAGE_NAME=$(cat ${{ steps.config.outputs.output_dir }}/package.json | grep '"name"' | cut -d'"' -f4)
109+
PACKAGE_VERSION=$(cat ${{ steps.config.outputs.output_dir }}/package.json | grep '"version"' | cut -d'"' -f4)
110+
echo "📦 Generated package: $PACKAGE_NAME@$PACKAGE_VERSION"
111+
112+
# Count API files
113+
API_COUNT=$(find ${{ steps.config.outputs.output_dir }} -name "*api.ts" | wc -l)
114+
echo "🔍 Generated API files: $API_COUNT"
115+
116+
# Show file structure
117+
echo ""
118+
echo "📂 Generated file structure:"
119+
ls -lh ${{ steps.config.outputs.output_dir }}
120+
121+
# Publish to GitHub Packages (Safe Testing)
122+
- name: Publish to GitHub Packages
123+
if: ${{ github.event.inputs.test_level == 'github_packages' }}
124+
run: |
125+
cd ${{ steps.config.outputs.output_dir }}
126+
127+
# Configure for GitHub Packages
128+
npm config set registry https://npm.pkg.github.com
129+
npm config set //npm.pkg.github.com/:_authToken ${{ secrets.GITHUB_TOKEN }}
130+
131+
# Publish the test package
132+
npm publish
133+
134+
PACKAGE_NAME=$(cat package.json | grep '"name"' | cut -d'"' -f4)
135+
PACKAGE_VERSION=$(cat package.json | grep '"version"' | cut -d'"' -f4)
136+
137+
echo "✅ Published test package to GitHub Packages"
138+
echo "📦 Package: $PACKAGE_NAME@$PACKAGE_VERSION"
139+
echo "🔗 View at: https://github.com/mxenabled/mx-platform-node/packages"
140+
141+
- name: Slack notification
142+
if: always()
143+
uses: ravsamhq/notify-slack-action@v2
144+
with:
145+
status: ${{ job.status }}
146+
token: ${{ secrets.GITHUB_TOKEN }}
147+
notification_title: "{repo}: {workflow} workflow"
148+
message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>"
149+
footer: "<{workflow_url}|View Workflow>"
150+
notify_when: "failure"
151+
env:
152+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ wwwroot/*.js
22
node_modules
33
typings
44
dist
5+
6+
# Ignore all tempfiles.
7+
/tmp/*
8+
!/tmp/.keep

openapi/config-latest.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Latest is mapped to v20111101 for now to maintain backwards compatibility.
2+
# In the future, this will point to the latest version of the API.
3+
---
4+
generatorName: typescript-axios
5+
npmName: mx-platform-node
6+
npmVersion: 1.12.0
7+
supportsES6: true

openapi/config-v20111101.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
generatorName: typescript-axios
3+
npmName: mx-platform-node-v20111101
4+
npmVersion: 1.12.0
5+
supportsES6: true

openapi/config-v20250224.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
generatorName: typescript-axios
3+
npmName: mx-platform-node-v20250224
4+
npmVersion: 2.0.0
5+
supportsES6: true

0 commit comments

Comments
 (0)