From c1fc24adf904bca9e3b0c3644363cd5aeda23327 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 5 Oct 2026 19:47:10 +0200 Subject: [PATCH] Release from the version in project.godot The version now lives in project.godot (application/config/version) and Settings.version reads it from there. The Build workflow tests and exports on every push, and on main creates the tag, uploads the builds and creates the Gitea release when that version has no tag yet. This replaces gitea-release.yaml, which released when a branch named after the version was pushed. Godot setup moves into a local .gitea/actions/setup-godot action shared by the test and build jobs, and Godot is updated to 4.7.2 to match the editor the project is made with. --- .gitea/actions/setup-godot/action.yaml | 38 ++++++++ .gitea/workflows/gitea-build.yaml | 118 ++++++++++++++++--------- .gitea/workflows/gitea-release.yaml | 90 ------------------- RELEASING.md | 20 +++++ Settings.gd | 4 +- project.godot | 1 + tests/unit/test_settings.gd | 13 +++ tests/unit/test_settings.gd.uid | 1 + 8 files changed, 150 insertions(+), 135 deletions(-) create mode 100644 .gitea/actions/setup-godot/action.yaml delete mode 100644 .gitea/workflows/gitea-release.yaml create mode 100644 RELEASING.md create mode 100644 tests/unit/test_settings.gd create mode 100644 tests/unit/test_settings.gd.uid diff --git a/.gitea/actions/setup-godot/action.yaml b/.gitea/actions/setup-godot/action.yaml new file mode 100644 index 0000000..dc49d1d --- /dev/null +++ b/.gitea/actions/setup-godot/action.yaml @@ -0,0 +1,38 @@ +name: "Setup Godot" +description: "Downloads Godot for Linux, puts it on PATH as `godot` and optionally installs the export templates" + +inputs: + version: + description: "Godot version, e.g. 4.7.2" + required: true + export-templates: + description: "Also install the export templates ('true' or 'false')" + required: false + default: "false" + +runs: + using: "composite" + steps: + - name: Download Godot + shell: bash + run: | + URL="https://github.com/godotengine/godot-builds/releases/download/${{ inputs.version }}-stable" + mkdir -p "$HOME/.godot-bin" + curl --fail -L -o godot.zip "$URL/Godot_v${{ inputs.version }}-stable_linux.x86_64.zip" + unzip -q godot.zip + mv "Godot_v${{ inputs.version }}-stable_linux.x86_64" "$HOME/.godot-bin/godot" + chmod +x "$HOME/.godot-bin/godot" + rm godot.zip + echo "$HOME/.godot-bin" >> "$GITHUB_PATH" + + - name: Install Export Templates + if: inputs.export-templates == 'true' + shell: bash + run: | + URL="https://github.com/godotengine/godot-builds/releases/download/${{ inputs.version }}-stable" + TEMPLATES_DIR="$HOME/.local/share/godot/export_templates/${{ inputs.version }}.stable" + curl --fail -L -o export_templates.tpz "$URL/Godot_v${{ inputs.version }}-stable_export_templates.tpz" + unzip -q export_templates.tpz + mkdir -p "$TEMPLATES_DIR" + mv templates/* "$TEMPLATES_DIR" + rm -r templates export_templates.tpz diff --git a/.gitea/workflows/gitea-build.yaml b/.gitea/workflows/gitea-build.yaml index 5032ba6..f94ed3b 100644 --- a/.gitea/workflows/gitea-build.yaml +++ b/.gitea/workflows/gitea-build.yaml @@ -1,6 +1,17 @@ # # .gitea/workflows/gitea-build.yaml # +# Tests and exports MusicPlayer on every push and pull request to main and develop, +# and releases it from main. +# +# Releases follow the version in project.godot (application/config/version). Bump it, +# push to main, and once the tests and exports pass the builds are uploaded to the +# package registry and the tag and Gitea release are created. If that version already +# has a tag, nothing is released. See RELEASING.md. +# +# All jobs run in this one workflow, one after another: separate workflows started by +# the same push run at the same time on the single runner and can break each other's +# copy of a shared action. # name: "Build" @@ -11,25 +22,23 @@ on: branches: [main, develop] env: - GODOT_VERSION: 4.7 - PROJECT_PATH: . - EXPORT_NAME: MusicPlayer + GODOT_VERSION: 4.7.2 + PROJECT_NAME: MusicPlayer jobs: - # Runs before build in the same workflow, so the two never race for the runner test: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v4 - - name: Download Godot - run: | - curl -L -o godot.zip https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_linux.x86_64.zip - unzip godot.zip - mv Godot_v$GODOT_VERSION-stable_linux.x86_64 godot - chmod +x godot - - name: Run tests - run: GODOT=./godot ./run_tests.sh + + - name: Setup Godot + uses: ./.gitea/actions/setup-godot + with: + version: ${{ env.GODOT_VERSION }} + + - name: Run Tests + run: ./run_tests.sh build: needs: test @@ -38,41 +47,62 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 - - name: Download Godot + with: + fetch-depth: 0 + fetch-tags: true + + - name: Read Version + id: version run: | - #echo "https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_linux.x86_64.zip" - curl -L -o godot.zip https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_linux.x86_64.zip - unzip godot.zip - mv Godot_v$GODOT_VERSION-stable_linux.x86_64 godot - chmod +x godot + GAME_VERSION="$(sed -n 's/^config\/version="\(.*\)"$/\1/p' project.godot)" + if [ -z "$GAME_VERSION" ]; then + echo "No application/config/version in project.godot" + exit 1 + fi + echo "GAME_VERSION=$GAME_VERSION" >> "$GITHUB_ENV" + if [ "$GITHUB_REF" != "refs/heads/main" ]; then + echo "Not on main, building without releasing" + echo "release=false" >> "$GITHUB_OUTPUT" + elif git rev-parse -q --verify "refs/tags/$GAME_VERSION" > /dev/null; then + echo "$GAME_VERSION is already released, building without releasing" + echo "release=false" >> "$GITHUB_OUTPUT" + else + echo "Releasing $GAME_VERSION" + echo "release=true" >> "$GITHUB_OUTPUT" + fi - - name: Download Godot Export Templates + - name: Setup Godot + uses: ./.gitea/actions/setup-godot + with: + version: ${{ env.GODOT_VERSION }} + export-templates: "true" + + - name: Export run: | - #echo "https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_export_templates.tpz" - curl -L -o export_templates.zip https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_export_templates.tpz - unzip export_templates.zip + mkdir -p build + godot --headless --path . --import + godot --headless --path . --export-release "Windows Desktop" "build/${PROJECT_NAME}_${GAME_VERSION}.exe" + godot --headless --path . --export-release "Linux" "build/${PROJECT_NAME}_${GAME_VERSION}.x86_64" + ls -la build - - name: Install Export Templates + - name: Upload Artifacts + if: steps.version.outputs.release == 'true' run: | - mkdir -p ~/.local/share/godot/export_templates/$GODOT_VERSION.stable - mv ./templates/* ~/.local/share/godot/export_templates/$GODOT_VERSION.stable - - - name: Create build folder - run: | - mkdir -v -p build - - - name: Windows Build - run: | - cd $PROJECT_PATH - ./godot --headless --verbose --export-release "Windows Desktop" "build/$EXPORT_NAME.exe" - - - name: Linux Build - run: | - cd $PROJECT_PATH - ./godot --headless --verbose --export-release "Linux" "build/$EXPORT_NAME.x86_64" - -# - name: MacOS Build -# run: | -# cd $PROJECT_PATH -# ./godot --headless --verbose --export-release "macOS" "build/$EXPORT_NAME.zip" + for FILE in build/${PROJECT_NAME}_${GAME_VERSION}*; do + NAME="$(basename "$FILE")" + echo "Uploading $NAME" + curl --fail --user ${{ github.repository_owner }}:${{ secrets.TOKEN }} \ + --upload-file "$FILE" \ + https://gitea.sanplex.xyz/api/packages/sansan/generic/$PROJECT_NAME/$GAME_VERSION/$NAME + done + - name: Create Release + if: steps.version.outputs.release == 'true' + uses: akkuman/gitea-release-action@v1 + env: + NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18 + with: + tag_name: ${{ env.GAME_VERSION }} + target_commitish: ${{ github.sha }} + files: |- + build/${{ env.PROJECT_NAME }}_* diff --git a/.gitea/workflows/gitea-release.yaml b/.gitea/workflows/gitea-release.yaml deleted file mode 100644 index 084ea63..0000000 --- a/.gitea/workflows/gitea-release.yaml +++ /dev/null @@ -1,90 +0,0 @@ -# -# .gitea/workflows/gitea-release.yaml -# -# - -name: "Publish" -on: - push: - branches: - - '*.*' - -env: - GODOT_VERSION: 4.7 - PROJECT_PATH: . - PROJECT_NAME: MusicPlayer - GAME_VERSION: ${{gitea.ref_name}} - EXPORT_NAME: MusicPlayer_${{gitea.ref_name}} - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - name: Download Godot - run: | - #echo "https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_linux.x86_64.zip" - curl -L -o godot.zip https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_linux.x86_64.zip - unzip godot.zip - mv Godot_v$GODOT_VERSION-stable_linux.x86_64 godot - chmod +x godot - - - name: Download Godot Export Templates - run: | - #echo "https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_export_templates.tpz" - curl -L -o export_templates.zip https://github.com/godotengine/godot-builds/releases/download/$GODOT_VERSION-stable/Godot_v$GODOT_VERSION-stable_export_templates.tpz - unzip export_templates.zip - - - name: Install Export Templates - run: | - mkdir -p ~/.local/share/godot/export_templates/$GODOT_VERSION.stable - mv ./templates/* ~/.local/share/godot/export_templates/$GODOT_VERSION.stable - - - name: Create build folder - run: | - mkdir -v -p build - - - name: Windows Build - run: | - cd $PROJECT_PATH - ./godot --headless --verbose --export-release "Windows Desktop" "build/$EXPORT_NAME.exe" - - - name: Linux Build - run: | - cd $PROJECT_PATH - ./godot --headless --verbose --export-release "Linux" "build/$EXPORT_NAME.x86_64" - -# - name: MacOS Build -# run: | -# cd $PROJECT_PATH -# ./godot --headless --verbose --export-release "macOS" "build/$EXPORT_NAME.zip" - - - name: Upload Artifact Windows - run: | - #ls -la build - curl --user ${{ github.repository_owner }}:${{ secrets.TOKEN }} \ - --upload-file "build/$EXPORT_NAME.exe" \ - https://gitea.sanplex.xyz/api/packages/sansan/generic/$PROJECT_NAME/$GAME_VERSION/$EXPORT_NAME.exe - - - name: Upload Artifact Linux - run: | - ls -la build - curl --user ${{ github.repository_owner }}:${{ secrets.TOKEN }} \ - --upload-file "build/$EXPORT_NAME.x86_64" \ - https://gitea.sanplex.xyz/api/packages/sansan/generic/$PROJECT_NAME/$GAME_VERSION/$EXPORT_NAME.x86_64 - -# - name: Upload Artifact MacOS -# run: | -# ls -la build -# curl --user ${{ github.repository_owner }}:${{ secrets.TOKEN }} \ -# --upload-file "build/$EXPORT_NAME.zip" \ -# https://gitea.sanplex.xyz/api/packages/sansan/generic/$PROJECT_NAME/$GAME_VERSION/$EXPORT_NAME.zip - - - name: Create release - uses: akkuman/gitea-release-action@v1 - env: - NODE_OPTIONS: '--experimental-fetch' # if nodejs < 18 - with: - files: |- - build/** diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..d043822 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,20 @@ +# Releasing + +Releases are made from the version in `project.godot` +(**Project > Project Settings > Application > Config > Version**). The game shows the +same version in the About window. + +1. Bump the version, e.g. from `1.9.0` to `1.10.0`, and add a `WHATS_NEW` entry in + `AboutWindow.gd`. +2. Merge to `main` and push. + +The `Build` workflow (`.gitea/workflows/gitea-build.yaml`) then: + +1. runs the tests, +2. exports the Windows and Linux builds, +3. if no tag exists for the version yet: uploads the builds to the package registry + under `MusicPlayer//`, and creates the `` tag and Gitea release + with the builds attached. + +Pushes that don't change the version, and pushes to `develop`, only test and export. +Don't create tags or `1.x.y` branches by hand; the workflow makes the tag. diff --git a/Settings.gd b/Settings.gd index 3a98896..ebbc4db 100644 --- a/Settings.gd +++ b/Settings.gd @@ -28,7 +28,9 @@ var edit_players: bool = false var currently_syncing: bool = false var character_select_open: bool = false -var version: String = "1.9.0" +## The game version, set in Project Settings > Application > Config > Version. +## Releases are made from it, see RELEASING.md. +var version: String = ProjectSettings.get_setting("application/config/version", "") func delete_children(node: Node) -> void: for n: Node in node.get_children(): diff --git a/project.godot b/project.godot index dea3cc7..32e1acc 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true [application] config/name="MusicPlayer" +config/version="1.9.0" run/main_scene="res://MainWindow.tscn" config/features=PackedStringArray("4.7", "Forward Plus") config/icon="res://icon.svg" diff --git a/tests/unit/test_settings.gd b/tests/unit/test_settings.gd new file mode 100644 index 0000000..4e94c2c --- /dev/null +++ b/tests/unit/test_settings.gd @@ -0,0 +1,13 @@ +extends GdUnitTestSuite + + +func test_version_comes_from_project_settings() -> void: + assert_str(Settings.version).is_equal( + ProjectSettings.get_setting("application/config/version")) + + +func test_version_is_major_minor_patch() -> void: + # The release job tags and names builds with this version + var pattern: RegEx = RegEx.create_from_string("^\\d+\\.\\d+\\.\\d+$") + + assert_object(pattern.search(Settings.version)).is_not_null() diff --git a/tests/unit/test_settings.gd.uid b/tests/unit/test_settings.gd.uid new file mode 100644 index 0000000..f374636 --- /dev/null +++ b/tests/unit/test_settings.gd.uid @@ -0,0 +1 @@ +uid://bf4hbba7kfoab