Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GHA workflow for generating WebAPI client library for Java #471

Merged
Merged
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
33 changes: 33 additions & 0 deletions .github/workflows/4-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,17 @@ env:
IMAGE_NAME: ${{ github.repository }}

jobs:
detect-current-api-version:
uses: ./.github/workflows/detect-webapi-version.yaml
with:
# We cannot use environment variables here due to workflow limitation.
# https://docs.github.com/en/enterprise-cloud@latest/actions/using-workflows/reusing-workflows#limitations
registry: ghcr.io
image-repo: ${{ github.repository }}

publish-container-image:
runs-on: ubuntu-latest
needs: detect-current-api-version
permissions:
packages: write
steps:
Expand Down Expand Up @@ -39,3 +48,27 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
provenance: false

detect-newer-api-version:
needs: publish-container-image
uses: ./.github/workflows/detect-webapi-version.yaml
with:
# We cannot use environment variables here due to workflow limitation.
# https://docs.github.com/en/enterprise-cloud@latest/actions/using-workflows/reusing-workflows#limitations
registry: ghcr.io
image-repo: ${{ github.repository }}

generate-webapi-clients:
needs:
- detect-current-api-version
- detect-newer-api-version
if: ${{ needs.detect-current-api-version.outputs.apiver != needs.detect-newer-api-version.outputs.apiver }}
uses: ./.github/workflows/4.a-generate-webapi-clients.yaml
permissions:
contents: write
packages: write
with:
# We cannot use environment variables here due to workflow limitation.
# https://docs.github.com/en/enterprise-cloud@latest/actions/using-workflows/reusing-workflows#limitations
registry: ghcr.io
image-repo: ${{ github.repository }}
48 changes: 48 additions & 0 deletions .github/workflows/4.a-generate-webapi-clients.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: 4.a-Generate WebAPI client libraries

on:
workflow_call:
inputs:
registry:
type: string
required: true
image-repo:
type: string
required: true
tag:
type: string
required: false
default: latest
workflow_dispatch:
inputs:
registry:
type: string
required: false
default: ghcr.io
image-repo:
type: string
required: false
default: "green-software-foundation/carbon-aware-sdk"
tag:
type: string
required: false
default: latest

permissions:
contents: write
packages: write

jobs:
detect-api-version:
uses: ./.github/workflows/detect-webapi-version.yaml
with:
registry: ${{ inputs.registry }}
image-repo: ${{ inputs.image-repo }}
tag: ${{ inputs.tag }}

generate-java-client:
needs: detect-api-version
uses: ./.github/workflows/4.a.1-generate-webapi-client-java.yaml
with:
image: ${{ needs.detect-api-version.outputs.image }}
apiver: ${{ needs.detect-api-version.outputs.apiver }}
84 changes: 84 additions & 0 deletions .github/workflows/4.a.1-generate-webapi-client-java.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: 4.a.1-Generate WebAPI client library for Java

on:
workflow_call:
inputs:
image:
required: true
type: string
apiver:
required: true
type: string

jobs:
generate-java-client:
runs-on: ubuntu-latest
services:
webapi:
image: ${{ inputs.image }}
ports:
- 8080:8080
options: >-
--health-cmd "curl -sS http://localhost:8080/health"
--health-interval 3s
--health-timeout 5s
--health-retries 5
permissions:
packages: write
env:
API: http://localhost:8080/api/v1/swagger.yaml
steps:
- name: Prepare
run: |
mkdir work pages
npm install -g @openapitools/[email protected]
- name: Generate client library
run: |
echo '{"apiPackage": "foundation.greensoftware.carbonaware.webapi.client", "artifactDescription": "Carbon Aware SDK client library for Java", "artifactId": "casdk-client", "artifactVersion": "${{ inputs.apiver }}", "developerOrganization": "Green Software Foundation", "developerOrganizationUrl": "https://greensoftware.foundation/", "groupId": "foundation.greensoftware", "licenseName": "MIT License", "scmUrl": "${{ env.REPO }}", "artifactUrl": "${{ env.REPO }}/packages/", "scmConnection": "${{ github.repositoryUrl }}", "scmDeveloperConnection": "${{ github.repositoryUrl }}", "licenseUrl": "https://opensource.org/license/mit/", "developerName": "Green Software Foundation", "developerEmail": "[email protected]"}' > config.json
openapi-generator-cli generate -i ${{ env.API }} -g java -o work -c config.json
sed -i "s|</project>|<distributionManagement><repository><id>github</id><name>GitHub Packages</name><url>https://maven.pkg.github.com/${{ github.repository }}</url></repository></distributionManagement></project>|" work/pom.xml
shell: bash
- name: Setup Java 8
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 8
cache: maven
- name: Run Maven
run: mvn -B deploy javadoc:javadoc
env:
GITHUB_TOKEN: ${{ github.token }}
working-directory: work
- name: Upload Javadoc
uses: actions/upload-artifact@v4
with:
name: javadoc
path: work/target/apidocs

