Skip to content

Commit

Permalink
Make publish scripts available for all languages but create-only (#27)
Browse files Browse the repository at this point in the history
* Make C# nuget publish workflow script create-only

* Standardize naming of publish.yml and make it optional

* Save history of patch notes
  • Loading branch information
tspence authored Aug 18, 2024
1 parent 6c5bcad commit d07d411
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 7 deletions.
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,58 @@ Here's how to use this program.

You can automate these steps in a Github workflow to execute this program automatically on new releases.

## Automating SDK patches

If you publish updates to your API regularly, you can use GitHub Actions to automatically check for changes to your
OpenAPI / Swagger file and generate a new software development kit.

Create a GitHub action using this template:

```yaml
name: Check for OpenAPI updates

on:
schedule:
- cron: "0 0 * * 0" # Run once per week

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup .NET Core @ Latest
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"

- name: Add the SDK Generator
run: dotnet tool install SdkGenerator --global

- name: Generate the latest SDK
run: SdkGenerator build -p ./sdk-config.json

- name: Save patch notes
id: patch-notes
run: SdkGenerator get-patch-notes -p ./sdk-config.json

- name: Save pull request name
id: pr-name
run: SdkGenerator get-release-name -p ./sdk-config.json

- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v6
with:
commit-message: ${{ steps.patch-notes.outputs }}
title: ${{ steps.pr-name.outputs }}
```
## Supported Languages
| Language | Supported | Github Workflows | Notes |
Expand Down
6 changes: 3 additions & 3 deletions src/SdkGenerator/Languages/CSharpSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ public async Task Export(GeneratorContext context)
await ExportEndpoints(context);

// Let's try using Scriban to populate these files
await ScribanFunctions.ExecuteTemplate(context,
"SdkGenerator.Templates.csharp.nuget-publish.yml.scriban",
context.MakePath(context.Project.Csharp.Folder, ".github", "workflows", "nuget-publish.yml"));
await ScribanFunctions.ExecuteTemplateIfNotExists(context,
"SdkGenerator.Templates.csharp.publish.yml.scriban",
context.MakePath(context.Project.Csharp.Folder, ".github", "workflows", "publish.yml"));
await ScribanFunctions.ExecuteTemplate(context,
"SdkGenerator.Templates.csharp.ApiClient.scriban",
context.MakePath(context.Project.Csharp.Folder, "src", context.Project.Csharp.ClassName + ".cs"));
Expand Down
3 changes: 3 additions & 0 deletions src/SdkGenerator/Languages/JavaSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,9 @@ public async Task Export(GeneratorContext context)
await ExportEndpoints(context);

// Let's try using Scriban to populate these files
await ScribanFunctions.ExecuteTemplateIfNotExists(context,
"SdkGenerator.Templates.java.publish.yml.scriban",
context.MakePath(context.Project.Csharp.Folder, ".github", "workflows", "publish.yml"));
await ScribanFunctions.ExecuteTemplate(context,
"SdkGenerator.Templates.java.ApiClient.java.scriban",
context.MakePath(context.Project.Java.Folder, "src", "main", "java",
Expand Down
3 changes: 3 additions & 0 deletions src/SdkGenerator/Languages/PythonSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,9 @@ public async Task Export(GeneratorContext context)
await ExportEndpoints(context);

// Let's try using Scriban to populate these files
await ScribanFunctions.ExecuteTemplateIfNotExists(context,
"SdkGenerator.Templates.python.publish.yml.scriban",
context.MakePath(context.Project.Csharp.Folder, ".github", "workflows", "publish.yml"));
await ScribanFunctions.ExecuteTemplate(context,
"SdkGenerator.Templates.python.ApiClient.scriban",
context.MakePath(context.Project.Python.Folder, "src", context.Project.Python.Namespace, context.Project.Python.ClassName.WordsToSnakeCase() + ".py"));
Expand Down
3 changes: 3 additions & 0 deletions src/SdkGenerator/Languages/TypescriptSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ public async Task Export(GeneratorContext context)
await ExportEndpoints(context);

// Let's try using Scriban to populate these files
await ScribanFunctions.ExecuteTemplateIfNotExists(context,
"SdkGenerator.Templates.ts.publish.yml.scriban",
context.MakePath(context.Project.Csharp.Folder, ".github", "workflows", "publish.yml"));
await ScribanFunctions.ExecuteTemplate(context,
"SdkGenerator.Templates.ts.ApiClient.scriban",
context.MakePath(context.Project.Typescript.Folder, "src", context.Project.Typescript.ClassName + ".ts"));
Expand Down
69 changes: 69 additions & 0 deletions src/SdkGenerator/PatchNotes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,72 @@
# 1.3.1
August 18, 2024

* Make automated publishing workflow scripts create-only so updates do not trigger GitHub security

# 1.3.0
August 13, 2024

* New modes to calculate patch notes and release name for use with automated PRs

# 1.2.6
July 25, 2024

* Fix issue with path combining
* Upgrade to DotNet 8.0
* Do not generate markdown files if not requested
* Make security schemes section blankout optional if users don't want to save keys
* Python: Fix capitalization/list issue
* TypeScript: Fix duplicated import for nested classes

# 1.2.5
March 13, 2024

* Fix issues with embedded resources so this can work from DotNet tool

# 1.2.4
February 10, 2024

* More capitalization improvements - better handle imprecise inputs
* Fixed issues with Python SDK for array uploads
* C# SDK uses URI object instead of string for custom endpoint

# 1.2.3
January 29, 2024

* Allow specific endpoints to be ignored during SDK generation
* Better capitalization for multi-word phrases converted to PascalCase
* Fixed issues with Python SDK generation, json double conversion

# 1.2.2
January 12, 2024

* Numerous small fixes for API endpoints that download octet-streams/byte arrays
* Better logic for excluding endpoints and excluding parameters - patch notes generate correctly
* SDKs now generate endpoints that download blobs and still parse errors correctly
* Treat both "byte" and "byte[]" as blob download endpoints
* Python uses immutable bytes object
* Fixes for readme uploads

# 1.2.1
October 22, 2023

* Class and property generation can now avoid language-specific keywords
* Variable names are now cleansed for parameters (some APIs use $param=value)
* Java now uses semver3 as is becoming the standard in most places
* Generated API documentation will now only link to data model pages if specified
* Readme can now select between `list` and `table` style data model documentation

# 1.2.0
October 11, 2023

* Verified that Python and TypeScript work correctly, at least for my current SDKs

# 1.1.9
October 9, 2023

* Improvements for patch notes generation
* Cleaned up the Python export to use the latest idioms and to work with single-result-object

# 1.1.8
September 14, 2023

Expand Down
8 changes: 4 additions & 4 deletions src/SdkGenerator/SdkGenerator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
<PackageTags>SDK generator swagger openapi swashbuckle</PackageTags>
<Copyright>Copyright 2021 - 2024</Copyright>
<PackageReleaseNotes>
# 1.3.0
August 13, 2024
# 1.3.1
August 18, 2024

* New modes to calculate patch notes and release name for use with automated PRs
* Make automated publishing workflow scripts create-only so updates do not trigger GitHub security
</PackageReleaseNotes>
<PackageIcon>docs/icons-puzzle.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>1.3.0</Version>
<Version>1.3.1</Version>
<Authors>Ted Spence</Authors>
<!-- Project Url is filled in by sourcelink in the .NET 8 SDK, but you can add it explicitly via
package -->
Expand Down
58 changes: 58 additions & 0 deletions src/SdkGenerator/Templates/java/publish.yml.scriban
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# This is a basic workflow to help you get started with Actions

name: Java CI with Maven

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: 11
distribution: 'temurin'
server-id: ossrh
server-username: OSSRH_USERNAME
server-password: OSSRH_PASSWORD
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE

- name: Verify with Maven
if: github.event_name == 'pull_request'
run: mvn -B clean verify

- name: Verify javadoc
if: github.event_name == 'pull_request'
run: mvn -B -Prelease javadoc:test-javadoc

- name: Compile
run: mvn -B -Prelease compile

- name: Javadoc
run: mvn -B -Prelease javadoc:jar

- name: Source
run: mvn -B -Prelease source:jar

- name: Publish to Apache Maven Central
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: mvn -B -Prelease deploy
env:
OSSRH_USERNAME: ${{ secrets.MAVEN_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
39 changes: 39 additions & 0 deletions src/SdkGenerator/Templates/python/publish.yml.scriban
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Upload Python Package

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Run Pyre
run: |
python -m pip install pyre-check
python -m pip install dacite
pyre --source-directory src check
- name: Build package
run: python -m build
- name: Publish package
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
34 changes: 34 additions & 0 deletions src/SdkGenerator/Templates/ts/publish.yml.scriban
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Publish to NPM CI/CD

on:
push:
branches: [main]
pull_request:
branches: [main]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 18.18.0
registry-url: 'https://registry.npmjs.org'
- name: npm install
run: npm install
- name: npm audit
run: npm audit
- name: ESLint
run: npm run lint
- name: npm compile
run: npm run compile
- name: Publish NPM Package
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run:
npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

0 comments on commit d07d411

Please sign in to comment.