Skip to content

Add GitHub Actions workflow to build and deploy plugin to OMCSI#1948

Draft
Copilot wants to merge 5 commits intomainfrom
copilot/add-github-actions-workflow
Draft

Add GitHub Actions workflow to build and deploy plugin to OMCSI#1948
Copilot wants to merge 5 commits intomainfrom
copilot/add-github-actions-workflow

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 7, 2026

Adds a CI/CD workflow that builds the plugin JAR via Gradle and deploys it to an omcsi instance.

  • Trigger: Push to DEPLOY_BRANCH (default: main) + manual workflow_dispatch
  • Build: Zulu JDK 17 / ./gradlew shadowJar / shadow JAR (*-all.jar) from build/libs/
  • Ponder dependency: Clones Dans-Plugins/Ponder at tag 2.0.0 and installs to Maven local before building (the repo.dansplugins.com Maven repository is currently down)
  • Dependency caching: Uses gradle/actions/setup-gradle@v3 for Gradle dependency caching (consistent with publish-release.yml)
  • Build resilience: Retry logic (3 attempts, 30s backoff) handles transient network failures from external Maven repositories
  • Deploy: POST to ${OMCSI_DEPLOY_URL}/api/plugins/deploy with bearer auth
  • Validation: Fails fast with clear messages on missing PLUGIN_JAR_NAME, OMCSI_DEPLOY_URL, OMCSI_DEPLOY_TOKEN, or non-200 responses (401 → auth error, 400 → bad request)
  • Security: All GitHub context values (vars.PLUGIN_JAR_NAME, github.ref_name, github.server_url/github.repository) are passed via the env: block to prevent shell injection

Additional build.gradle changes

  • Added mavenLocal() to repositories so locally-installed Ponder artifacts can be resolved
  • Moved JitPack to the end of the repository list and added Gradle content filtering (includeGroupByRegex 'com\\.github\\..*') so JitPack is only queried for com.github.* artifacts — this prevents JitPack timeouts from blocking resolution of rpkit and other non-GitHub artifacts from their proper repositories

Required repo configuration

Type Name Description
Secret OMCSI_DEPLOY_URL Base URL of the omcsi instance
Secret OMCSI_DEPLOY_TOKEN DEPLOY_AUTH_TOKEN from omcsi .env
Variable PLUGIN_JAR_NAME Target JAR filename on the server
Variable DEPLOY_BRANCH Branch that triggers deploys (optional, default: main)

Modeled after the Activity Tracker deploy workflow, adjusted for this project's Gradle/JDK 17 toolchain and consistent with the existing publish-release.yml workflow (Zulu JDK, shadowJar task).

Original prompt

This section details on the original issue you should resolve

<issue_title>Add GitHub Actions workflow to build and deploy plugin to OMCSI</issue_title>
<issue_description>## Summary

Add a .github/workflows/deploy.yml file that automatically builds the plugin JAR and deploys it to the omcsi (open-mc-server-infrastructure) instance when changes are pushed to the deploy branch.

Implementation

Create .github/workflows/deploy.yml modeled after the Activity Tracker reference workflow with the following adjustments for this project:

  • JDK version: [8 / 11 / 17 / 21]
  • Build tool & command:
    • Maven: mvn --batch-mode package
    • Gradle: ./gradlew build
  • JAR location:
    • Maven: target/ (exclude original-*, *-sources.jar, *-javadoc.jar)
    • Gradle: build/libs/ (exclude *-sources.jar, *-javadoc.jar)

Required Secrets

Add via repo Settings → Secrets and variables → Actions:

Secret Value
OMCSI_DEPLOY_URL Base URL of the omcsi instance, e.g. https://mc.example.com:8092
OMCSI_DEPLOY_TOKEN Value of DEPLOY_AUTH_TOKEN from the omcsi .env file

Required Variables

Add via repo Settings → Secrets and variables → Actions → Variables:

Variable Value
PLUGIN_JAR_NAME Filename of the JAR on the server, e.g. MyPlugin.jar
DEPLOY_BRANCH Branch that triggers deploys (default: main)

Acceptance Criteria

  • .github/workflows/deploy.yml exists in the repo
  • Pushing to the deploy branch triggers a build and successful deploy
  • Workflow can also be triggered manually via the Actions tab (workflow_dispatch)
  • Failed builds, missing variables, auth errors, and bad requests all produce a clear error message and non-zero exit code
  • Secrets and variables documented in this ticket are configured in the repo

Reference

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copilot AI changed the title [WIP] Add GitHub Actions workflow to build and deploy plugin Add GitHub Actions workflow to build and deploy plugin to OMCSI Mar 7, 2026
@dmccoystephenson dmccoystephenson requested a review from Copilot March 7, 2026 03:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new GitHub Actions workflow (.github/workflows/deploy.yml) that automatically builds the Medieval Factions plugin JAR using Gradle and deploys it to an omcsi (open-mc-server-infrastructure) instance. The workflow triggers on pushes to a configurable deploy branch (defaulting to main) and supports manual dispatch.

