@@ -0,0 +1,139 @@
|
|||||||
|
name: Build & Publish Bedrock Addon
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
PROJECT_NAME: Construct
|
||||||
|
BP_SOURCE: "packs/BP"
|
||||||
|
RP_SOURCE: "packs/RP"
|
||||||
|
CF_PROJECT_ID: 1283139
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Package mcaddon
|
||||||
|
run: |
|
||||||
|
VERSION=${{ github.event.release.tag_name }}
|
||||||
|
OUTPUT="${PROJECT_NAME}-${VERSION}.mcaddon"
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
cp -r "$BP_SOURCE" "build/${BP_SOURCE}"
|
||||||
|
cp -r "$RP_SOURCE" "build/${RP_SOURCE}"
|
||||||
|
cp LICENSE "build/${BP_SOURCE}"
|
||||||
|
cp LICENSE "build/${RP_SOURCE}"
|
||||||
|
|
||||||
|
cd build
|
||||||
|
zip -r "$OUTPUT" "${BP_SOURCE}" "${RP_SOURCE}"
|
||||||
|
mv "$OUTPUT" ..
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
- name: Upload asset to GitHub Release
|
||||||
|
uses: softprops/action-gh-release@e798e6a1ede8d07b74ac4cdac6bdfa4cc1653907
|
||||||
|
with:
|
||||||
|
files: ${{ env.PROJECT_NAME }}-${{ github.event.release.tag_name }}.mcaddon
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Upload to CurseForge
|
||||||
|
env:
|
||||||
|
RELEASE_BODY: ${{ github.event.release.body }}
|
||||||
|
run: |
|
||||||
|
VERSION=${{ github.event.release.tag_name }}
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Read the game version from manifest.json
|
||||||
|
MIN_ENGINE_VERSION=$(sed -E 's,//.*$,,' "$BP_SOURCE/manifest.json" | jq -r '.header.min_engine_version | @csv')
|
||||||
|
IFS=',' read -r LEADING MAJOR MINOR <<< "$MIN_ENGINE_VERSION"
|
||||||
|
ENGINE_PREFIX="${MAJOR}.${MINOR}"
|
||||||
|
|
||||||
|
# Fetch all Bedrock versions from CurseForge API
|
||||||
|
CF_VERSIONS_HTTP=$(curl -sS -L \
|
||||||
|
-o curseforge-versions.json \
|
||||||
|
-w "%{http_code}" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "X-Api-Token: ${{ secrets.CF_API_TOKEN }}" \
|
||||||
|
"https://minecraft-bedrock.curseforge.com/api/game/versions")
|
||||||
|
if [ "$CF_VERSIONS_HTTP" -lt 200 ] || [ "$CF_VERSIONS_HTTP" -ge 300 ]; then
|
||||||
|
echo "CurseForge versions API returned HTTP $CF_VERSIONS_HTTP"
|
||||||
|
cat curseforge-versions.json
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Guard against non-JSON responses (HTML/proxy errors), which break jq parsing later.
|
||||||
|
if ! jq -e . curseforge-versions.json >/dev/null; then
|
||||||
|
echo "CurseForge versions API response was not valid JSON"
|
||||||
|
cat curseforge-versions.json
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract all game version IDs whose name matches the game version from the manifest.json
|
||||||
|
GAME_VERSION_IDS=$(jq -c --arg prefix "$ENGINE_PREFIX" '
|
||||||
|
if type == "array" then
|
||||||
|
[ .[] | select((.name // "") | startswith($prefix)) | .id ]
|
||||||
|
elif (type == "object" and has("data") and (.data | type == "array")) then
|
||||||
|
[ .data[] | select((.name // "") | startswith($prefix)) | .id ]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
' curseforge-versions.json)
|
||||||
|
if [ "$GAME_VERSION_IDS" = "[]" ]; then
|
||||||
|
echo "No matching CurseForge versions found for engine prefix $ENGINE_PREFIX"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Found CurseForge version IDs for game version $ENGINE_PREFIX: $GAME_VERSION_IDS"
|
||||||
|
|
||||||
|
PACK_FILENAME=${PROJECT_NAME}-$VERSION.mcaddon
|
||||||
|
|
||||||
|
# Build metadata as JSON so the changelog is uploaded with preserved Markdown.
|
||||||
|
printf "%s" "$RELEASE_BODY" > curseforge-changelog.md
|
||||||
|
jq -n \
|
||||||
|
--rawfile changelog curseforge-changelog.md \
|
||||||
|
--arg displayName "$PACK_FILENAME" \
|
||||||
|
--argjson gameVersions "$GAME_VERSION_IDS" \
|
||||||
|
'{
|
||||||
|
changelog: $changelog,
|
||||||
|
changelogType: "markdown",
|
||||||
|
displayName: $displayName,
|
||||||
|
releaseType: "release",
|
||||||
|
gameVersions: $gameVersions
|
||||||
|
}' > curseforge-metadata.json
|
||||||
|
METADATA_JSON=$(jq -c . curseforge-metadata.json)
|
||||||
|
|
||||||
|
# Upload the behavior pack
|
||||||
|
UPLOAD_HTTP=$(curl -sS -X POST \
|
||||||
|
-o curseforge-upload-response.json \
|
||||||
|
-w "%{http_code}" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "X-Api-Token: ${{ secrets.CF_API_TOKEN }}" \
|
||||||
|
--form-string "metadata=$METADATA_JSON" \
|
||||||
|
-F "file=@$PACK_FILENAME" \
|
||||||
|
https://minecraft-bedrock.curseforge.com/api/projects/$CF_PROJECT_ID/upload-file
|
||||||
|
)
|
||||||
|
if [ "$UPLOAD_HTTP" -lt 200 ] || [ "$UPLOAD_HTTP" -ge 300 ]; then
|
||||||
|
echo "CurseForge upload returned HTTP $UPLOAD_HTTP"
|
||||||
|
cat curseforge-upload-response.json
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! jq -e . curseforge-upload-response.json >/dev/null; then
|
||||||
|
echo "CurseForge upload response was not valid JSON"
|
||||||
|
cat curseforge-upload-response.json
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
UPLOADED_ID=$(jq -r '.id // empty' curseforge-upload-response.json)
|
||||||
|
if [ -n "$UPLOADED_ID" ]; then
|
||||||
|
echo "Successfully uploaded release. File ID: $UPLOADED_ID"
|
||||||
|
else
|
||||||
|
echo "Upload failed. Response:"
|
||||||
|
cat curseforge-upload-response.json
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -74,4 +74,4 @@ If you have any issues or suggestions, please don't hesitate to open an issue on
|
|||||||
|
|
||||||
### Adding Translations
|
### Adding Translations
|
||||||
|
|
||||||
Construct currently only supports American English, but has translation capabilities. If you would like to contribute a translation, please join our Discord and reach out!
|
Construct currently supports American English and Chinese (thanks to [wed150](https://github.com/wed150) & [EndrTrekker](https://github.com/EndrTrekker)). If you would like to contribute a translation, please join our Discord and reach out!
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"format_version": 2,
|
"format_version": 2,
|
||||||
"header": {
|
"header": {
|
||||||
"name": "Construct [BP] v1.0.7",
|
"name": "Construct [BP] v1.0.8",
|
||||||
"description": "Survival building addon by §aForestOfLight§r.",
|
"description": "Survival building addon by §aForestOfLight§r.",
|
||||||
"uuid": "8c0c0153-d8b9-482a-889f-aef922b8fe58",
|
"uuid": "8c0c0153-d8b9-482a-889f-aef922b8fe58",
|
||||||
"min_engine_version": [1, 26, 0],
|
"min_engine_version": [1, 26, 10],
|
||||||
"version": [1, 0, 7]
|
"version": [1, 0, 8]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
"dependencies": [
|
"dependencies": [
|
||||||
{
|
{
|
||||||
"module_name": "@minecraft/server",
|
"module_name": "@minecraft/server",
|
||||||
"version": "2.6.0-beta"
|
"version": "2.7.0-beta"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"module_name": "@minecraft/server-ui",
|
"module_name": "@minecraft/server-ui",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"uuid": "375ec465-3dc1-429f-8b4c-a337889e1ed4", // Construct RP
|
"uuid": "375ec465-3dc1-429f-8b4c-a337889e1ed4", // Construct RP
|
||||||
"version": [1, 0, 7]
|
"version": [1, 0, 8]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
@@ -33,12 +33,6 @@ export class MenuFormBuilder {
|
|||||||
allStructuresForm.button(`§2${structureName}`);
|
allStructuresForm.button(`§2${structureName}`);
|
||||||
});
|
});
|
||||||
allStructuresForm.button({ translate: 'construct.mainmenu.selectstructure.other' });
|
allStructuresForm.button({ translate: 'construct.mainmenu.selectstructure.other' });
|
||||||
//allStructuresForm.button({ translate: 'construct.mainmenu.selectstructure.howto' }); useless
|
|
||||||
//here is a same button at buildAllInstanceName() already
|
|
||||||
//It work as the button construct.mainmenu.selectstructure.other
|
|
||||||
|
|
||||||
//here is no locationkey named construct.mainmenu.selectstructure.howto but there's a key named construct.mainmenu.howto
|
|
||||||
|
|
||||||
return allStructuresForm;
|
return allStructuresForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"format_version": 2,
|
"format_version": 2,
|
||||||
"header": {
|
"header": {
|
||||||
"name": "Construct [RP] v1.0.7",
|
"name": "Construct [RP] v1.0.8",
|
||||||
"description": "Survival building addon by §aForestOfLight§r.",
|
"description": "Survival building addon by §aForestOfLight§r.",
|
||||||
"uuid": "375ec465-3dc1-429f-8b4c-a337889e1ed4",
|
"uuid": "375ec465-3dc1-429f-8b4c-a337889e1ed4",
|
||||||
"version": [1, 0, 7],
|
"version": [1, 0, 8],
|
||||||
"min_engine_version": [1,26,0]
|
"min_engine_version": [1,26,10]
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"dependencies": [
|
"dependencies": [
|
||||||
{
|
{
|
||||||
"uuid": "8c0c0153-d8b9-482a-889f-aef922b8fe58", // Construct BP
|
"uuid": "8c0c0153-d8b9-482a-889f-aef922b8fe58", // Construct BP
|
||||||
"version": [1, 0, 7]
|
"version": [1, 0, 8]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
|
|||||||
Reference in New Issue
Block a user