diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index dc49cc9e..ff6d7fd0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -5,255 +5,153 @@ on: - 'dev/**' - 'exp/**' paths: - - "**.gradle" - - "gradle.properties" - - "src/**" - - "versions/**" - - ".github/**" + - '*.gradle' + - 'gradle.properties' + - 'src/**' + - 'versions/**' + - '.github/**' release: types: - published pull_request: - + 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: - build: - if: ${{ github.event_name == 'push' && !startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build skip]') == false }} - strategy: - matrix: - java: [ 17 ] - os: [ ubuntu-latest ] - runs-on: ${{ matrix.os }} + show_action_parameters: + runs-on: ubuntu-latest + steps: + - name: Show action parameters + run: | + cat < $GITHUB_STEP_SUMMARY + ## Action Parameters + - target_subproject: \`${{ inputs.target_subproject }}\` + - target_release_tag: \`${{ inputs.target_release_tag }}\` + EOF + generate_matrix: + uses: ./.github/workflows/generate_matrix.yml + with: + target_subproject: ${{ inputs.target_subproject }} + # Ensure the input target subproject is valid. + validate_target_subproject: + runs-on: ubuntu-latest steps: - name: Checkout the sources uses: actions/checkout@v4 with: fetch-depth: 0 - - - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v4 - with: - distribution: 'adopt' - java-version: ${{ matrix.java }} - - - name: Cache Gradle packages - uses: actions/cache@v4 - with: - path: | - ~/.gradle/caches - ./.gradle/loom-caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} - - - name: Get short commit sha - id: get_short_sha - run: | - short_sha=$(echo ${GITHUB_SHA} | cut -c1-7) - echo "short_sha=$short_sha" >> $GITHUB_OUTPUT - - - name: Get commit count - id: get_commit_count - run: | - commit_count=$(git log | grep -e '^commit [a-zA-Z0-9]*' | wc -l) - echo "commit_count=$commit_count" >> $GITHUB_OUTPUT - - - name: Read Properties mod info - id: mod_info - uses: christian-draeger/read-properties@1.1.1 - with: - path: gradle.properties - properties: 'mod_name mod_version' - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Preprocess sources + - name: Validate target subproject + if: ${{ github.event_name == 'workflow_dispatch' }} + # ubuntu-22.04 uses Python 3.10.6 + run: python3 .github/workflows/scripts/validate_subproject.py env: - BUILD_TYPE: "BETA" - run: ./gradlew preprocessResources --stacktrace - - - name: Publish Maven with Gradle + TARGET_SUBPROJECT: ${{ 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.4 env: - BUILD_TYPE: "BETA" - MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} - MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} - SIGNING_PGP_KEY: ${{ secrets.SIGNING_PGP_KEY }} - run: ./gradlew build publish -x test --stacktrace - - - name: Upload assets to GitHub Action - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.mod_info.outputs.mod_name }} ${{ steps.mod_info.outputs.mod_version }}.${{ steps.get_commit_count.outputs.commit_count }}+${{ steps.get_short_sha.outputs.short_sha }} - path: | - LICENSE - fabricWrapper/build/libs/*.jar - fabricWrapper/build/tmp/submods/META-INF/jars/*.jar - - - name: Create Github release - if: contains(github.event.head_commit.message, '[publish skip]') == false && contains(github.event.ref, 'refs/heads/exp') == false - uses: softprops/action-gh-release@v1 + GITHUB_TOKEN: ${{ github.token }} with: - prerelease: true - files: | - LICENSE - fabricWrapper/build/libs/*.jar - fabricWrapper/build/tmp/submods/META-INF/jars/*.jar - name: "[CI#${{ github.run_number }}]${{ steps.mod_info.outputs.mod_name }} ${{ steps.mod_info.outputs.mod_version }}.${{ steps.get_commit_count.outputs.commit_count }}+${{ steps.get_short_sha.outputs.short_sha }}" - tag_name: "${{ github.ref_name }}.${{ steps.get_commit_count.outputs.commit_count }}" - target_commitish: ${{ github.event.ref }} - generate_release_notes: true - - publish: - if: ${{ github.event_name == 'release' }} - strategy: - matrix: - java: [ 17 ] - os: [ ubuntu-latest ] - runs-on: ${{ matrix.os }} - + tag: ${{ inputs.target_release_tag }} + prepare_build_info: + if: ${{ !startsWith(github.event.ref, 'refs/tags/') }} + runs-on: ubuntu-latest + outputs: + build_publish: ${{ steps.build_info.outputs.build_publish }} + build_target_subprojects: ${{ steps.subprojects.outputs.subprojects }} + build_type: ${{ steps.build_info.outputs.version_type }} + publish_channel: ${{ steps.build_info.outputs.publish_channel }} + publish_target_release_tag: ${{ steps.build_info.outputs.publish_target_release_tag }} steps: - name: Checkout the sources uses: actions/checkout@v4 with: fetch-depth: 0 - - - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v4 - with: - distribution: 'adopt' - java-version: ${{ matrix.java }} - - - name: Cache Gradle packages - uses: actions/cache@v4 - with: - path: | - ~/.gradle/caches - ./.gradle/loom-caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle', 'gradle.properties', '**/*.accesswidener') }} - restore-keys: ${{ runner.os }}-gradle- - - - name: Get short commit sha - id: get_short_sha - run: | - short_sha=$(echo ${GITHUB_SHA} | cut -c1-7) - echo "short_sha=$short_sha" >> $GITHUB_OUTPUT - - - name: Get commit count - id: get_commit_count + - name: Determining build info + id: build_info run: | - commit_count=$(git log | grep -e '^commit [a-zA-Z0-9]*' | wc -l) - echo "commit_count=$commit_count" >> $GITHUB_OUTPUT - - - name: Read Properties mod info - id: mod_info - uses: christian-draeger/read-properties@1.1.1 - with: - path: gradle.properties - properties: 'mod_name mod_version' - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Preprocess sources - env: - BUILD_TYPE: "RELEASE" - run: ./gradlew preprocessResources --stacktrace - - - name: Publish Maven with Gradle + if [ ${{ github.event_name }} == 'push' ] + then + # build_publish=true + # build_version_type=BETA + # publish_channel=dev + elif [ ${{ github.event_name }} == 'release' ] + then + build_publish=true + build_version_type=RELEASE + publish_channel=stable + publish_target_release_tag=${{ github.event.ref }} + elif [ ${{ github.event_name }} == 'pull_request' ] + then + build_publish=false + build_version_type=PULL_REQUEST + elif [ ${{ github.event_name }} == 'workflow_dispatch' ] + then + build_publish=true + build_version_type=RELEASE + publish_channel=stable + publish_target_release_tag=${{ inputs.target_release_tag }} + else + echo Unknown github event name $GITHUB_EVENT_NAME + exit 1 + fi + + echo 'build_publish=$build_publish' >> $GITHUB_OUTPUT + echo 'build_version_type=$build_version_type' >> $GITHUB_OUTPUT + echo 'publish_channel=$publish_channel' >> $GITHUB_OUTPUT + echo 'publish_target_release_tag=$publish_target_release_tag' >> $GITHUB_OUTPUT + + cat < $GITHUB_STEP_SUMMARY + ## Determining build info + - build_publish: \`${{ build_publish }}\` + - build_version_type: \`${{ build_version_type }}\` + - publish_channel: \`${{ publish_channel }}\` + - publish_target_release_tag: \`${{ publish_target_release_tag }}\` + EOF + - name: Determining subprojects + id: subprojects + run: python3 .github/workflows/scripts/determining_subproject.py env: - BUILD_TYPE: "RELEASE" - MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} - MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} - SIGNING_PGP_KEY: ${{ secrets.SIGNING_PGP_KEY }} - run: ./gradlew build publish -x test --stacktrace - - - name: Upload assets to GitHub Action - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.mod_info.outputs.mod_name }} ${{ steps.mod_info.outputs.mod_version }}.${{ steps.get_commit_count.outputs.commit_count }}+${{ steps.get_short_sha.outputs.short_sha }} - path: | - LICENSE - fabricWrapper/build/libs/*.jar - fabricWrapper/build/tmp/submods/META-INF/jars/*.jar - - - name: Upload assets Github Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ github.event.ref }} - files: | - LICENSE - fabricWrapper/build/libs/*.jar - fabricWrapper/build/tmp/submods/META-INF/jars/*.jar - - - name: Publish release to CurseForge & Modrinth - uses: Kir-Antipov/mc-publish@v3.3 - with: - modrinth-id: mv1zH6ln - modrinth-token: ${{ secrets.MODRINTH_API_TOKEN }} - curseforge-id: 576459 - curseforge-token: ${{ secrets.CF_API_TOKEN }} - files: | - fabricWrapper/build/libs/!(*-@(dev|sources|javadoc)).jar - fabricWrapper/build/tmp/submods/META-INF/jars/!(*-@(dev|sources)).jar - name: 'MagicLib ${{ steps.mod_info.outputs.mod_version }}.${{ steps.get_commit_count.outputs.commit_count }}' - version: ${{ steps.mod_info.outputs.mod_version }}.${{ steps.get_commit_count.outputs.commit_count }} - version-type: 'release' - changelog: ${{ github.event.release.body }} - loaders: | - fabric - quilt - game-versions: | - 1.14.4 - 1.15.2 - 1.16.5 - 1.17.1 - 1.18.2 - 1.19.2 - 1.19.3 - 1.19.4 - 1.20.1 - 1.20.2 - game-version-filter: any - java: | - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - dependencies: | - carpet(optional) - malilib(optional) - retry-attempts: 2 - retry-delay: 10000 - - pull_request: - if: ${{ github.event_name == 'pull_request' }} + TARGET_SUBPROJECT: ${{ github.event.inputs.target_subproject }} + build: + if: ${{ contains(github.event.head_commit.message, '[build skip]') == false }} + needs: + - prepare_build_info + - validate_target_subproject + - validate_release + uses: ./.github/workflows/build.yml + secrets: inherit + with: + build_publish: ${{ needs.prepare_build_info.outputs.build_publish }} + build_version_type: ${{ needs.prepare_build_info.outputs.build_version_type }} + target_subproject: ${{ needs.prepare_build_info.outputs.build_target_subprojects }} + publish: + if: ${{ needs.build.outputs.build_publish }} strategy: - matrix: - java: [ 17 ] - os: [ ubuntu-20.04 ] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout the sources - uses: actions/checkout@v4 - - - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v4 - with: - distribution: 'adopt' - java-version: ${{ matrix.java }} - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Preprocess sources - run: ./gradlew preprocessResources --stacktrace - - - name: Build with Gradle - run: ./gradlew build --stacktrace + matrix: ${{ fromJson(needs.generate_matrix.outputs.matrix) }} + needs: + - build + - generate_matrix + - prepare_build_info + uses: ./.github/workflows/publish.yml + secrets: inherit + with: + build_publish: ${{ needs.prepare_build_info.outputs.build_publish }} + build_version_type: ${{ needs.prepare_build_info.outputs.build_version_type }} + publish_channel: ${{ needs.prepare_build_info.outputs.publish_channel }} + publish_target_release_tag: ${{ needs.prepare_build_info.outputs.publish_target_release_tag }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..1aed2a16 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,90 @@ +name: step.build +on: + workflow_call: + inputs: + build_publish: + type: boolean + required: true + build_version_type: + type: string + required: true + target_subproject: + description: see CI.yml, leave it empty to build all + type: string + required: false + default: '' +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout the sources + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 21 + - name: Cache gradle files + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + ./.gradle/loom-cache + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle.properties', '**/*.accesswidener', 'settings.json') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Build with gradle + run: | + chmod +x gradlew + if [ -z "${{ inputs.target_subproject }}" ]; then + echo "Building all subprojects" + ./gradlew build + else + args=$(echo "${{ inputs.target_subproject }}" | tr ',' '\n' | sed 's/$/:build/' | paste -sd ' ') + echo "Building with arguments=$args" + ./gradlew $args + fi + env: + BUILD_TYPE: ${{ inputs.build_type }} + - name: Publish Maven with Gradle + if: ${{ inputs.build_publish }} + run: | + if [ -z "${{ inputs.target_subproject }}" ]; then + echo "Publishing all subprojects" + ./gradlew publish + else + args=$(echo "${{ inputs.target_subproject }}" | tr ',' '\n' | sed 's/$/:publish/' | paste -sd ' ') + echo "Publishing with arguments=$args" + ./gradlew $args + fi + env: + BUILD_TYPE: ${{ inputs.build_type }} + MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + SIGNING_PGP_KEY: ${{ secrets.SIGNING_PGP_KEY }} + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: | + */**/build/libs/ + summary: + runs-on: ubuntu-22.04 + needs: + - build + steps: + - name: Checkout the sources + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + path: build-artifacts + - name: Make build summary + # ubuntu-22.04 uses Python 3.10.6 + run: python3 .github/workflows/scripts/summary.py diff --git a/.github/workflows/generate_matrix.yml b/.github/workflows/generate_matrix.yml new file mode 100644 index 00000000..0993a557 --- /dev/null +++ b/.github/workflows/generate_matrix.yml @@ -0,0 +1,29 @@ +name: step.generate_matrix +on: + workflow_call: + inputs: + target_subproject: + description: see CI.yml, for generating matrix entries + type: string + required: false + default: '' + outputs: + matrix: + description: The generated run matrix + value: ${{ jobs.generate_matrix.outputs.matrix }} +jobs: + generate_matrix: + runs-on: ubuntu-22.04 + steps: + - name: Checkout the sources + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Generate matrix + id: generate_matrix + # ubuntu-22.04 uses Python 3.10.6 + run: python3 .github/workflows/scripts/matrix.py + env: + TARGET_SUBPROJECT: ${{ inputs.target_subproject }} + outputs: + matrix: ${{ steps.generate_matrix.outputs.matrix }} \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..1b05d7dd --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,103 @@ +name: step.publish +on: + workflow_call: + inputs: + publish_channel: + type: string + required: false + publish_target_release_tag: + description: |- + The tag of the release you want to append the artifact to. + type: string + required: false + default: '' +jobs: + publish: + 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 + steps: + - name: Checkout the sources + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + path: build-artifacts + - name: Get git info + id: get_git_info + run: | + short_sha=$(echo ${GITHUB_SHA} | cut -c1-7) + commit_count=$(git log | grep -e '^commit [a-zA-Z0-9]*' | wc -l) + echo "short_sha=$short_sha" >> $GITHUB_OUTPUT + echo "commit_count=$commit_count" >> $GITHUB_OUTPUT + - name: Read Properties mod info + id: mod_info + uses: christian-draeger/read-properties@1.1.1 + with: + path: gradle.properties + properties: 'mod.name mod.version' + - name: Publish Minecraft Mods (Dev Channel) + if: ${{ inputs.publish_channel == 'dev' }} + uses: Kir-Antipov/mc-publish@v3.3 + with: + # modrinth-id: + # modrinth-token: ${{ secrets.MODRINTH_API_TOKEN }} + # curseforge-id: + # curseforge-token: ${{ secrets.CF_API_TOKEN }} + github-tag: ${{ github.ref_name }}.${{ steps.get_git_info.outputs.commit_count }} + github-token: ${{ secrets.GITHUB_TOKEN }} + github-prerelease: true + github-generate-changelog: true + files: | + build-artifacts/magiclib-wrapper/${{ matrix.platform }}/${{ matrix.mc_ver }}/build/libs/!(*-@(dev|sources|javadoc)).jar + build-artifacts/magiclib-wrapper/${{ matrix.platform }}/${{ matrix.mc_ver }}/build/tmp/submods/META-INF/jars/!(*-@(dev|sources|javadoc)).jar + name: '[CI#${{ github.run_number }}]${{ steps.mod_info.outputs.mod-name }} ${{ steps.mod_info.outputs.mod-version }}.${{ steps.get_git_info.outputs.commit_count }}+${{ steps.get_git_info.outputs.short_sha }}' + version: ${{ steps.mod_info.outputs.mod-version }}.${{ steps.get_git_info.outputs.commit_count }}+${{ steps.get_git_info.outputs.short_sha }} + version-type: dev + changelog: | + **This version is automatically released by CI Build** + Latest commit log: + ${{ github.event.head_commit.message }} + loaders: | + ${{ matrix.platform }} + game-versions: | + ${{ matrix.mc_ver }} + game-version-filter: any + dependencies: | + carpet(optional) + malilib(optional) + retry-attempts: 2 + retry-delay: 10000 + - name: Publish Minecraft Fabric Mods (Stable Channel) + if: ${{ inputs.publish_channel == 'stable' }} + uses: Kir-Antipov/mc-publish@v3.3 + with: + # modrinth-id: + # modrinth-token: ${{ secrets.MODRINTH_API_TOKEN }} + # curseforge-id: + # curseforge-token: ${{ secrets.CF_API_TOKEN }} + github-tag: ${{ inputs.publish_target_release_tag }} + github-token: ${{ secrets.GITHUB_TOKEN }} + github-generate-changelog: true + files: | + build-artifacts/magiclib-wrapper/${{ matrix.platform }}/${{ matrix.mc_ver }}/build/libs/!(*-@(dev|sources|javadoc)).jar + build-artifacts/magiclib-wrapper/${{ matrix.platform }}/${{ matrix.mc_ver }}/build/tmp/submods/META-INF/jars/!(*-@(dev|sources|javadoc)).jar + name: '${{ steps.mod_info.outputs.mod-name }} ${{ steps.mod_info.outputs.mod-version }}.${{ steps.get_git_info.outputs.commit_count }}+${{ steps.get_git_info.outputs.short_sha }}' + version: ${{ steps.mod_info.outputs.mod-version }}.${{ steps.get_git_info.outputs.commit_count }} + version-type: release + changelog: ${{ github.event.release.body }} + loaders: | + ${{ matrix.platform }} + game-versions: | + ${{ matrix.mc_ver }} + game-version-filter: any + dependencies: | + carpet(optional) + malilib(optional) + retry-attempts: 2 + retry-delay: 10000 diff --git a/.github/workflows/scripts/common.py b/.github/workflows/scripts/common.py new file mode 100644 index 00000000..fc31b7fe --- /dev/null +++ b/.github/workflows/scripts/common.py @@ -0,0 +1,81 @@ +""" +Common functions +""" +__author__ = 'Hendrix_Shen' + +import json +from typing import Dict, List, Set + +__PLATFORM_MAPPING: dict = { + 'fabric': 'Fabric', + 'forge': 'Forge', + 'neoforge': 'NeoForge', + 'quilt': 'Quilt' +} + + +def get_mc_vers(subproject_dict: Dict[str, List[str]]) -> List[str]: + mc_vers: Set[str] = set() + + for subproject in subproject_dict: + for mc_ver in subproject_dict[subproject]: + mc_vers.add(mc_ver) + + return sorted(list(mc_vers)) + + +def get_subproject_dict() -> Dict[str, List[str]]: + with open('settings.json') as f: + settings: dict = json.load(f) + + projects: Dict[str, List[str]] = {} + + for project in settings['projects']: + for version in settings['projects'][project]['versions']: + module: Module = Module(version) + + if module.platform() not in projects: + projects[module.platform()] = [] + + projects[module.platform()].append(module.mc_ver()) + + for platform in projects: + projects[platform] = sorted(list(set(projects[platform]))) + + return projects + + +def pretty_platform(platform: str) -> str: + return __PLATFORM_MAPPING.get(platform, '* Unknown *') + + +def read_prop(file_name: str, key: str) -> str: + with open(file_name) as prop: + return next(filter( + lambda x: x.split('=', 1)[0].strip() == key, + prop.readlines() + )).split('=', 1)[1].lstrip() + + +class Module: + __mc_ver: str + __platform: str + + def __init__(self, module_name: str) -> None: + s = module_name.split('-') + + if len(s) == 2: + self.__mc_ver = s[0] + self.__platform = s[1] + else: + self.__mc_ver = 'unknown' + self.__platform = 'unknown' + + def platform(self) -> str: + return self.__platform + + def mc_ver(self) -> str: + return self.__mc_ver + + def pretty_platform(self) -> str: + return pretty_platform(self.__platform) diff --git a/.github/workflows/scripts/determining_subproject.py b/.github/workflows/scripts/determining_subproject.py new file mode 100644 index 00000000..a064029b --- /dev/null +++ b/.github/workflows/scripts/determining_subproject.py @@ -0,0 +1,31 @@ +import os +from typing import List, Dict + +import common + +WRAPPER_NAME = ':magiclib-wrapper' + + +def main(): + target_subproject_env = os.environ.get('TARGET_SUBPROJECT', '') + target_subprojects = list(filter(None, target_subproject_env.split(',') if target_subproject_env != '' else [])) + subproject_dict: Dict[str, List[str]] = common.get_subproject_dict() + gradle_subprojects: List[str] = [] + + for target_subproject in target_subprojects: + for platform in subproject_dict: + if target_subproject in subproject_dict[platform]: + gradle_subprojects.append('{}:{}:{}'.format(WRAPPER_NAME, platform, target_subproject)) + + result: str = ','.join(gradle_subprojects) + + with open(os.environ['GITHUB_STEP_SUMMARY'], 'w') as f: + f.write('### Determining subprojects\n') + f.write('subprojects={}\n'.format(result)) + + with open(os.environ['GITHUB_OUTPUT'], 'w') as f: + f.write('subprojects={}\n'.format(result)) + + +if __name__ == '__main__': + main() diff --git a/.github/workflows/scripts/matrix.py b/.github/workflows/scripts/matrix.py new file mode 100644 index 00000000..b327288c --- /dev/null +++ b/.github/workflows/scripts/matrix.py @@ -0,0 +1,48 @@ +""" +Modified from github.com/Fallen-Breath/fabric-mod-template +Originally authored by Fallen_Breath + +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__ = 'Hendrix_Shen' + +import json +import os +from typing import Dict, List + +import common + + +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)) + subproject_dict: Dict[str, List[str]] = common.get_subproject_dict() + matrix: Dict[str, List[Dict[str, str]]] = {'include': []} + + if len(target_subprojects) == 0: + for platform in subproject_dict: + for mc_ver in subproject_dict[platform]: + matrix['include'].append({ + 'platform': platform, + 'mc_ver': mc_ver + }) + else: + for platform in subproject_dict: + for mc_ver in subproject_dict[platform]: + if mc_ver in target_subprojects: + matrix['include'].append({ + 'platform': platform, + 'mc_ver': mc_ver + }) + + 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/scripts/summary.py b/.github/workflows/scripts/summary.py new file mode 100644 index 00000000..71036aca --- /dev/null +++ b/.github/workflows/scripts/summary.py @@ -0,0 +1,117 @@ +""" +Modified from github.com/Fallen-Breath/fabric-mod-template +Originally authored by Fallen_Breath + +A script to scan through all valid mod jars in build-artifacts.zip/$module/$version/build/libs, +and generate an artifact summary table for that to GitHub action step summary +""" +__author__ = 'Hendrix_Shen' + +import functools +import glob +import hashlib +import json +import os +from typing import List + +import common + + +def get_sha256_hash(file_path: str) -> str: + sha256_hash = hashlib.sha256() + + with open(file_path, 'rb') as f: + for buf in iter(functools.partial(f.read, 4096), b''): + sha256_hash.update(buf) + + return sha256_hash.hexdigest() + + +def get_file_info(file_paths: List[str], subproject: str, warnings: List[str]) -> dict: + if len(file_paths) == 0: + file_name = '*not found*' + file_size = 0 + sha256 = '*N/A*' + else: + file_name = '`{}`'.format(os.path.basename(file_paths[0])) + file_size = '{} B'.format(os.path.getsize(file_paths[0])) + sha256 = '`{}`'.format(get_sha256_hash(file_paths[0])) + if len(file_paths) > 1: + warnings.append( + 'Found too many build files in subproject {}: {}'.format(subproject, ', '.join(file_paths))) + + return { + 'file_name': file_name, + 'file_size': file_size, + 'sha256': sha256 + } + + +def main(): + with open('settings.json') as f: + settings: dict = json.load(f) + + with open(os.environ['GITHUB_STEP_SUMMARY'], 'w') as f: + f.write('## Build Artifacts Summary\n\n') + warnings = [] + fabric_mods: List[str] = [] + + for project in settings['projects']: + for version in settings['projects'][project]['versions']: + fabric_mods.append(common.Module(version).mc_ver()) + + fabric_mods = sorted(set(fabric_mods)) + f.write('### Fabric Mod\n') + f.write('| File | Size | SHA-256 |\n') + f.write('| --- | --- | --- |\n') + + for mod in fabric_mods: + file_paths = glob.glob('build-artifacts/magiclib-wrapper/fabric/{}/build/libs/*.jar'.format(mod)) + print(file_paths) + file_paths = list( + filter(lambda fp: not fp.endswith('-sources.jar') and not fp.endswith('-javadoc.jar'), file_paths)) + file_info = get_file_info(file_paths, 'magiclib-wrapper', warnings) + f.write('| {} | {} | {} |\n'.format(file_info.get('file_name'), file_info.get('file_size'), + file_info.get('sha256'))) + + f.write('### Module {}\n'.format(common.read_prop('magiclib-core/gradle.properties', 'mod.name'))) + f.write('| Platform | File | Size | SHA-256 |\n') + f.write('| --- | --- | --- | --- |\n') + + for subproject in ['fabric', 'forge', 'neoforge']: + platform = common.pretty_platform(subproject) + file_paths = glob.glob('build-artifacts/magiclib-core/{}/build/libs/*.jar'.format(subproject)) + file_paths = list(filter( + lambda fp: not fp.endswith('-sources.jar') and not fp.endswith('-slim.jar') and not fp.endswith( + '-javadoc.jar'), file_paths)) + file_info = get_file_info(file_paths, subproject, warnings) + f.write('| {} | {} | {} | {} |\n'.format(platform, file_info.get('file_name'), file_info.get('file_size'), + file_info.get('sha256'))) + + for module in settings['projects']: + f.write( + '### Module {}\n'.format(common.read_prop('{}/gradle.properties'.format(module), 'mod.name'))) + f.write('| Minecraft | Platform | File | Size | SHA-256 |\n') + f.write('| --- | --- | --- | --- | --- |\n') + + for subproject in settings['projects'][module]['versions']: + platform = common.Module(subproject).pretty_platform() + game_versions = common.read_prop('{}/versions/{}/gradle.properties'.format(module, subproject), + 'dependencies.minecraft_dependency').rstrip() + file_paths = glob.glob('build-artifacts/{}/versions/{}/build/libs/*.jar'.format(module, subproject)) + file_paths = list(filter( + lambda fp: not fp.endswith('-sources.jar') and not fp.endswith('-shadow.jar') and not fp.endswith( + '-javadoc.jar'), file_paths)) + + file_info = get_file_info(file_paths, subproject, warnings) + f.write('| {} | {} | {} | {} | {} |\n'.format(game_versions, platform, file_info.get('file_name'), + file_info.get('file_size'), file_info.get('sha256'))) + + if len(warnings) > 0: + f.write('\n### Warnings\n\n') + for warning in warnings: + f.write('- {}\n'.format(warning)) + + +if __name__ == '__main__': + main() diff --git a/.github/workflows/scripts/validate_subproject.py b/.github/workflows/scripts/validate_subproject.py new file mode 100644 index 00000000..6920a3f9 --- /dev/null +++ b/.github/workflows/scripts/validate_subproject.py @@ -0,0 +1,26 @@ +""" +A script to valid TARGET_SUBPROJECT. +""" +__author__ = 'Hendrix_Shen' + +import os +import sys +from typing import List + +import common + + +def main(): + target_subproject_env = os.environ.get('TARGET_SUBPROJECT', '') + target_subprojects = list(filter(None, target_subproject_env.split(',') if target_subproject_env != '' else [])) + subproject_dict: dict = common.get_subproject_dict() + mc_ver: List[str] = common.get_mc_vers(subproject_dict) + + for subproject in target_subprojects: + if subproject not in mc_ver: + print('Could not found subproject {} in any platform!'.format(subproject)) + sys.exit(1) + + +if __name__ == '__main__': + main()