Changes:

  • Added a new CI/CD workflow file that builds the plugin, locates the output JAR, and deploys it via a POST request to the omcsi deploy API with bearer authentication
  • Includes input validation for required secrets/variables and HTTP status code handling with descriptive error messages
  • Supports configurable deploy branch via a repository variable (DEPLOY_BRANCH)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +65
run: ./gradlew build

- name: Locate built JAR
id: locate-jar
run: |
# Use find to reliably locate the shadow JAR, excluding any
# *-sources / *-javadoc JARs.
JAR_FILE=$(find build/libs -maxdepth 1 -name '*.jar' \
! -name '*-sources.jar' \
! -name '*-javadoc.jar' \
-print -quit)
if [ -z "${JAR_FILE}" ]; then
echo "❌ No JAR found in build/libs/"
exit 1
fi
echo "jar_file=${JAR_FILE}" >> "$GITHUB_OUTPUT"
echo "✅ Found JAR: ${JAR_FILE}"
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The find command picks the first JAR it encounters, but build/libs/ will contain both the regular JAR (medieval-factions-5.7.2.jar) and the shadow/fat JAR (medieval-factions-5.7.2-all.jar) since the shadow plugin sets archiveClassifier.set('all') in build.gradle. The order find returns files is non-deterministic, so this may deploy the regular JAR (without bundled dependencies) instead of the shadow JAR, which would fail at runtime.

You should either:

  1. Target the shadow JAR specifically by matching *-all.jar (e.g., find build/libs -name '*-all.jar' -print -quit), or
  2. Use ./gradlew shadowJar as the build command (consistent with publish-release.yml) and only match the shadow JAR.
Suggested change
run: ./gradlew build
- name: Locate built JAR
id: locate-jar
run: |
# Use find to reliably locate the shadow JAR, excluding any
# *-sources / *-javadoc JARs.
JAR_FILE=$(find build/libs -maxdepth 1 -name '*.jar' \
! -name '*-sources.jar' \
! -name '*-javadoc.jar' \
-print -quit)
if [ -z "${JAR_FILE}" ]; then
echo "❌ No JAR found in build/libs/"
exit 1
fi
echo "jar_file=${JAR_FILE}" >> "$GITHUB_OUTPUT"
echo "✅ Found JAR: ${JAR_FILE}"
run: ./gradlew shadowJar
- name: Locate built JAR
id: locate-jar
run: |
# Use find to reliably locate the shadow/fat JAR (with the `-all` classifier).
JAR_FILE=$(find build/libs -maxdepth 1 -name '*-all.jar' -print -quit)
if [ -z "${JAR_FILE}" ]; then
echo "❌ No shadow JAR (-all.jar) found in build/libs/"
exit 1
fi
echo "jar_file=${JAR_FILE}" >> "$GITHUB_OUTPUT"
echo "✅ Found shadow JAR: ${JAR_FILE}"

Copilot uses AI. Check for mistakes.
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing workflows in this repository (medieval-factions.yml and publish-release.yml) both use the zulu JDK distribution. This workflow uses temurin instead. For consistency across workflows, consider using zulu here as well (see .github/workflows/publish-release.yml:24 and .github/workflows/medieval-factions.yml:17).

Suggested change
distribution: temurin
distribution: zulu

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +26
on:
push:
workflow_dispatch:
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The on: push trigger without any branch filter will cause this workflow to appear (as skipped) for every push to every branch in the repository. While the if condition correctly gates execution, this adds noise to the Actions tab. Consider adding a branch filter that covers the expected deploy branch(es), e.g. branches: [main], and still keep the if condition as a safeguard for the variable-based override. Alternatively, if supporting arbitrary DEPLOY_BRANCH values is important, the current approach is acceptable but worth documenting.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +73
run: |
PLUGIN_JAR_NAME="${{ vars.PLUGIN_JAR_NAME }}"
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${{ vars.PLUGIN_JAR_NAME }} is interpolated directly into the shell script, which means if the variable contains shell metacharacters (e.g., spaces, semicolons, backticks), it could break the script or lead to injection. Consider assigning it to an environment variable using the env: block (similar to how DEPLOY_TOKEN and DEPLOY_URL are handled) instead of using direct ${{ }} interpolation in the run: block.

Suggested change
run: |
PLUGIN_JAR_NAME="${{ vars.PLUGIN_JAR_NAME }}"
PLUGIN_JAR_NAME: ${{ vars.PLUGIN_JAR_NAME }}
run: |