push-javadoc:
needs: generate-java-client
concurrency: push-to-doc-website
runs-on: ubuntu-latest
env:
DOCPATH: casdk-docs/static/client-apidocs/${{ inputs.apiver }}/java
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare
run: mkdir -p ${{ env.DOCPATH }}
- name: Download Javadoc
uses: actions/download-artifact@v4
with:
name: javadoc
path: ${{ env.DOCPATH }}
- name: Push Javadoc
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add ${{ env.DOCPATH }}
git commit -m "Add Javadoc for WebAPI ${{ inputs.apiver }}"
git push origin ${{ github.ref_name }}
env:
GITHUB_TOKEN: ${{ github.token }}
55 changes: 55 additions & 0 deletions .github/workflows/detect-webapi-version.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Detect API version from OpenAPI document in WebAPI container image

on:
workflow_call:
inputs:
registry:
type: string
required: true
image-repo:
type: string
required: true
tag:
type: string
required: false
default: latest
outputs:
image:
value: ${{ jobs.make-image-name-for-pull.outputs.image }}
apiver:
value: ${{ jobs.detect-api-version.outputs.apiver }}

jobs:
make-image-name-for-pull:
runs-on: ubuntu-latest
outputs:
image: ${{ steps.make-image-name.outputs.IMAGE_NAME }}
steps:
- name: Make string for pulling container image
id: make-image-name
run: |
REPO=${{ inputs.registry }}/${{ inputs.image-repo }}
REPO_LOWER=${REPO,,}
echo "IMAGE_NAME=$REPO_LOWER:${{ inputs.tag }}" >> "$GITHUB_OUTPUT"

detect-api-version:
needs: make-image-name-for-pull
runs-on: ubuntu-latest
services:
webapi:
image: ${{ needs.make-image-name-for-pull.outputs.image }}
ports:
- 8080:8080
options: >-
--health-cmd "curl -sS http://localhost:8080/health"
--health-interval 3s
--health-timeout 5s
--health-retries 5
outputs:
apiver: ${{ steps.detect-api-version.outputs.CURRENT_API_VERSION }}
steps:
- name: Detect API version
id: detect-api-version
run: |
API_VERSION=`curl -sS http://localhost:8080/api/v1/swagger.yaml | yq -r .info.version`
echo "CURRENT_API_VERSION=$API_VERSION" >> "$GITHUB_OUTPUT"
53 changes: 12 additions & 41 deletions samples/java-client/README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
# Java Client Example

