Skip to content

Auto Rebase & Build Patches #350

Auto Rebase & Build Patches

Auto Rebase & Build Patches #350

name: Auto Rebase & Build Patches
on:
schedule:
- cron: '0 * * * *' # Every hour
workflow_dispatch: # Manual trigger
push:
branches:
- ci
env:
# The branch that contains your custom patches
SOURCE_BRANCH: patches-impl
# The upstream repo
UPSTREAM_REPO: dokploy/dokploy
# The upstream branch to sync from
UPSTREAM_BRANCH: canary
# Your custom image name
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/dokploy-patches
jobs:
check-and-rebase:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- name: Checkout your repo
uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git & Check Version
id: check
run: |
git config user.name "GitHub Action"
git config user.email "action@github.com"
git remote add upstream https://github.com/${{ env.UPSTREAM_REPO }}.git
git fetch upstream
# 1. Find the LAST commit that touched package.json in apps/dokploy
VERSION_COMMIT=$(git log -1 --format=%H upstream/${{ env.UPSTREAM_BRANCH }} -- apps/dokploy/package.json)
# 2. Extract Version and tag
# We use git show to read the file content from that commit without checking it out yet
APP_VERSION=$(git show $VERSION_COMMIT:apps/dokploy/package.json | jq -r .version)
echo "Detected upstream version: $APP_VERSION"
echo "app_version=$APP_VERSION" >> $GITHUB_OUTPUT
TARGET_COMMIT=$(git rev-parse --verify --quiet "$APP_VERSION^{commit}" || true)
if [ -z "$TARGET_COMMIT" ]; then
echo "No release tag yet. Skipping build"
echo "should_build=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Target Release Commit: $TARGET_COMMIT"
echo "commit_hash=$TARGET_COMMIT" >> "$GITHUB_OUTPUT"
# 3. Check Registry
IMAGE_URL="${{ env.IMAGE_NAME }}:$APP_VERSION"
echo "Checking for image: $IMAGE_URL"
if docker manifest inspect "$IMAGE_URL" > /dev/null 2>&1; then
echo "::warning::Image $IMAGE_URL already exists! Skipping build."
echo "should_build=false" >> "$GITHUB_OUTPUT"
else
echo "Image not found. Proceeding with build."
echo "should_build=true" >> "$GITHUB_OUTPUT"
fi
- name: Rebase & Create Branch
if: steps.check.outputs.should_build == 'true'
run: |
TARGET_COMMIT=${{ steps.check.outputs.commit_hash }}
APP_VERSION=${{ steps.check.outputs.app_version }}
echo "Starting rebase onto $TARGET_COMMIT for version $APP_VERSION..."
# 1. Checkout our patches
git checkout ${{ env.SOURCE_BRANCH }}
# 2. Create temp branch for rebase
git checkout -b temp-rebase-branch
# 3. Rebase onto the target commit
if ! git rebase $TARGET_COMMIT; then
echo "::error::Rebase failed! Manual intervention required."
git rebase --abort
exit 1
fi
# 4. Create release branch
RELEASE_BRANCH_NAME="release/${APP_VERSION}-patches"
echo "Creating branch: $RELEASE_BRANCH_NAME"
git checkout -B $RELEASE_BRANCH_NAME
# Push immediately (we need to be on this branch for build script to pick up context if needed, though script uses envs)
git push -f origin $RELEASE_BRANCH_NAME
- name: Setup Node.js
if: steps.check.outputs.should_build == 'true'
uses: actions/setup-node@v3
with:
node-version: 20
- name: Install Dependencies
if: steps.check.outputs.should_build == 'true'
run: |
corepack enable
corepack prepare pnpm@latest --activate
pnpm install --frozen-lockfile
- name: Login to GHCR
if: steps.check.outputs.should_build == 'true'
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Docker Image
if: steps.check.outputs.should_build == 'true'
run: |
# 0. Setup .env.production for Dockerfile
# Dockerfile COPY expects .env.production at root context
cp apps/dokploy/.env.production.example .env.production
# 1. Patch the push script using sed
# We replace 'dokploy/dokploy' with our custom image name AND inject set -e
sed -i "s|#!/bin/bash|#!/bin/bash\nset -e|g" apps/dokploy/docker/push.sh
sed -i "s|dokploy/dokploy|${{ env.IMAGE_NAME }}|g" apps/dokploy/docker/push.sh
# Patch push.sh to use the passed VERSION env var instead of calculating it
sed -i 's|VERSION=$(node -p "require('\''./package.json'\'').version")|VERSION=${VERSION}|g' apps/dokploy/docker/push.sh
# 2. Run the push script directly
chmod +x apps/dokploy/docker/push.sh
# Pass VERSION explicitly and run from root context (because Dockerfile expects root)
VERSION="${{ steps.check.outputs.app_version }}" ./apps/dokploy/docker/push.sh
- name: Create Release Tag
id: create_tag
if: steps.check.outputs.should_build == 'true'
run: |
VERSION=${{ steps.check.outputs.app_version }}
SHORT_HASH=$(git rev-parse --short HEAD)
TAG_NAME="${VERSION}-patches-${SHORT_HASH}"
echo "Creating tag $TAG_NAME"
git tag $TAG_NAME
git push origin $TAG_NAME
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
- name: Create GitHub Release
if: steps.check.outputs.should_build == 'true'
uses: softprops/action-gh-release@v1
with:
tag_name: "${{ steps.create_tag.outputs.tag_name }}"
name: "Dokploy Patches ${{ steps.check.outputs.app_version }}"
body: |
## Dokploy Patches Release
Based on upstream version: `${{ steps.check.outputs.app_version }}`
### Docker Image
This release corresponds to the Docker image tag: `${{ steps.check.outputs.app_version }}`
Update your Dokploy instance for a recent version and you can switch to the patched version:
```bash
docker pull ${{ env.IMAGE_NAME }}:${{ steps.check.outputs.app_version }}
docker service update --image ${{ env.IMAGE_NAME }}:${{ steps.check.outputs.app_version }} dokploy
```
[View Image on GHCR](https://github.com/${{ github.repository_owner }}/dokploy/pkgs/container/dokploy-patches)