🐳 Auto-Build FiveM Docker Images #157
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 🐳 Auto-Build FiveM Docker Images | |
| on: | |
| schedule: | |
| - cron: '0 0 * * *' | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'Dockerfile' | |
| - 'config/**' | |
| - '.github/workflows/build.yml' | |
| jobs: | |
| discover: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.build-matrix.outputs.matrix }} | |
| should-build: ${{ steps.build-matrix.outputs.should-build }} | |
| steps: | |
| - name: 🔍 Fetch FiveM Artifacts from artifacts.jgscripts.com | |
| id: fetch-artifacts | |
| run: | | |
| echo "Fetching FiveM Artifacts API data from artifacts.jgscripts.com/json..." | |
| API_RESPONSE=$(curl -sL --max-time 30 https://artifacts.jgscripts.com/json 2>&1) | |
| if [ $? -ne 0 ] || [ -z "$API_RESPONSE" ]; then | |
| echo "⚠️ Cannot retrieve API, using fallback list" | |
| echo "use_fallback=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Validate JSON | |
| echo "$API_RESPONSE" | jq . > /dev/null 2>&1 | |
| if [ $? -ne 0 ]; then | |
| echo "⚠️ Invalid JSON from API, using fallback list" | |
| echo "use_fallback=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Extract recommendedArtifact | |
| RECOMMENDED=$(echo "$API_RESPONSE" | jq -r '.recommendedArtifact // empty') | |
| if [ -z "$RECOMMENDED" ]; then | |
| echo "⚠️ No recommendedArtifact found in API, using fallback list" | |
| echo "use_fallback=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Extract linuxDownloadLink | |
| LINUX_DL=$(echo "$API_RESPONSE" | jq -r '.linuxDownloadLink // empty') | |
| if [ -z "$LINUX_DL" ]; then | |
| echo "⚠️ No linuxDownloadLink found in API, using fallback list" | |
| echo "use_fallback=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Extract full version from download link (Format: XXXXX-hash) | |
| # e.g. from: https://runtime.fivem.net/.../24574-315823736cfbc085104ca0d32779311cd2f1a5a8/fx.tar.xz | |
| FULL_VERSION=$(echo "$LINUX_DL" | grep -oE '[0-9]{4,6}-[a-f0-9]{40}') | |
| if [ -z "$FULL_VERSION" ]; then | |
| echo "⚠️ Cannot extract version from download link, using fallback" | |
| echo "use_fallback=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "✅ Recommended artifact found:" | |
| echo " Version: $RECOMMENDED" | |
| echo " Full Version: $FULL_VERSION" | |
| echo " Download: $LINUX_DL" | |
| # Save for next step | |
| echo "recommended=$RECOMMENDED" >> $GITHUB_OUTPUT | |
| echo "full_version=$FULL_VERSION" >> $GITHUB_OUTPUT | |
| echo "use_fallback=false" >> $GITHUB_OUTPUT | |
| - name: 📋 Create Build Matrix | |
| id: build-matrix | |
| run: | | |
| USE_FALLBACK="${{ steps.fetch-artifacts.outputs.use_fallback }}" | |
| if [ "$USE_FALLBACK" = "true" ]; then | |
| # Fallback: Use static artifact list based on Dockerfile defaults | |
| # NOTE: Hashes are placeholders and are only used when artifacts.jgscripts.com | |
| # is unreachable. These should be replaced with actual versions from the Dockerfile. | |
| echo "⚠️ Using fallback artifact list (based on Dockerfile defaults)" | |
| # Create fallback with only one version (Dockerfile default) | |
| ARTIFACT="18443" | |
| FULL_VER="18443-746f079d418d6a05ae5fe78268bc1b4fd66ce738" | |
| MATRIX="[{\"artifact\":\"$ARTIFACT\",\"fullver\":\"$FULL_VER\",\"tag\":\"latest\"}]" | |
| COUNT=1 | |
| else | |
| # Use recommended artifact from API | |
| RECOMMENDED="${{ steps.fetch-artifacts.outputs.recommended }}" | |
| FULL_VERSION="${{ steps.fetch-artifacts.outputs.full_version }}" | |
| echo "✅ Using recommended artifact from API:" | |
| echo " Artifact: $RECOMMENDED" | |
| echo " Full Version: $FULL_VERSION" | |
| # Create matrix with recommended version | |
| # Tag as "latest" and build step also creates tag with version number | |
| MATRIX="[{\"artifact\":\"$RECOMMENDED\",\"fullver\":\"$FULL_VERSION\",\"tag\":\"latest\"}]" | |
| COUNT=1 | |
| fi | |
| echo "✅ Matrix created with $COUNT artifact(s)" | |
| echo "matrix=$MATRIX" >> $GITHUB_OUTPUT | |
| echo "should-build=true" >> $GITHUB_OUTPUT | |
| # For log | |
| echo "Artifacts to build:" | |
| echo "$MATRIX" | jq . | |
| build: | |
| needs: discover | |
| runs-on: ubuntu-latest | |
| if: needs.discover.outputs.should-build == 'true' | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| matrix: | |
| build: ${{ fromJson(needs.discover.outputs.matrix) }} | |
| max-parallel: 2 | |
| steps: | |
| - name: 📥 Checkout | |
| uses: actions/checkout@v4 | |
| - name: 🔑 Login to ghcr.io | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: 🐳 Setup Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: 🔨 Build ${{ matrix.build.artifact }} | |
| run: | | |
| ARTIFACT=${{ matrix.build.artifact }} | |
| FULL_VER=${{ matrix.build.fullver }} | |
| TAG=${{ matrix.build.tag }} | |
| IMAGE="ghcr.io/${{ github.repository_owner }}/fivem" | |
| echo "🔨 Building: $IMAGE:$TAG" | |
| echo " Artifact: $ARTIFACT" | |
| echo " Full Version: $FULL_VER" | |
| # Build with both latest and version tags | |
| docker buildx build \ | |
| --push \ | |
| -f Dockerfile \ | |
| --build-arg FIVEM_NUM=$ARTIFACT \ | |
| --build-arg FIVEM_VER=$FULL_VER \ | |
| --build-arg DATA_VER=0e7ba538339f7c1c26d0e689aa750a336576cf02 \ | |
| -t $IMAGE:$TAG \ | |
| -t $IMAGE:$ARTIFACT \ | |
| . | |
| if [ $? -eq 0 ]; then | |
| echo "✅ Built: $IMAGE:$TAG" | |
| echo "✅ Also tagged as: $IMAGE:$ARTIFACT" | |
| else | |
| exit 1 | |
| fi | |
| no-build: | |
| needs: discover | |
| runs-on: ubuntu-latest | |
| if: needs.discover.outputs.should-build != 'true' | |
| steps: | |
| - name: ⏭️ Skip | |
| run: | | |
| echo "⏭️ Build skipped - no valid artifacts found" | |
| echo " artifacts.jgscripts.com API could not be retrieved" | |
| summary: | |
| needs: [discover, build] | |
| runs-on: ubuntu-latest | |
| if: success() && needs.discover.outputs.should-build == 'true' | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: 📥 Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: 📝 Update README Badge | |
| run: | | |
| # Get the artifact version from discover job | |
| MATRIX='${{ needs.discover.outputs.matrix }}' | |
| ARTIFACT=$(echo "$MATRIX" | jq -r '.[0].artifact') | |
| if [ -z "$ARTIFACT" ] || [ "$ARTIFACT" == "null" ]; then | |
| echo "::error::Failed to extract artifact version from matrix" | |
| exit 1 | |
| fi | |
| echo "Updating README badge with FiveM version: $ARTIFACT" | |
| # Update the badge in README.md | |
| sed -i "s|https://img.shields.io/badge/fivem-[0-9]*-green.svg|https://img.shields.io/badge/fivem-$ARTIFACT-green.svg|g" README.md | |
| # Check if there were changes | |
| if git diff --quiet README.md; then | |
| echo "No changes to README.md" | |
| else | |
| echo "README.md updated with new version badge" | |
| git config --global user.name "github-actions[bot]" | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| git add README.md | |
| git commit -m "chore: update FiveM version badge to $ARTIFACT" | |
| if ! git push; then | |
| echo "::error::Failed to push README changes" | |
| exit 1 | |
| fi | |
| echo "✅ Successfully updated README with version $ARTIFACT" | |
| fi | |
| - name: ✅ Summary | |
| run: | | |
| cat >> $GITHUB_STEP_SUMMARY << 'EOF' | |
| ## ✅ Build Complete | |
| **Registry:** ghcr.io/${{ github.repository_owner }}/fivem | |
| ### Images Built: | |
| The recommended FiveM Docker image has been successfully built and pushed! | |
| The current recommended version was automatically fetched from artifacts.jgscripts.com. | |
| **Available Tags:** | |
| - `latest` - Currently recommended version (updated with each build) | |
| - `[VERSION]` - Specific version number (e.g. `24574`) - **remains permanently!** | |
| **Important:** Old version tags are never overwritten and remain permanently available in the registry. | |
| For production environments, it is recommended to use specific version numbers instead of `latest`. | |
| EOF |