Copilot uses AI. Check for mistakes.
--header "Authorization: Bearer ${DEPLOY_TOKEN}" \
--form "pluginName=${PLUGIN_JAR_NAME}" \
--form "file=@${JAR_FILE}" \
--form "branch=${{ github.ref_name }}" \
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly to PLUGIN_JAR_NAME, ${{ github.ref_name }} on this line is directly interpolated into the shell script. Branch names can contain characters that are special in shell (e.g., single quotes). This is a script injection risk. Consider passing these values via the env: block and referencing them as shell variables instead.

Copilot uses AI. Check for mistakes.
@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot address comments

…jection safety

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 7, 2026

@copilot address comments

All review comments addressed in b8d5e13:

  • Switched to ./gradlew shadowJar and *-all.jar matching for deterministic fat JAR selection
  • Changed JDK distribution to zulu for consistency with existing workflows
  • Moved PLUGIN_JAR_NAME, github.ref_name, and github.server_url/github.repository into the env: block to prevent shell injection
  • Added documentation explaining why the on: push trigger has no branch filter (required for variable-based DEPLOY_BRANCH)

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot Ponder (https://www.github.com/Dans-Plugins/Ponder) must be built from source and installed to Maven locally; the Maven repo is currently down

…ency resolution

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 7, 2026

@copilot Ponder (https://www.github.com/Dans-Plugins/Ponder) must be built from source and installed to Maven locally; the Maven repo is currently down

Addressed in 99dd43c. The deploy workflow now clones Dans-Plugins/Ponder at the 2.0.0 tag and runs ./gradlew publishToMavenLocal before building the plugin. Also added mavenLocal() to build.gradle repositories so the locally-installed Ponder artifacts are resolved.

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot The Deploy Plugin to omcsi GitHub Action is failing due to dependency resolution:

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':shadowJar'.
> Could not resolve all dependencies for configuration ':runtimeClasspath'.
   > Could not resolve com.github.Dans-Plugins:Mailboxes:v1.1.
     Required by:
         project :
      > Could not resolve com.github.Dans-Plugins:Mailboxes:v1.1.
         > Could not get resource 'https://jitpack.io/com/github/Dans-Plugins/Mailboxes/v1.1/Mailboxes-v1.1.pom'.
            > Could not GET 'https://jitpack.io/com/github/Dans-Plugins/Mailboxes/v1.1/Mailboxes-v1.1.pom'.
               > Read timed out
   > Could not resolve com.rpkit:rpk-player-lib-bukkit:2.3.2.
     Required by:
         project :
      > Could not resolve com.rpkit:rpk-player-lib-bukkit:2.3.2.
         > Could not get resource 'https://jitpack.io/com/rpkit/rpk-player-lib-bukkit/2.3.2/rpk-player-lib-bukkit-2.3.2.pom'.
            > Could not GET 'https://jitpack.io/com/rpkit/rpk-player-lib-bukkit/2.3.2/rpk-player-lib-bukkit-2.3.2.pom'.
               > Read timed out
   > Could not resolve com.rpkit:rpk-notification-lib-bukkit:2.3.2.
     Required by:
         project :
      > Could not resolve com.rpkit:rpk-notification-lib-bukkit:2.3.2.
         > Could not get resource 'https://jitpack.io/com/rpkit/rpk-notification-lib-bukkit/2.3.2/rpk-notification-lib-bukkit-2.3.2.pom'.
            > Could not GET 'https://jitpack.io/com/rpkit/rpk-notification-lib-bukkit/2.3.2/rpk-notification-lib-bukkit-2.3.2.pom'.
               > Read timed out
   > Could not resolve com.rpkit:rpk-lock-lib-bukkit:2.3.2.
     Required by:
         project :
      > Could not resolve com.rpkit:rpk-lock-lib-bukkit:2.3.2.
         > Could not get resource 'https://jitpack.io/com/rpkit/rpk-lock-lib-bukkit/2.3.2/rpk-lock-lib-bukkit-2.3.2.pom'.
            > Could not GET 'https://jitpack.io/com/rpkit/rpk-lock-lib-bukkit/2.3.2/rpk-lock-lib-bukkit-2.3.2.pom'.
               > Read timed out

…, add Gradle caching and build retries

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 8, 2026

@copilot The Deploy Plugin to omcsi GitHub Action is failing due to dependency resolution:

...

Fixed in 0660c24. The root cause was JitPack being tried before repo.rpkit.com for rpkit artifacts — JitPack timeouts blocked resolution entirely. Changes:

  • build.gradle: Moved JitPack to the end of the repository list and added content { includeGroupByRegex 'com\\.github\\..*' } so Gradle only queries JitPack for com.github.* artifacts (i.e. Mailboxes). rpkit artifacts now resolve directly from repo.rpkit.com without hitting JitPack.
  • deploy.yml: Added gradle/actions/setup-gradle@v3 for dependency caching (consistent with publish-release.yml) and retry logic (3 attempts, 30s backoff) for transient JitPack failures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add GitHub Actions workflow to build and deploy plugin to OMCSI

3 participants