Skip to content
Merged
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
143 changes: 143 additions & 0 deletions .github/workflows/create-release-tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Create OreSpawn release tag
run-name: Create OreSpawn tag from ${{ inputs.release_ref }}

on:
workflow_dispatch:
inputs:
release_ref:
description: MMD target branch or commit to tag, for example master-1.10.2.
required: true
default: master-1.10.2
type: string
confirm_version:
description: Exact four-component version declared by the target, for example 4.0.8.110021.
required: true
type: string

permissions:
actions: read
contents: write

concurrency:
group: orespawn-create-tag-${{ inputs.confirm_version }}
cancel-in-progress: false

jobs:
create-release-tag:
name: Validate candidate and create tag
if: github.repository == 'MinecraftModDevelopmentMods/OreSpawn'
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out selected release candidate
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ inputs.release_ref }}
fetch-depth: 0

- name: Validate target, version, and prior CI
id: validate
env:
GH_TOKEN: ${{ github.token }}
CONFIRM_VERSION: ${{ inputs.confirm_version }}
run: |
set -euo pipefail

value() { sed -n "s/^$1=//p" gradle.properties; }
release_version="$(value mod_version)"
minecraft_version="$(value minecraft_version)"
loader_name="$(value loader_name)"
loader_code="$(value loader_code)"

for required in release_version minecraft_version loader_name loader_code; do
if [[ -z "${!required}" ]]; then
echo "Selected ref is missing required release metadata: $required" >&2
exit 1
fi
done

IFS=. read -r mc_major mc_minor mc_patch extra <<<"$minecraft_version"
if [[ -n "${extra:-}" || -z "${mc_major:-}" || -z "${mc_minor:-}" ]]; then
echo "Invalid minecraft_version=$minecraft_version" >&2
exit 1
fi
mc_patch="${mc_patch:-0}"
if [[ ! "$mc_major" =~ ^[0-9]+$ || ! "$mc_minor" =~ ^[0-9]+$ || ! "$mc_patch" =~ ^[0-9]+$ ]]; then
echo "Invalid minecraft_version=$minecraft_version" >&2
exit 1
fi
case "$loader_name:$loader_code" in
forge:1|neoforge:2) ;;
*) echo "Invalid loader metadata $loader_name/$loader_code" >&2; exit 1 ;;
esac

printf -v minor_padded '%02d' "$((10#$mc_minor))"
printf -v patch_padded '%02d' "$((10#$mc_patch))"
target_suffix="${mc_major}${minor_padded}${patch_padded}${loader_code}"
if [[ ! "$release_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.${target_suffix}$ ]]; then
echo "mod_version $release_version does not match $minecraft_version $loader_name target $target_suffix" >&2
exit 1
fi
if [[ "$CONFIRM_VERSION" != "$release_version" ]]; then
echo "confirm_version must equal $release_version" >&2
exit 1
fi
if [[ ! -f .github/workflows/release-on-tag.yml ]]; then
echo "Selected target has not adopted the validated tag workflow" >&2
exit 1
fi

release_sha="$(git rev-parse HEAD)"
successful_ci="$(gh api \
"repos/$GITHUB_REPOSITORY/commits/$release_sha/check-runs?per_page=100" \
--jq '[.check_runs[] | select(.name == "Build, test, and audit" and .conclusion == "success")] | length')"
if [[ "$successful_ci" -lt 1 ]]; then
echo "The selected commit has no successful Build, test, and audit check" >&2
exit 1
fi
if gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$release_version" >/dev/null 2>&1; then
echo "Tag $release_version already exists" >&2
exit 1
fi

echo "release_version=$release_version" >> "$GITHUB_OUTPUT"
echo "release_sha=$release_sha" >> "$GITHUB_OUTPUT"

- name: Create the validated release tag
env:
GH_TOKEN: ${{ github.token }}
RELEASE_VERSION: ${{ steps.validate.outputs.release_version }}
RELEASE_SHA: ${{ steps.validate.outputs.release_sha }}
run: |
set -euo pipefail
gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \
-f ref="refs/tags/$RELEASE_VERSION" \
-f sha="$RELEASE_SHA" >/dev/null

created_sha="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$RELEASE_VERSION" --jq '.object.sha')"
if [[ "$created_sha" != "$RELEASE_SHA" ]]; then
echo "Created tag resolved to $created_sha instead of $RELEASE_SHA" >&2
exit 1
fi

- name: Show the manual publication step
env:
RELEASE_VERSION: ${{ steps.validate.outputs.release_version }}
RELEASE_SHA: ${{ steps.validate.outputs.release_sha }}
RELEASE_WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/workflows/deploy-release.yml
run: |
{
echo "## Release tag created"
echo
echo "Tag \`$RELEASE_VERSION\` now points to validated commit \`$RELEASE_SHA\`."
echo
echo "**Nothing has been published.**"
echo
echo "To continue, open [Deploy OreSpawn release]($RELEASE_WORKFLOW_URL), select **Run workflow**, and enter:"
echo
echo "- mode: \`publish\`"
echo "- release_ref: \`$RELEASE_VERSION\`"
echo "- curseforge_channel: \`release\`, \`beta\`, or \`alpha\`"
echo "- confirm_version: \`$RELEASE_VERSION\`"
} >> "$GITHUB_STEP_SUMMARY"
Loading