name: Build & Push Docker Image on: push: branches: [main] paths-ignore: - 'docs/**' - '**/*.md' workflow_dispatch: permissions: contents: write jobs: version-bump: runs-on: ubuntu-latest outputs: version: ${{ steps.bump.outputs.VERSION }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Determine bump type and update version id: bump run: | # Check if this push is a merge commit from dev branch COMMIT_MSG=$(git log -1 --pretty=%s) PARENT_COUNT=$(git log -1 --pretty=%p | wc -w) if echo "$COMMIT_MSG" | grep -qiE "^Merge (pull request|branch).*dev"; then BUMP="minor" elif [ "$PARENT_COUNT" -gt 1 ] && git log -1 --pretty=%P | xargs -n1 git branch -r --contains 2>/dev/null | grep -q "origin/dev"; then BUMP="minor" else BUMP="patch" fi echo "Bump type: $BUMP" # Read current version CURRENT=$(node -p "require('./server/package.json').version") IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT" if [ "$BUMP" = "minor" ]; then MINOR=$((MINOR + 1)) PATCH=0 else PATCH=$((PATCH + 1)) fi NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" echo "VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT echo "$CURRENT → $NEW_VERSION ($BUMP)" # Update both package.json files cd server && npm version "$NEW_VERSION" --no-git-tag-version && cd .. cd client && npm version "$NEW_VERSION" --no-git-tag-version && cd .. # Commit and tag git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add server/package.json server/package-lock.json client/package.json client/package-lock.json git commit -m "chore: bump version to $NEW_VERSION [skip ci]" git tag "v$NEW_VERSION" git push origin main --follow-tags build: runs-on: ${{ matrix.runner }} needs: version-bump strategy: fail-fast: false matrix: include: - platform: linux/amd64 runner: ubuntu-latest - platform: linux/arm64 runner: ubuntu-24.04-arm steps: - name: Prepare platform tag-safe name run: echo "PLATFORM_PAIR=$(echo ${{ matrix.platform }} | sed 's|/|-|g')" >> $GITHUB_ENV - uses: actions/checkout@v4 with: ref: main - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push by digest id: build uses: docker/build-push-action@v6 with: context: . platforms: ${{ matrix.platform }} outputs: type=image,name=mauriceboe/trek,push-by-digest=true,name-canonical=true,push=true no-cache: true - name: Export digest run: | mkdir -p /tmp/digests digest="${{ steps.build.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" - name: Upload digest artifact uses: actions/upload-artifact@v4 with: name: digests-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 merge: runs-on: ubuntu-latest needs: [version-bump, build] steps: - uses: actions/checkout@v4 with: ref: main - name: Download build digests uses: actions/download-artifact@v4 with: path: /tmp/digests pattern: digests-* merge-multiple: true - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Create and push multi-arch manifest working-directory: /tmp/digests run: | VERSION=${{ needs.version-bump.outputs.version }} mapfile -t digests < <(printf 'mauriceboe/trek@sha256:%s\n' *) docker buildx imagetools create \ -t mauriceboe/trek:latest \ -t mauriceboe/trek:$VERSION \ -t mauriceboe/nomad:latest \ -t mauriceboe/nomad:$VERSION \ "${digests[@]}" - name: Inspect manifest run: docker buildx imagetools inspect mauriceboe/trek:latest