Repository navigation
Add Kotlin publishing and shared NuGet/Swift package versions #319
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
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,35 +1,74 @@ | ||
| name: dotnet CI build | ||
| # Keep this filename: its existing run counter supplies all package versions. | ||
| name: Protocol packages | ||
|
|
||
| on: push | ||
| on: | ||
| push: | ||
| branches: ["**"] | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| donet-ci-build: | ||
| version: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| package-version: ${{ steps.version.outputs.version }} | ||
| steps: | ||
| - name: Checkout source | ||
| uses: actions/checkout@v4 | ||
| - uses: actions/checkout@v6 | ||
| - name: Test shared version rules | ||
| run: python3 -B -m unittest discover -s scripts -p 'test_*.py' | ||
| - name: Calculate the shared package version | ||
| id: version | ||
| run: | | ||
| VERSION=$(python3 scripts/package-version.py) | ||
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Setup .NET Core @ Latest | ||
| uses: actions/setup-dotnet@v4 | ||
| nuget: | ||
| needs: version | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: | | ||
| 9.0.x | ||
| dotnet-version: 9.0.x | ||
| source-url: https://nuget.pkg.github.com/BluEye-Robotics/index.json | ||
| env: | ||
| NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} | ||
|
|
||
| - name: Sanitize branch name | ||
| id: branches | ||
| NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Build the NuGet package | ||
| env: | ||
| PACKAGE_VERSION: ${{ needs.version.outputs.package-version }} | ||
| run: dotnet pack Blueye.Protocol.Protobuf.csproj -p:Version="$PACKAGE_VERSION" -c Release -o out | ||
| - name: Publish to GitHub Packages | ||
| if: github.event_name != 'pull_request' && github.repository == 'BluEye-Robotics/ProtocolDefinitions' | ||
| env: | ||
| NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| BRANCH="${GITHUB_REF_NAME}" | ||
| SANITIZED=$(echo "$BRANCH" | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | tr '[:upper:]' '[:lower:]' | cut -c1-63) | ||
| echo "sanitized-branch-name=$SANITIZED" >> "$GITHUB_OUTPUT" | ||
| dotnet nuget push ./out/*.nupkg --skip-duplicate --no-symbols \ | ||
| --source https://nuget.pkg.github.com/BluEye-Robotics/index.json --api-key "$NUGET_AUTH_TOKEN" | ||
|
|
||
| - name: Build project and generate NuGet package | ||
| run: | | ||
| dotnet pack Blueye.Protocol.Protobuf.csproj --version-suffix "${{ steps.branches.outputs.sanitized-branch-name }}.$GITHUB_RUN_NUMBER" -c Release -o out | ||
| kotlin: | ||
| needs: version | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| uses: ./.github/workflows/ci-kotlin.yaml | ||
| with: | ||
| package-version: ${{ needs.version.outputs.package-version }} | ||
|
|
||
| - name: Push generated package to GitHub registry | ||
| env: | ||
| NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} | ||
| run: dotnet nuget push ./out/*.nupkg --skip-duplicate --no-symbols --api-key $NUGET_AUTH_TOKEN | ||
| swift: | ||
| needs: [version, nuget, kotlin] | ||
| if: >- | ||
| github.event_name != 'pull_request' && | ||
| github.repository == 'BluEye-Robotics/ProtocolDefinitions' && | ||
| github.ref == 'refs/heads/master' && | ||
| vars.SWIFT_PROTOCOL_REPOSITORY != '' | ||
| uses: ./.github/workflows/ci-swift.yaml | ||
| with: | ||
| package-version: ${{ needs.version.outputs.package-version }} | ||
| secrets: | ||
| CI_PAT: ${{ secrets.CI_PAT }} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| name: Kotlin package | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| package-version: | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| defaults: | ||
| run: | ||
| working-directory: kotlin | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - uses: actions/setup-java@v5 | ||
| with: | ||
| distribution: temurin | ||
| java-version: "17" | ||
| - uses: gradle/actions/setup-gradle@v4 | ||
| - name: Build, test, and publish to a local test repository | ||
| env: | ||
| PACKAGE_VERSION: ${{ inputs.package-version }} | ||
| run: ./gradlew --no-daemon build publishProtocolPublicationToSmokeTestRepository -PpackageVersion="$PACKAGE_VERSION" | ||
| - name: Verify package from a separate consuming project | ||
| env: | ||
| PACKAGE_VERSION: ${{ inputs.package-version }} | ||
| run: ./gradlew --no-daemon -p smoke-test run -PpackageVersion="$PACKAGE_VERSION" | ||
|
|
||
| publish: | ||
| if: github.event_name != 'pull_request' && github.repository == 'BluEye-Robotics/ProtocolDefinitions' | ||
| needs: build | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - uses: actions/setup-java@v5 | ||
| with: | ||
| distribution: temurin | ||
| java-version: "17" | ||
| - uses: gradle/actions/setup-gradle@v4 | ||
| - name: Publish to GitHub Packages | ||
| env: | ||
| GITHUB_ACTOR: ${{ github.actor }} | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| PACKAGE_VERSION: ${{ inputs.package-version }} | ||
| run: ./gradlew --no-daemon publishProtocolPublicationToGitHubPackagesRepository -PpackageVersion="$PACKAGE_VERSION" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| name: Release blueye.protocol.swift | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| package-version: | ||
| required: true | ||
| type: string | ||
| secrets: | ||
| CI_PAT: | ||
| required: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| dispatch: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Dispatch the protocol revision and shared version | ||
| env: | ||
| GH_TOKEN: ${{ secrets.CI_PAT }} | ||
| SWIFT_PROTOCOL_REPOSITORY: ${{ vars.SWIFT_PROTOCOL_REPOSITORY }} | ||
| PACKAGE_VERSION: ${{ inputs.package-version }} | ||
| run: | | ||
| gh api "repos/$SWIFT_PROTOCOL_REPOSITORY/dispatches" \ | ||
| -f event_type=protocol-update \ | ||
| -f "client_payload[sha]=$GITHUB_SHA" \ | ||
| -f "client_payload[version]=$PACKAGE_VERSION" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,3 +38,7 @@ node_modules | |
|
|
||
| # Rider directories | ||
| .idea | ||
|
|
||
| # Gradle build state | ||
| .gradle | ||
| .kotlin | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <Project> | ||
| <PropertyGroup> | ||
| <VersionPrefix>$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)version.txt').Trim()).0</VersionPrefix> | ||
| </PropertyGroup> | ||
| </Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # Kotlin/JVM package | ||
|
|
||
| Maven coordinate: `com.blueyerobotics:protocol-definitions`. | ||
|
|
||
| The library generates Java message classes and Kotlin builder DSLs from the | ||
| shared schemas. It uses the **full** `protobuf-java` and `protobuf-kotlin` runtimes, | ||
| including descriptors, reflection, and `Any`. It targets Java 8 bytecode, uses | ||
| Kotlin 2.2.21, and builds with JDK 17 and the included Gradle 8.14.3 wrapper. | ||
| It is a JVM/Android library, not a Kotlin Multiplatform library, and contains no | ||
| network transport implementation. | ||
|
|
||
| ## Consume | ||
|
|
||
| Add the repository to `dependencyResolutionManagement.repositories` in your | ||
| `settings.gradle.kts` (or your project's `repositories` block): | ||
|
|
||
| ```kotlin | ||
| maven { | ||
| url = uri("https://maven.pkg.github.com/blueye-robotics/ProtocolDefinitions") | ||
| credentials { | ||
| username = providers.gradleProperty("gpr.user").orNull ?: System.getenv("GITHUB_ACTOR") | ||
| password = providers.gradleProperty("gpr.key").orNull ?: System.getenv("GITHUB_TOKEN") | ||
| } | ||
| content { includeGroup("com.blueyerobotics") } | ||
| } | ||
| mavenCentral() | ||
| ``` | ||
|
|
||
| Store `gpr.user` and `gpr.key` in your user-level `~/.gradle/gradle.properties`, | ||
| not in source control. Use a GitHub personal access token (classic) with | ||
| `read:packages` and access to the repository. In Actions, a workflow's | ||
| `GITHUB_TOKEN` can be used where it has the required package access. | ||
|
|
||
| After the first release is published, use its full version from the package workflow | ||
| (the run number below is an example): | ||
|
|
||
| ```kotlin | ||
| dependencies { | ||
| implementation("com.blueyerobotics:protocol-definitions:6.5.815") | ||
| } | ||
| ``` | ||
|
|
||
| Both Protobuf runtimes are transitive API dependencies. Consumers do not need a | ||
| Protobuf Gradle plugin or `protoc` installation. | ||
|
|
||
| ```kotlin | ||
| import blueye.protocol.Attitude | ||
| import blueye.protocol.attitude | ||
| import com.google.protobuf.Any as ProtoAny | ||
|
|
||
| val original = attitude { yaw = 90f } | ||
| val decoded = Attitude.parseFrom(original.toByteArray()) | ||
| val packed = ProtoAny.pack(original) | ||
| val unpacked = packed.unpack(Attitude::class.java) | ||
| val descriptor = Attitude.getDescriptor() | ||
| ``` | ||
|
|
||
| Java classes live directly in `blueye.protocol` because the schemas enable | ||
| `java_multiple_files`. This does not change protobuf wire names or field numbers. | ||
| For Protobuf JSON, add `com.google.protobuf:protobuf-java-util` at the same runtime | ||
| version (currently `4.36.2`); tests exercise JSON with an `Any` type registry. | ||
|
|
||
| ## Develop and test | ||
|
|
||
| From `kotlin/`: | ||
|
|
||
| ```sh | ||
| ./gradlew build | ||
| ./gradlew publishProtocolPublicationToSmokeTestRepository -PpackageVersion=6.5.0-local | ||
| ./gradlew -p smoke-test run -PpackageVersion=6.5.0-local | ||
| ``` | ||
|
|
||
| The Gradle build downloads the matching `protoc` artifact and runtimes using the | ||
| version in `../protobuf.version`. Java and Kotlin sources are generated only in | ||
| the build directory. The separate smoke-test project resolves the actual local | ||
| Maven publication to verify the JAR, Kotlin DSL, and transitive dependencies. | ||
| The publication includes a sources JAR, POM, and Gradle module metadata. | ||
|
|
||
| ## Publishing | ||
|
|
||
| `ci-kotlin.yaml` is called by the **Protocol packages** workflow in | ||
| `ci-dotnet.yaml`. The caller supplies the same version to NuGet, Maven, and Swift; | ||
| this reusable workflow does not calculate its own build number. Builds and tests | ||
| run on pushes and pull requests. Upstream branch pushes publish to GitHub Packages | ||
| using `GITHUB_TOKEN` with `packages: write`; pull requests and forks do not publish. | ||
|
|
||
| The shared `version.txt` contains the Blueye App major/minor version, currently | ||
| `6.5`. Master publishes stable `6.5.<run-number>` versions automatically. Other | ||
| branches publish `6.5.<run-number>-branch-<sanitized-branch>`. Local builds default | ||
| to `6.5.0-local`. The run counter belongs to `ci-dotnet.yaml`, so merges to master | ||
| do not require a version-file edit. NuGet and Maven publish first, then the same | ||
| version and source SHA are dispatched to Swift for generation and tagging. | ||
|
|
||
| Published versions are immutable. A workflow rerun keeps its original version; | ||
| prefer rerunning failed jobs so successful publications are not repeated. | ||
|
|
||
| To publish manually after testing, set credentials as above and run | ||
| `./gradlew publishProtocolPublicationToGitHubPackagesRepository -PpackageVersion=<version>`. | ||
| The generic `publish` task also writes to the local smoke-test repository. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.