name: Build MCC and Documents on: push: branches: - master workflow_dispatch: env: PROJECT: "MinecraftClient" target-version: "net10.0" dotnet-version: "10.0.x" compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded -p:PublishSingleFile=true" jobs: determine-build: runs-on: ubuntu-slim outputs: skip: ${{ steps.check-skip.outputs.skip }} steps: - name: Check skip CI id: check-skip run: | LOWER=$(echo "$COMMIT_MSG" | tr '[:upper:]' '[:lower:]') if echo "$LOWER" | grep -qE 'skip.?ci|ci.?skip'; then echo "skip=true" >> $GITHUB_OUTPUT else echo "skip=false" >> $GITHUB_OUTPUT fi env: COMMIT_MSG: ${{ github.event.head_commit.message }} fetch-translations: strategy: fail-fast: true runs-on: ubuntu-latest needs: determine-build if: ${{ needs.determine-build.outputs.skip != 'true' }} timeout-minutes: 15 steps: - name: Check cache uses: actions/cache/restore@v3 id: cache-check with: path: ${{ github.workspace }}/* key: "translation-${{ github.sha }}" lookup-only: true restore-keys: "translation-" - name: Checkout if: steps.cache-check.outputs.cache-hit != 'true' uses: actions/checkout@v3 with: fetch-depth: 0 submodules: 'true' - name: Check Crowdin secrets id: crowdin-check run: | if [ -z "$CROWDIN_PROJECT_ID" ] || [ -z "$CROWDIN_PERSONAL_TOKEN" ]; then echo "available=false" >> $GITHUB_OUTPUT else echo "available=true" >> $GITHUB_OUTPUT fi env: CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_TOKEN }} - name: Download translations from crowdin uses: crowdin/github-action@v2.4.0 if: steps.cache-check.outputs.cache-hit != 'true' && steps.crowdin-check.outputs.available == 'true' with: upload_sources: ${{ github.repository == 'MCCTeam/Minecraft-Console-Client' }} upload_translations: false download_translations: true localization_branch_name: l10n_master create_pull_request: false push_translations: false base_path: ${{ github.workspace }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_TOKEN }} - name: Save cache uses: actions/cache/save@v3 if: steps.cache-check.outputs.cache-hit != 'true' with: path: ${{ github.workspace }}/* key: "translation-${{ github.sha }}" create-tag: runs-on: ubuntu-slim timeout-minutes: 5 # Wait 5 minutes in case of network issues/etc needs: determine-build if: ${{ needs.determine-build.outputs.skip != 'true' }} steps: - id: make-tag run: | TAG="$(date -u +'%Y%m%d')-${{ github.run_number }}" echo "tag=$TAG" >> $GITHUB_OUTPUT echo "TAG=$TAG" >> $GITHUB_ENV - name: Create Release Tag uses: actions/github-script@v7 with: script: | const tag = process.env.TAG; try { await github.rest.git.createRef({ owner: context.repo.owner, repo: context.repo.repo, ref: `refs/tags/${tag}`, sha: context.sha }); } catch(error) { if (error.message.includes('already exists')) { console.log(`Tag ${tag} already exists`); } else { throw error; } } outputs: build-tag: ${{ steps.make-tag.outputs.tag }} build: runs-on: ubuntu-latest # Check if we're not skipping build, tag is created, and translations successfully fetched (or skipped) if: ${{ needs.determine-build.outputs.skip != 'true' && needs.create-tag.result == 'success' && (needs.fetch-translations.result == 'success' || needs.fetch-translations.result == 'skipped') }} needs: [determine-build, fetch-translations, create-tag] timeout-minutes: 15 strategy: matrix: target: [win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64] steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 submodules: 'true' - name: Get Current Date run: | echo date_dashed=$(date -u +'%Y-%m-%d') >> $GITHUB_ENV - name: Restore Translations (if available) uses: actions/cache/restore@v3 with: path: ${{ github.workspace }}/* key: "translation-${{ github.sha }}" restore-keys: "translation-" - name: Setup .NET SDK uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.dotnet-version }} - name: Setup Environment Variables run: | PROJECT_PATH=${{ github.workspace }}/${{ env.PROJECT }} FILE_EXT=${{ (startsWith(matrix.target, 'win') && '.exe') || '' }} TARGET_OUT_PATH=$PROJECT_PATH/bin/Release/${{ env.target-version }}/${{ matrix.target }}/publish/ echo "project-path=$PROJECT_PATH" >> $GITHUB_ENV echo "file-ext=$FILE_EXT" >> $GITHUB_ENV echo "target-out-path=$TARGET_OUT_PATH" >> $GITHUB_ENV echo "assembly-info=$PROJECT_PATH/Properties/AssemblyInfo.cs" >> $GITHUB_ENV echo "build-version-info=${{ needs.create-tag.outputs.build-tag }}" >> $GITHUB_ENV echo "commit=$(echo ${{ github.sha }} | cut -c 1-7)" >> $GITHUB_ENV - name: Setup Binaries Path run: | echo built-executable-path=${{ env.target-out-path }}${{ env.PROJECT }}${{ env.file-ext }} >> $GITHUB_ENV - name: Set Version Info run: | echo '' >> ${{ env.assembly-info }} echo "[assembly: AssemblyConfiguration(\"GitHub build ${{ github.run_number }}, built on ${{ env.date_dashed }} from commit ${{ env.commit }}\")]" >> ${{ env.assembly-info }} - name: Inject Sentry DSN (if applicable) if: ${{ github.repository == 'MCCTeam/Minecraft-Console-Client' }} run: | grep -q 'SentryDSN = "";' ${{ env.project-path }}/Program.cs || { echo "SentryDSN pattern not found in Program.cs"; exit 1; } sed -i -e 's|SentryDSN = "";|SentryDSN = "${{ secrets.SENTRY_DSN }}";|g' ${{ env.project-path }}/Program.cs - name: Build Target run: dotnet publish ${{ env.project-path }}/${{ env.PROJECT }}.csproj -f ${{ env.target-version }} -r ${{ matrix.target }} ${{ env.compile-flags }} env: DOTNET_NOLOGO: true - name: Rename Binary run: | mv ${{ env.built-executable-path }} ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }}${{ env.file-ext }} - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }} path: ${{ env.PROJECT }}-${{ env.build-version-info }}-${{ matrix.target }}${{ env.file-ext }} if-no-files-found: error create-release: runs-on: ubuntu-slim needs: [create-tag, build] if: ${{ needs.build.result == 'success' && needs.create-tag.result == 'success' }} steps: - name: Download All Artifacts uses: actions/download-artifact@v4 with: path: artifacts/ merge-multiple: true - name: Truncate commit message for release name id: release-name run: | SUBJECT=$(echo "$COMMIT_MSG" | head -n 1) MAX=220 TRUNCATED="${SUBJECT:0:$MAX}" echo "name=${BUILD_TAG}: $TRUNCATED" >> $GITHUB_OUTPUT env: COMMIT_MSG: ${{ github.event.head_commit.message }} BUILD_TAG: ${{ needs.create-tag.outputs.build-tag }} - name: Create Release uses: ncipollo/release-action@v1.14.0 with: token: ${{ secrets.GITHUB_TOKEN }} artifacts: "artifacts/**/*" tag: ${{ needs.create-tag.outputs.build-tag }} name: ${{ steps.release-name.outputs.name }} generateReleaseNotes: true artifactErrorsFailBuild: true allowUpdates: true makeLatest: true omitBodyDuringUpdate: true omitNameDuringUpdate: true replacesArtifacts: true