99 runs-on : ubuntu-latest
1010
1111 steps :
12+ - name : Checkout source
13+ uses : actions/checkout@v4
14+
15+ #
16+ # Download manually-attached ZIP from the GitHub Release
17+ #
1218 - name : Download ZIP from Release Assets
1319 env :
1420 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
1521 run : |
16- echo "Fetching release assets…"
22+ echo "🔍 Searching release assets…"
1723
18- # Get asset download URL
19- ASSET_URL=$(curl -s \
24+ RELEASE_DATA=$(curl -s \
2025 -H "Authorization: Bearer $GITHUB_TOKEN" \
2126 -H "Accept: application/vnd.github+json" \
22- https://api.github.com/repos/${{ github.repository }}/releases/latest \
23- | jq -r '.assets[] | select(.name | endswith(".zip")) | .url')
27+ https://api.github.com/repos/${{ github.repository }}/releases/latest)
28+
29+ ASSET_URL=$(echo "$RELEASE_DATA" | grep -oP '"url": "\K[^"]+' | grep '/assets/' | head -n 1)
2430
25- if [ -z "$ASSET_URL" ] || [ "$ASSET_URL" = "null" ] ; then
26- echo "❌ No ZIP asset found in the release!"
31+ if [ -z "$ASSET_URL" ]; then
32+ echo "❌ No ZIP found in release assets !"
2733 exit 1
2834 fi
2935
30- echo "Found asset URL: $ASSET_URL"
36+ echo "📦 Found asset URL: $ASSET_URL"
3137
32- # Download the ZIP
3338 curl -L \
3439 -H "Authorization: Bearer $GITHUB_TOKEN" \
3540 -H "Accept: application/octet-stream" \
3641 "$ASSET_URL" \
3742 -o decorations-plus.zip
3843
39- echo "📦 Downloaded decorations-plus.zip"
44+ echo "✅ ZIP downloaded: decorations-plus.zip"
4045
46+ #
47+ # Extract release metadata
48+ #
4149 - name : Prepare Release Info
4250 id : info
4351 run : |
4452 echo "tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
53+ echo "is_prerelease=${{ github.event.release.prerelease }}" >> $GITHUB_OUTPUT
54+
4555 echo "body<<EOF" >> $GITHUB_OUTPUT
4656 echo "${{ github.event.release.body }}" >> $GITHUB_OUTPUT
4757 echo "EOF" >> $GITHUB_OUTPUT
48- echo "is_prerelease=${{ github.event.release.prerelease }}" >> $GITHUB_OUTPUT
4958
59+ #
60+ # Upload to CurseForge
61+ #
5062 - name : Upload to CurseForge
5163 env :
5264 CURSEFORGE_TOKEN : ${{ secrets.CURSEFORGE_TOKEN }}
5365 PROJECT_ID : 1356841
5466 RELEASE_TAG : ${{ steps.info.outputs.tag }}
55- IS_PRERELEASE : ${{ steps.info.outputs.is_prerelease }}
5667 RELEASE_BODY : ${{ steps.info.outputs.body }}
68+ IS_PRERELEASE : ${{ steps.info.outputs.is_prerelease }}
5769 run : |
5870 echo "📄 Release tag: $RELEASE_TAG"
5971 echo "📘 Pre-release: $IS_PRERELEASE"
6072
61- # Extract version list from HTML comment
73+ #
74+ # Parse version list from release notes
75+ #
6276 VERSIONS=$(echo "$RELEASE_BODY" | sed -n 's/.*<!-- minecraft-versions: \(.*\) -->.*/\1/p' | tr -d "\r")
77+
6378 if [ -z "$VERSIONS" ]; then
64- echo "❌ No minecraft versions found!"
79+ echo "❌ No minecraft- versions comment found!"
6580 exit 1
6681 fi
6782
68- echo "Found Minecraft versions: $VERSIONS"
83+ echo "🎯 Minecraft versions: $VERSIONS"
6984
85+ #
7086 # Fetch CurseForge version list
71- GAME_VERSIONS=$(curl -s -H "X-Api-Token: ${CURSEFORGE_TOKEN}" \
87+ #
88+ GAME_VERSIONS=$(curl -s -H "X-Api-Token: $CURSEFORGE_TOKEN" \
7289 "https://minecraft.curseforge.com/api/game/versions")
7390
74- # Filter valid MC version IDs using Node
75- VERSION_IDS=$(node <<EOF
91+ #
92+ # Export these so Node can read them
93+ #
94+ export GAME_VERSIONS="$GAME_VERSIONS"
95+ export VERSIONS="$VERSIONS"
96+
97+ #
98+ # Filter ONLY real Minecraft versions using Node.js
99+ #
100+ VERSION_IDS=$(node <<'EOF'
76101 const all = JSON.parse(process.env.GAME_VERSIONS);
77102 const wanted = process.env.VERSIONS.split(",").map(v => v.trim());
78103
79- const matched = all.filter(v =>
104+ const matches = all.filter(v =>
80105 wanted.includes(v.name) &&
81106 v.gameVersionStatus === 1 &&
82107 v.versionType === "release" &&
83108 v.gameVersionTypeID === null
84109 );
85110
86- console.log(JSON.stringify(matched .map(v => v.id)));
111+ console.log(JSON.stringify(matches .map(v => v.id)));
87112 EOF
88113 )
89114
90- echo "🎯 Valid CurseForge IDs: $VERSION_IDS"
115+ echo "🔥 Matching CurseForge IDs: $VERSION_IDS"
91116
92117 if [ "$VERSION_IDS" = "[]" ]; then
93- echo "❌ No valid CurseForge version IDs found !"
118+ echo "❌ No valid CurseForge version IDs matched !"
94119 exit 1
95120 fi
96121
122+ #
97123 # Determine release type
124+ #
98125 RELEASE_TYPE="release"
99126 if [[ "$RELEASE_TAG" == *"beta"* ]] || [[ "$IS_PRERELEASE" == "true" ]]; then
100127 RELEASE_TYPE="beta"
@@ -104,23 +131,29 @@ jobs:
104131
105132 echo "🚀 Release type: $RELEASE_TYPE"
106133
107- # Build metadata JSON (safe, exact formatting)
108- METADATA=$(node <<EOF
109- console.log(JSON.stringify({
134+ #
135+ # Build JSON metadata using Node
136+ #
137+ METADATA=$(node <<'EOF'
138+ const out = {
110139 changelog: process.env.RELEASE_BODY,
111140 changelogType: "markdown",
112141 displayName: "Decorations Plus " + process.env.RELEASE_TAG,
113142 gameVersions: JSON.parse(process.env.VERSION_IDS),
114- releaseType: "${RELEASE_TYPE}"
115- }));
143+ releaseType: process.env.RELEASE_TYPE
144+ };
145+ console.log(JSON.stringify(out));
116146 EOF
117147 )
118148
119- echo "📝 Final metadata :"
149+ echo "📝 Metadata :"
120150 echo "$METADATA"
121151
122- # Upload file
123- echo "📤 Uploading to CurseForge…"
152+ #
153+ # Upload to CurseForge
154+ #
155+ echo "📤 Uploading file to CurseForge…"
156+
124157 RESPONSE=$(curl -X POST \
125158 "https://minecraft.curseforge.com/api/projects/${PROJECT_ID}/upload-file" \
126159 -H "X-Api-Token: ${CURSEFORGE_TOKEN}" \
@@ -137,9 +170,9 @@ jobs:
137170 if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 300 ]; then
138171 FILE_ID=$(node -e "console.log(JSON.parse(process.argv[1]).id || '')" "$BODY")
139172 echo "file_id=$FILE_ID" >> $GITHUB_ENV
140- echo "✅ Upload success — File ID: $FILE_ID"
173+ echo "✅ CurseForge upload successful — File ID: $FILE_ID"
141174 else
142- echo "❌ Upload failed"
175+ echo "❌ Upload failed! "
143176 echo "$BODY"
144177 exit 1
145178 fi
0 commit comments