This folder contains an example for WebAPI client in Java. Client library would
be generated dynamically via
[openapi-generator-maven-plugin](https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin),
and call WebAPI endpoints without HTTP code.
This folder contains an example for WebAPI client in Java. Client library would be pulled from [GitHub Packages](https://github.com/orgs/Green-Software-Foundation/packages?repo_name=carbon-aware-sdk).

Javadoc is [here](apidocs).

openapi-generator-maven-plugin generates Maven/Gradle project when it kicks,
however this example uses generated codes directly. So you don't need to
run/modify project files in it.
Javadoc is [here](https://carbon-aware-sdk.greensoftware.foundation/client-apidocs/1.0.0/java).

## Requirements

- OpenAPI spec file
- Both online and offline file are available.
- See [WebAPI document](../../docs/carbon-aware-webapi.md#autogenerate-webapi)
for details.
- WebAPI instance
- See the [Overview](../../docs/overview.md#publish-webapi-with-container)
if you'd like to start it on container.
- See the [Overview](../../docs/overview.md#publish-webapi-with-container) if you'd like to start it on container.
- Java 8 or later
- Maven

## Client code

[WebApiClient.java](src/main/java/foundation/greensoftware/carbonawaresdk/samples/java/WebApiClient.java)
is an example program to call WebAPI endpoint. It calls all of endpoints, and
shows the result.
[WebApiClient.java](src/main/java/example/foundation/greensoftware/carbonawaresdk/WebApiClient.java) is an example program to call WebAPI endpoint. It calls all of endpoints, and shows the result.

Following methods are available:

Expand All @@ -53,19 +39,14 @@ Following methods are available:
- Call /emissions/average-carbon-intensity/batch
- Shows average data for westus yesterday.

[OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html)
is used for parameters in each APIs. However the error occurs if nano sec is set
to it in case of WattTime. So it is highly recommended that clears nanosec field
like `withNano(0)`.
[OffsetDateTime](https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html) is used for parameters in each APIs. However the error occurs if nano sec is set to it in case of WattTime. So it is highly recommended that clears nanosec field like `withNano(0)`.

## How it works

### 1. Set up for [POM](pom.xml)

You need to change following properties:

- `openapi.spec`
- OpenAPI spec file
- `webapi.endpoint`
- WebAPI base URL

Expand All @@ -83,27 +64,23 @@ $ mvn exec:java

### Running in container

This example also can run in container. You can use
[Maven official image](https://hub.docker.com/_/maven).
This example also can run in container. You can use [Maven official image](https://hub.docker.com/_/maven).

If you want to run both WebAPI and build process in container, you need to join
2 containers to same network.
If you want to run both WebAPI and build process in container, you need to join 2 containers to same network.

Following instructions are for Podman.

#### 1. Create pod

This pod publishes port 80 in the pod to 8080 on the host, then you can access
WebAPI in the pod. The pod is named to `carbon-aware-sdk`.
This pod publishes port 80 in the pod to 8080 on the host, then you can access WebAPI in the pod. The pod is named to `carbon-aware-sdk`.

```sh
podman pod create -p 8080:80 --name carbon-aware-sdk
```

#### 2. Start WebAPI container

Start WebAPI container in `carbon-aware-sdk` pod. It is specified at `--pod`
option.
Start WebAPI container in `carbon-aware-sdk` pod. It is specified at `--pod` option.

See [Overview](../../docs/overview.md) document to build container image.

Expand All @@ -117,13 +94,9 @@ $ podman run -it --rm --pod carbon-aware-sdk \

#### 3. Run Maven in the container

Run `mvn` command in Maven container in `catbon-aware-sdk` pod. You need to
mount Carbon Aware SDK source directory to the container. It mounts to `/src` in
the container in following case.
Run `mvn` command in Maven container in `catbon-aware-sdk` pod. You need to mount Carbon Aware SDK source directory to the container. It mounts to `/src` in the container in following case.

In following command, you can rebuild java-client, and can run the artifact. You
can get artifacts from `samples/java-client/target` on the container host of
course.
In following command, you can rebuild java-client, and can run the artifact. You can get artifacts from `samples/java-client/target` on the container host of course.

```sh
$ podman run -it --rm --pod carbon-aware-sdk \
Expand All @@ -132,6 +105,4 @@ $ podman run -it --rm --pod carbon-aware-sdk \
mvn -f /src/samples/java-client/pom.xml clean package exec:java
```

Maven will download many dependencies in each `mvn` call. You can avoid it when
you mount `.m2` like `-v $HOME/.m2:/root/.m2` because it shares Maven cache
between the host and the container.
Maven will download many dependencies in each `mvn` call. You can avoid it when you mount `.m2` like `-v $HOME/.m2:/root/.m2` because it shares Maven cache between the host and the container.
Loading
Loading