[CI/CD] Add CI/CD workflow for extensions#50
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the extensions build and CI/CD pipeline to (a) run tests/coverage reporting in CI and (b) produce a Docker build context that includes built extension JARs, intended to enable publishing an “all extensions” manager image.
Changes:
- Add a
deploymentproject (Dockerfile + build context) and per-extension Gradle tasks to copy extension JARs intodeployment/build/extensions. - Update CI workflow to spin up the dev-testing docker-compose stack, run
./gradlew build, and build multi-arch Docker images. - Enable JaCoCo reporting across Java subprojects and adjust ENTSO-E test ignores.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
gradle.properties |
Disables parallel Gradle and adds camelVersion property. |
build.gradle |
Enables JaCoCo + report generation for Java subprojects. |
entsoe/src/test/.../EntsoeProtocolTest.groovy |
Removes CI-wide ignore and ignores a specific test. |
entsoe/build.gradle |
Adds copyExtension task to stage the built JAR into deployment/build/extensions. |
ems/build.gradle |
Adds copyExtension task to stage the built JAR into deployment/build/extensions. |
deployment/Dockerfile |
Defines an image that layers staged extensions onto openremote/manager:latest-core. |
deployment/build.gradle |
Copies Dockerfile into the Docker build context (but currently at configuration time). |
.github/workflows/release.yml |
Removes the old release workflow. |
.github/workflows/ci_cd.yml |
Overhauls CI to run docker-compose-based integration tests and build/publish Docker/Maven artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@codex review |
| @@ -1,5 +1,5 @@ | |||
| org.gradle.jvmargs=-Xmx3g | |||
| org.gradle.parallel=true | |||
| org.gradle.parallel=false | |||
There was a problem hiding this comment.
Can you create an issue for adding back support for this?
| FROM openremote/manager:latest-core | ||
|
|
||
| RUN mkdir -p /deployment/manager/extensions | ||
| COPY extensions /deployment/manager/extensions No newline at end of file |
| tasks.register("prepareDockerContext", Copy) { | ||
| from(layout.projectDirectory.file("Dockerfile")) | ||
| into(layout.buildDirectory) | ||
| } |
| MAVEN_SIGNING_KEY: ${{ secrets._TEMP_MAVEN_SIGNING_KEY }} | ||
| MAVEN_SIGNING_PASSWORD: ${{ secrets._TEMP_MAVEN_SIGNING_PASSWORD }} | ||
| MAVEN_USERNAME: ${{ secrets._TEMP_MAVEN_USERNAME }} | ||
| MAVEN_PASSWORD: ${{ secrets._TEMP_MAVEN_PASSWORD }} |
| username: ${{ secrets._TEMP_DOCKERHUB_USER }} | ||
| password: ${{ secrets._TEMP_DOCKERHUB_PASSWORD }} |
| closeClient() | ||
| } | ||
|
|
||
| @Ignore |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a504a2972
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| tasks.register("copyExtension", Copy) { | ||
| dependsOn jar | ||
| from(jar.archiveFile) | ||
| into project(":deployment").layout.buildDirectory.dir("extensions") |
There was a problem hiding this comment.
Copy the EMS jar into the Docker context
This new Docker context is populated only by :entsoe:copyExtension; deployment/Dockerfile copies deployment/build/extensions, and a repo-wide check for copyExtension shows no equivalent task in ems/build.gradle. The develop/release manager images built by this workflow will therefore ship with openremote-entsoe-extension.jar but omit openremote-ems-extension.jar, so EMS services/models are not on the image classpath even though EMS is one of the official extensions.
Useful? React with 👍 / 👎.
| run: | | ||
| # Run build | ||
| # Make temp dir with 777 mask as docker seems to run as root | ||
| mkdir -pm 777 tmp |
There was a problem hiding this comment.
Create tmp under the OpenRemote checkout
This prepares tmp in the extensions checkout, but the compose file used two lines later is openremote/profile/dev-testing.yml, whose ../tmp:/storage bind resolves relative to the first -f compose file's directory (Docker documents paths as relative to the first compose file), i.e. openremote/tmp. In CI this chmods an unused directory while Compose creates/mounts openremote/tmp with default permissions, so tests that rely on the dev-testing shared storage can still hit the root-owned-directory problem this step is trying to avoid.
Useful? React with 👍 / 👎.
|
|
||
| # Release | ||
| release: | ||
| types: [ published ] |
There was a problem hiding this comment.
Exclude prereleases before pushing latest
Using the published release activity also runs for GitHub prereleases, but the release-only steps below push openremote/manager:latest and publish to Sonatype without checking github.event.release.prerelease. If someone publishes an RC/beta as a prerelease, this workflow will overwrite the production latest Docker tag and attempt a Maven release for that prerelease; add a prerelease guard or use a release activity that excludes prereleases.
Useful? React with 👍 / 👎.
| @@ -0,0 +1,4 @@ | |||
| FROM openremote/manager:latest-core | |||
There was a problem hiding this comment.
Pin the release image to the matching core
The release workflow tags the resulting image as the release version, but this Dockerfile always starts from the floating openremote/manager:latest-core. When an older release is rebuilt or when the core latest-core tag has advanced before the extension release runs, the image tagged with github.event.release.tag_name will contain a different manager core than the Gradle artifacts were built against, making the release image non-reproducible and potentially incompatible.
Useful? React with 👍 / 👎.
| -PkeystoreKeyAlias=$KEYSTORE_KEY_ALIAS -PkeystoreKeyPassword=$KEYSTORE_KEY_PASSWORD -PkeystoreFile=$PWD/keystore -PkeystorePassword=$KEYSTORE_PASSWORD | ||
| uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 | ||
| with: | ||
| platforms: linux/amd64,linux/arm64 |
There was a problem hiding this comment.
The docker/setup-qemu-action input is passed directly to tonistiigi/binfmt --install, and the action documents this field as architecture names such as arm64,riscv64,arm, not buildx platform strings. With linux/amd64,linux/arm64 here, the QEMU setup step can fail before both develop and release image builds; use arm64 or omit the input to install all emulators.
Useful? React with 👍 / 👎.
|
|
||
| # Release | ||
| release: | ||
| types: [ published ] |
There was a problem hiding this comment.
Avoid cancelling release runs with tag builds
Adding the release trigger while keeping the existing tag push trigger puts both runs in the same concurrency group because GitHub sets release GITHUB_REF to the tag ref. When a release is published while creating the tag, the tag-push build and the release-publish run can cancel each other under cancel-in-progress: true; if the push run wins, it only builds/tests and skips the Docker/Maven release steps.
Useful? React with 👍 / 👎.
| MAVEN_SIGNING_KEY: ${{ secrets._TEMP_MAVEN_SIGNING_KEY }} | ||
| MAVEN_SIGNING_PASSWORD: ${{ secrets._TEMP_MAVEN_SIGNING_PASSWORD }} | ||
| MAVEN_USERNAME: ${{ secrets._TEMP_MAVEN_USERNAME }} | ||
| MAVEN_PASSWORD: ${{ secrets._TEMP_MAVEN_PASSWORD }} |
There was a problem hiding this comment.
Preserve the Maven secret fallback
The previous publish path accepted either _TEMP_MAVEN_* or the stable MAVEN_* secrets, but this release path only maps the temporary names. In repositories/environments that still use the existing stable secret names, these env vars resolve to empty strings and the Sonatype publish/signing step fails even though the credentials are still configured under the supported names.
Useful? React with 👍 / 👎.
This PR includes the following changes:
developimage on push to main and publish it to DockerHub with tagopenremote/manager:developincluding ALL extensions (except EMS).managerimage when a new release is created an publish it to DockerHub with tag'openremote/manager:latestandopenremote/manager:$versionincluding ALL extensions (except EMS).deploymentfolder so they can be included when building a new image.