From 3a619bafd38a514ae05d9204d4add14a3aa558be Mon Sep 17 00:00:00 2001 From: Hendrix-Shen Date: Tue, 9 Apr 2024 20:34:47 +0800 Subject: [PATCH] CI Test Signed-off-by: Hendrix-Shen --- .github/workflows/CI.yml | 152 +++++++++++++++------------ .github/workflows/build.yml | 68 ++++++++++++ .github/workflows/scripts/summary.py | 130 +++++++++++++++++++++++ 3 files changed, 280 insertions(+), 70 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/scripts/summary.py diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index dc49cc9e..96f574a1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -5,7 +5,7 @@ on: - 'dev/**' - 'exp/**' paths: - - "**.gradle" + - "*.gradle" - "gradle.properties" - "src/**" - "versions/**" @@ -16,94 +16,106 @@ on: pull_request: jobs: - build: + dev-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 }} + uses: ./.github/workflows/build.yml + secrets: inherit + with: + release: false + release: + if: ${{ github.event_name == 'release' }} + uses: ./.github/workflows/build.yml + secrets: inherit + with: + release: true + publish: + if: ${{ !failure() && !cancelled() }} + needs: + - dev-build + - release + 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: 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 + - name: Download build artifacts + uses: actions/download-artifact@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 + name: build-artifacts + path: build-artifacts + - name: Get git info + id: get_git_info 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 "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: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Preprocess sources - env: - BUILD_TYPE: "BETA" - run: ./gradlew preprocessResources --stacktrace - - - name: Publish Maven with Gradle - 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 + properties: 'mod.name mod.version' + - name: Publish Minecraft Mods + uses: Kir-Antipov/mc-publish@v3.3 with: - prerelease: true +# modrinth-id: mv1zH6ln +# modrinth-token: ${{ secrets.MODRINTH_API_TOKEN }} +# curseforge-id: 576459 +# curseforge-token: ${{ secrets.CF_API_TOKEN }} + github-tag: ${{ github.ref_name }}.${{ steps.get_commit_count.outputs.commit_count }} + github-token: ${{ secrets.GITHUB_TOKEN }} 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 + build-artifacts/magiclib-wrapper/fabric/release/build/libs/!(*-@(dev|sources|javadoc)).jar + build-artifacts/magiclib-wrapper/fabric/release/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: release + github-generate-changelog: true + 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 + 1.20.4 + game-version-filter: any + java: | + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + dependencies: | + carpet(optional) + malilib(optional) + retry-attempts: 2 + retry-delay: 10000 - publish: - if: ${{ github.event_name == 'release' }} + publish-legacy: + if: false strategy: matrix: java: [ 17 ] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..e0f8ac95 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,68 @@ +name: step.build +on: + workflow_call: + inputs: + release: + type: boolean + required: false + default: false +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: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with gradle + run: ./gradlew build + env: + BUILD_TYPE: ${{ inputs.release == true && 'RELEASE' || 'BETA' }} + - name: Publish Maven with Gradle + run: ./gradlew publish + env: + BUILD_TYPE: ${{ inputs.release == true && 'RELEASE' || 'BETA' }} + 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/ + magiclib-wrapper/fabric/release/build/tmp/submods/META-INF/jars/ + 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/scripts/summary.py b/.github/workflows/scripts/summary.py new file mode 100644 index 00000000..4c1e73ac --- /dev/null +++ b/.github/workflows/scripts/summary.py @@ -0,0 +1,130 @@ +""" +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 + +platform_mapping: dict = { + 'fabric': 'Fabric', + 'forge': 'Forge', + 'neoforge': 'NeoForge', + 'quilt': 'Quilt' +} +platform_mapping.setdefault('* Unknown *') + + +def read_prop(file_name: str, key: str) -> str: + with open(file_name) as prop: + return next(filter( + lambda l: l.split('=', 1)[0].strip() == key, + prop.readlines() + )).split('=', 1)[1].lstrip() + + +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 = [] + + f.write('### Fabric Wrapper:\n') + f.write('| File | Size | SHA-256 |\n') + f.write('| --- | --- | --- |\n') + file_paths = glob.glob('build-artifacts/magiclib-wrapper/fabric/release/build/libs/*.jar') + file_paths = list(filter( + lambda fp: not fp.endswith('-sources.jar') and not fp.endswith('-dev.jar') and not fp.endswith( + '-javadoc.jar'), file_paths)) + file_info = get_file_info(file_paths, 'magiclib-wrapper', warnings) + + f.write('### Module {}:\n'.format(read_prop('magiclib-core/gradle.properties', 'mod.name'))) + f.write('| Platform | File | Size | SHA-256 |\n') + f.write('| --- | --- | --- | --- |\n') + f.write('| {} | {} | {} |\n'.format(file_info.get('file_name'), file_info.get('file_size'), + file_info.get('sha256'))) + + for subproject in ['fabric', 'forge', 'neoforge']: + platform = platform_mapping.get(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('-dev.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(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']: + s = subproject.split('-') + + if len(s) == 2: + platform = platform_mapping.get(s[1]) + else: + platform = '*unknown*' + + game_versions = read_prop('{}/versions/{}/gradle.properties'.format(module, subproject), + 'dependencies.minecraft_dependency') + 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('-dev.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()