From 5fb19e76ec78d2eb8a0d97801cde9c5d97729c89 Mon Sep 17 00:00:00 2001 From: topi-banana Date: Tue, 24 Dec 2024 21:24:08 +0900 Subject: [PATCH] ci/ release script --- .github/workflows/matrix_prep.yml | 29 +++ .github/workflows/release.yml | 198 +++++++++++++++++++ .github/workflows/scripts/matrix.py | 46 +++++ .github/workflows/update_modrinth_readme.yml | 2 +- 4 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/matrix_prep.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/scripts/matrix.py diff --git a/.github/workflows/matrix_prep.yml b/.github/workflows/matrix_prep.yml new file mode 100644 index 0000000..d0a0cc4 --- /dev/null +++ b/.github/workflows/matrix_prep.yml @@ -0,0 +1,29 @@ +name: _step.matrix_prepare + +on: + workflow_call: + inputs: + target_subproject: + description: see release.yml, for generating matrix entries + type: string + required: false + default: '' + outputs: + matrix: + description: The generated run matrix + value: ${{ jobs.matrix_prep.outputs.matrix }} + + +jobs: + matrix_prep: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - id: setmatrix + run: python3 .github/workflows/scripts/matrix.py # ubuntu-22.04 uses Python 3.10.6 + env: + TARGET_SUBPROJECT: ${{ inputs.target_subproject }} + + outputs: + matrix: ${{ steps.setmatrix.outputs.matrix }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..02a393a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,198 @@ +name: Release + +# release: (release title) +# dispatch (all): Manual release for $target_release_tag +# dispatch (specified): Manual release for $target_release_tag (subproject: $target_subproject) +run-name: |- + ${{ github.event_name == 'workflow_dispatch' && format('Manual release for {0}{1}', inputs.target_release_tag, inputs.target_subproject && format(' (subproject: {0})', inputs.target_subproject) || '') || '' }} + +on: + release: + types: + - published + workflow_dispatch: + inputs: + target_subproject: + description: |- + The subproject name(s) of the specified Minecraft version to be released, seperated with ",". + By default all subprojects will be released + type: string + required: false + default: '' + target_release_tag: + description: The tag of the release you want to append the artifact to + type: string + required: true + + +jobs: + show_action_parameters: + runs-on: ubuntu-latest + steps: + - name: Show action parameters + run: | + cat < $GITHUB_STEP_SUMMARY + ## Action Parameters + - target_subproject: \`${{ github.event.inputs.target_subproject }}\` + - target_release_tag: \`${{ github.event.inputs.target_release_tag }}\` + EOF + + matrix_prep: + uses: ./.github/workflows/matrix_prep.yml + with: + target_subproject: ${{ github.event.inputs.target_subproject }} + + # ensure the input release tag is valid + validate_release: + runs-on: ubuntu-latest + steps: + - name: Get github release information + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: cardinalby/git-get-release-action@1.2.5 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + tag: ${{ github.event.inputs.target_release_tag }} + + build: + uses: ./.github/workflows/build.yml + secrets: inherit + needs: + - validate_release + with: + target_subproject: ${{ github.event.inputs.target_subproject }} + release: true + + release: + needs: + - matrix_prep + - build + runs-on: ubuntu-latest + + # allow the mod publish step to add asserts to release + # https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token + permissions: + contents: write + + strategy: + matrix: ${{ fromJson(needs.matrix_prep.outputs.matrix) }} + + steps: + - uses: actions/checkout@v4 + + - name: Display context + run: | + echo ref_name = ${{ github.ref_name }} + echo target_subproject = ${{ github.event.inputs.target_subproject }} + echo target_release_tag = ${{ github.event.inputs.target_release_tag }} + + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + path: build-artifacts + + - name: Get github release information + if: ${{ github.event_name == 'workflow_dispatch' }} + id: get_release + uses: cardinalby/git-get-release-action@1.2.5 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + tag: ${{ github.event.inputs.target_release_tag }} + + - name: Generate publish related information + id: release_info + run: | + if [ $GITHUB_EVENT_NAME == 'release' ] + then + # Leave an empty value here, so Kir-Antipov/mc-publish will infer the tag from the action context + echo "tag_name=" >> $GITHUB_OUTPUT + elif [ $GITHUB_EVENT_NAME == 'workflow_dispatch' ] + then + echo "tag_name=${{ github.event.inputs.target_release_tag }}" >> $GITHUB_OUTPUT + else + echo Unknown github event name $GITHUB_EVENT_NAME + exit 1 + fi + + - name: Read common properties + id: properties_g + uses: christian-draeger/read-properties@1.1.1 + with: + path: gradle.properties + properties: 'mod_name mod_version' + + - name: Read version-specific properties + id: properties_v + uses: christian-draeger/read-properties@1.1.1 + with: + path: ${{ format('versions/{0}/gradle.properties', matrix.subproject) }} + properties: 'minecraft_version game_versions platform dependencies' + + - name: Fix game version + id: game_versions + run: | + # Fixed \n in game_versions isn't parsed by christian-draeger/read-properties as a line separator + echo 'value<> $GITHUB_OUTPUT + echo -e "${{ steps.properties_v.outputs.game_versions }}" >> $GITHUB_OUTPUT + echo 'EOF' >> $GITHUB_OUTPUT + + - name: Prepare file information + id: file_info + run: | + shopt -s extglob + FILE_PATHS=$(ls ${{ format('build-artifacts/{0}/build/libs/!(*-@(dev|sources|shadow)).jar', matrix.subproject) }}) + if (( ${#FILE_PATHS[@]} != 1 )); then + echo "Error: Found ${#FILE_PATHS[@]} files, expected exactly 1" + exit 1 + else + FILE_PATH=${FILE_PATHS[0]} + fi + + FILE_NAME=$(basename $FILE_PATH) + FILE_HASH=$(sha256sum $FILE_PATH | awk '{ print $1 }') + echo "path=$FILE_PATH" >> $GITHUB_OUTPUT + echo "name=$FILE_NAME" >> $GITHUB_OUTPUT + echo "hash=$FILE_HASH" >> $GITHUB_OUTPUT + cat $GITHUB_OUTPUT + + - name: Prepare changelog + uses: actions/github-script@v7 + id: changelog + with: + script: return process.env.CHANGELOG + result-encoding: string + env: + CHANGELOG: |- + ${{ format('{0}{1}', github.event.release.body, steps.get_release.outputs.body) }} + + ------- + + Build Information + + - File name: `${{ steps.file_info.outputs.name }}` + - SHA-256: `${{ steps.file_info.outputs.hash }}` + - Built from: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + - name: Publish Minecraft Mods + uses: Kir-Antipov/mc-publish@v3.3 + with: + version-type: release + # https://modrinth.com/settings/pats + modrinth-id: VozTPxB4 + modrinth-token: ${{ secrets.MODRINTH_API_TOKEN }} + + github-tag: ${{ steps.release_info.outputs.tag_name }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + files: ${{ steps.file_info.outputs.path }} + + name: ${{ format('{0} v{1} for mc{2}', steps.properties_g.outputs.mod_name, steps.properties_g.outputs.mod_version, steps.properties_v.outputs.minecraft_version) }} + version: ${{ format('v{1}-mc{0}', steps.properties_v.outputs.minecraft_version, steps.properties_g.outputs.mod_version) }} + + modrinth-loaders: ${{ steps.properties_v.outputs.platform }} + game-version: ${{ steps.game_versions.outputs.value }} + + github-changelog: ${{ format('{0}{1}', github.event.release.body, steps.get_release.outputs.body) }} + modrinth-changelog: ${{ steps.changelog.outputs.result }} diff --git a/.github/workflows/scripts/matrix.py b/.github/workflows/scripts/matrix.py new file mode 100644 index 0000000..a20e581 --- /dev/null +++ b/.github/workflows/scripts/matrix.py @@ -0,0 +1,46 @@ +""" +A script to scan through the versions directory and collect all folder names as the subproject list, +then output a json as the github action include matrix +""" +__author__ = 'Fallen_Breath' + +import json +import os +import sys + + +def main(): + target_subproject_env = os.environ.get('TARGET_SUBPROJECT', '') + target_subprojects = list(filter(None, target_subproject_env.split(',') if target_subproject_env != '' else [])) + print('target_subprojects: {}'.format(target_subprojects)) + + with open('settings.json') as f: + settings: dict = json.load(f) + + if len(target_subprojects) == 0: + subprojects = settings['versions'] + else: + subprojects = [] + for subproject in settings['versions']: + if subproject in target_subprojects: + subprojects.append(subproject) + target_subprojects.remove(subproject) + if len(target_subprojects) > 0: + print('Unexpected subprojects: {}'.format(target_subprojects), file=sys.stderr) + sys.exit(1) + + matrix_entries = [] + for subproject in subprojects: + matrix_entries.append({ + 'subproject': subproject, + }) + matrix = {'include': matrix_entries} + with open(os.environ['GITHUB_OUTPUT'], 'w') as f: + f.write('matrix={}\n'.format(json.dumps(matrix))) + + print('matrix:') + print(json.dumps(matrix, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/.github/workflows/update_modrinth_readme.yml b/.github/workflows/update_modrinth_readme.yml index d0cf65d..1f33c5b 100644 --- a/.github/workflows/update_modrinth_readme.yml +++ b/.github/workflows/update_modrinth_readme.yml @@ -21,4 +21,4 @@ jobs: - name: Run Python Script run: python .github/workflows/scripts/update_modrinth_readme.py VozTPxB4 README.md env: - SECRET: ${{ secrets.MODRINTH_API_TOKEN }} \ No newline at end of file + SECRET: ${{ secrets.MODRINTH_API_TOKEN }}