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