name: Release on: push: branches: - main tags: - 'v*' workflow_dispatch: inputs: version: description: 'Version to release (e.g., 1.6.24)' required: true type: string prerelease: description: 'Mark as pre-release' type: boolean default: false concurrency: group: release-${{ github.ref }} cancel-in-progress: false permissions: contents: write env: DOCKER_IMAGE: jhd3197/serverkit jobs: ci-gate: name: CI Gate uses: ./.github/workflows/backend-ci.yml version: name: Resolve Version runs-on: ubuntu-latest needs: ci-gate outputs: version: ${{ steps.version.outputs.version }} tag: ${{ steps.version.outputs.tag }} steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Get version id: version run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then VERSION="${{ github.event.inputs.version }}" elif [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref_type }}" = "tag" ]; then VERSION="${GITHUB_REF#refs/tags/v}" else VERSION=$(cat VERSION | tr -d '[:space:]') fi TAG="v$VERSION" echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "tag=$TAG" >> "$GITHUB_OUTPUT" echo "Releasing ServerKit version: $VERSION" - name: Create and push tag if: github.event_name == 'push' && github.ref_type != 'tag' run: | TAG="${{ steps.version.outputs.tag }}" if git rev-parse "$TAG" >/dev/null 2>&1; then echo "Tag $TAG already exists, skipping" else git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git tag -a "$TAG" -m "Release $TAG" git push origin "$TAG" fi build-release: name: Build Release Tarball runs-on: ${{ matrix.runner }} needs: version strategy: fail-fast: true matrix: include: - runner: ubuntu-latest arch: amd64 - runner: ubuntu-24.04-arm arch: arm64 steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '20' - name: Install build dependencies run: | sudo apt-get update sudo apt-get install -y python3-venv python3-pip rsync - name: Build release tarball env: BUILD_ARCH: ${{ matrix.arch }} run: bash scripts/build-release.sh - name: Upload release artifacts uses: actions/upload-artifact@v4 with: name: serverkit-release-${{ matrix.arch }} path: | serverkit-*.tar.gz checksums.txt if-no-files-found: error build-docker: name: Build Docker Image runs-on: ubuntu-latest needs: version steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} continue-on-error: true - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 push: ${{ secrets.DOCKERHUB_USERNAME != '' }} tags: | ${{ env.DOCKER_IMAGE }}:latest ${{ env.DOCKER_IMAGE }}:${{ needs.version.outputs.version }} build-args: | VERSION=${{ needs.version.outputs.version }} BUILD_TIME=${{ github.event.repository.updated_at }} GIT_COMMIT=${{ github.sha }} release: name: Create Release runs-on: ubuntu-latest needs: [version, build-docker, build-release] permissions: contents: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Download release artifacts uses: actions/download-artifact@v4 with: path: release-artifacts pattern: serverkit-release-* merge-multiple: true - name: Assemble release files run: | mkdir -p release cp VERSION release/VERSION cp docker-compose.yml release/docker-compose.yml cp Dockerfile release/Dockerfile mv release-artifacts/serverkit-*.tar.gz release/ 2>/dev/null || true mv release-artifacts/checksums.txt release/checksums.txt 2>/dev/null || true cd release sha256sum serverkit-*.tar.gz >> checksums.txt sort -u checksums.txt -o checksums.txt cat checksums.txt - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: tag_name: ${{ needs.version.outputs.tag }} name: ServerKit ${{ needs.version.outputs.tag }} draft: false prerelease: ${{ github.event.inputs.prerelease == 'true' }} files: | release/* body: | ## ServerKit ${{ needs.version.outputs.tag }} ServerKit is a server control panel for managing web applications, databases, Docker containers, and security on VPS/dedicated servers. ### Docker ```bash docker pull ${{ env.DOCKER_IMAGE }}:${{ needs.version.outputs.version }} docker pull ${{ env.DOCKER_IMAGE }}:latest ``` ### One-line installer ```bash curl -fsSL https://serverkit.ai/install.sh | bash ``` ### Quick Start ```bash git clone https://github.com/${{ github.repository }}.git cd ServerKit docker compose up -d ``` Default credentials: `admin` / `admin` ### What's New See [CHANGELOG](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details. env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} summary: name: Release Summary runs-on: ubuntu-latest needs: [version, release] steps: - name: Create summary run: | echo "## ServerKit Release Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Version:** ${{ needs.version.outputs.tag }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Docker" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Tag | Image |" >> $GITHUB_STEP_SUMMARY echo "|-----|-------|" >> $GITHUB_STEP_SUMMARY echo "| latest | ${{ env.DOCKER_IMAGE }}:latest |" >> $GITHUB_STEP_SUMMARY echo "| ${{ needs.version.outputs.version }} | ${{ env.DOCKER_IMAGE }}:${{ needs.version.outputs.version }} |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Release" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Tarballs: serverkit-${{ needs.version.outputs.tag }}-linux-amd64.tar.gz, serverkit-${{ needs.version.outputs.tag }}-linux-arm64.tar.gz" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Release created at: https://github.com/${{ github.repository }}/releases/tag/${{ needs.version.outputs.tag }}" >> $GITHUB_STEP_SUMMARY