Skip to content
Draft
Changes from 2 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
116 changes: 116 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Workflow to automatically build the Medieval-Factions plugin JAR and deploy it
# to a running omcsi (open-mc-server-infrastructure) instance.
#
# ─── Setup ───────────────────────────────────────────────────────────────────
# Required GitHub repository secrets:
# OMCSI_DEPLOY_URL – Base URL of your omcsi instance,
# e.g. https://mc.example.com:8092
# OMCSI_DEPLOY_TOKEN – The value set as DEPLOY_AUTH_TOKEN in your omcsi .env
#
# Required GitHub repository variables:
# PLUGIN_JAR_NAME – Filename of the plugin JAR on the server,
# e.g. MedievalFactions.jar (the file that will be replaced)
#
# Optional GitHub repository variables:
# DEPLOY_BRANCH – Branch that triggers a deployment (default: main)
# ─────────────────────────────────────────────────────────────────────────────

name: Deploy Plugin to omcsi

# Trigger on pushes (branch-gated via the job condition) and on manual runs
# via the "Run workflow" button in the Actions tab.
# Note: ${{ vars.* }} expressions are NOT evaluated inside the `on:` event
# filter – only inside job steps and conditions.
on:
push:
workflow_dispatch:
Comment on lines +26 to +28
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.

jobs:
build-and-deploy:
name: Build and Deploy Plugin
# Run on manual dispatch (any branch) or when the pushed branch matches
# DEPLOY_BRANCH (default: main).
if: ${{ github.event_name == 'workflow_dispatch' || github.ref_name == (vars.DEPLOY_BRANCH || 'main') }}
runs-on: ubuntu-latest
permissions:
contents: read

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

- 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.
java-version: '17'

- name: Build plugin JAR
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: Deploy plugin to omcsi
env:
DEPLOY_TOKEN: ${{ secrets.OMCSI_DEPLOY_TOKEN }}
DEPLOY_URL: ${{ secrets.OMCSI_DEPLOY_URL }}
JAR_FILE: ${{ steps.locate-jar.outputs.jar_file }}
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.
if [ -z "${PLUGIN_JAR_NAME}" ]; then
echo "❌ PLUGIN_JAR_NAME variable is not set"
exit 1
fi
if [ -z "${DEPLOY_URL}" ]; then
echo "❌ OMCSI_DEPLOY_URL secret is not set"
exit 1
fi
if [ -z "${DEPLOY_TOKEN}" ]; then
echo "❌ OMCSI_DEPLOY_TOKEN secret is not set"
exit 1
fi

RESPONSE_BODY=$(mktemp)
trap 'rm -f "${RESPONSE_BODY}"' EXIT
HTTP_STATUS=$(curl --silent --write-out "%{http_code}" \
--output "${RESPONSE_BODY}" \
--request POST \
--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.
--form "repoUrl=${{ github.server_url }}/${{ github.repository }}" \
"${DEPLOY_URL}/api/plugins/deploy") || {
echo "❌ curl failed – network error or invalid URL"
exit 1
}

if [ "${HTTP_STATUS}" -eq 200 ]; then
echo "✅ Plugin deployed successfully (HTTP ${HTTP_STATUS})"
elif [ "${HTTP_STATUS}" -eq 401 ]; then
echo "❌ Authentication failed – check OMCSI_DEPLOY_TOKEN (HTTP ${HTTP_STATUS})"
echo "Response body:"; cat "${RESPONSE_BODY}"
exit 1
elif [ "${HTTP_STATUS}" -eq 400 ]; then
echo "❌ Bad request – check PLUGIN_JAR_NAME and the uploaded JAR (HTTP ${HTTP_STATUS})"
echo "Response body:"; cat "${RESPONSE_BODY}"
exit 1
else
echo "❌ Deployment failed (HTTP ${HTTP_STATUS})"
echo "Response body:"; cat "${RESPONSE_BODY}"
exit 1
fi