diff --git a/.github/workflows/README.md b/.github/workflows/README.md index c031f39..b0548b3 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -1,74 +1,94 @@ # CI/CD Pipeline Guide -## 🚀 New Simplified Pipeline +## 🚀 Simplified Pipeline - Only 3 Workflows! -### For Releases (Recommended) -Use the **Unified Release** workflow from GitHub Actions tab: -1. Go to Actions → Unified Release → Run workflow -2. Enter version number (e.g., 0.1.25) or choose release type -3. Click "Run workflow" +### 1️⃣ For Releases → **Unified Release** +Use this for all version releases: +1. Go to [Actions → Unified Release](https://github.com/cpfarhood/devcontainer/actions/workflows/release-unified.yaml) +2. Click "Run workflow" +3. Either: + - Enter specific version (e.g., `0.2.1`), OR + - Choose release type (patch/minor/major) for auto-increment +4. Click "Run workflow" -This single workflow: +**This single workflow does EVERYTHING:** - ✅ Updates chart version - ✅ Creates git tag -- ✅ Builds and pushes Docker image with proper tags -- ✅ Publishes Helm chart -- ✅ Creates GitHub Release with notes -- ✅ **NO MORE `[skip ci]` NONSENSE!** +- ✅ Builds Docker image with all proper tags +- ✅ Publishes Helm chart to GHCR +- ✅ Creates GitHub Release with changelog +- ✅ No more `[skip ci]` blocking builds! -### For Quick Fixes -Use the **Quick Fix Build** workflow when you need to push a fix without ceremony: -1. Go to Actions → Quick Fix Build → Run workflow -2. Optionally specify a tag (defaults to 'latest') -3. Click "Run workflow" +### 2️⃣ For Quick Fixes → **Quick Fix Build** +Use this for emergency fixes without version changes: +1. Go to [Actions → Quick Fix Build](https://github.com/cpfarhood/devcontainer/actions/workflows/quick-fix.yaml) +2. Click "Run workflow" +3. Enter tag (default: `latest`) +4. Click "Run workflow" -This builds and pushes the Docker image immediately without version bumps. +**Just builds and pushes Docker image** - no version bumps, no releases. + +### 3️⃣ Automatic CI → **Build and Push** +Runs automatically on: +- Pull requests (builds but doesn't push) +- Tags starting with `v*` (builds and pushes) +- Manual trigger available ## Workflow Files -| Workflow | Purpose | Trigger | What it does | -|----------|---------|---------|--------------| -| `release-unified.yaml` | **Main release workflow** | Manual dispatch | Complete release process | -| `quick-fix.yaml` | Emergency fixes | Manual dispatch | Just build & push Docker | -| `build-and-push.yaml` | CI builds | Tags & PRs | Auto-build on tags/PRs | -| `release.yaml` | GitHub releases | Tag push | Create GitHub release | -| `helm-publish.yaml` | Helm chart only | Tags | Publish Helm chart | +| Workflow | File | Purpose | When to Use | +|----------|------|---------|-------------| +| **Unified Release** | `release-unified.yaml` | Full release process | New versions | +| **Quick Fix Build** | `quick-fix.yaml` | Docker build only | Hotfixes | +| **Build and Push** | `build-and-push.yaml` | CI/CD automation | PRs & tags | -## Common Tasks +## Examples ### Release a new version ```bash -# Option 1: Use GitHub UI +# Via GitHub UI (Recommended): # Go to Actions → Unified Release → Run workflow -# Option 2: Use GitHub CLI -gh workflow run release-unified.yaml -f version=0.1.25 -f release_type=patch +# Via GitHub CLI: +gh workflow run release-unified.yaml -f version=0.2.1 +# OR auto-increment: +gh workflow run release-unified.yaml -f release_type=patch ``` ### Push a quick fix ```bash -# Use GitHub UI: Actions → Quick Fix Build → Run workflow -# Or: +# Via GitHub UI: +# Go to Actions → Quick Fix Build → Run workflow + +# Via GitHub CLI: gh workflow run quick-fix.yaml -f tag=hotfix-1 ``` -### Check build status +### Check workflow status ```bash -gh run list --workflow=release-unified.yaml +# List all recent runs +gh run list --limit 5 + +# Watch a specific workflow +gh run watch ``` ## Version Strategy - **Major** (1.0.0): Breaking changes - **Minor** (0.2.0): New features -- **Patch** (0.1.25): Bug fixes +- **Patch** (0.2.1): Bug fixes -## Old Pipeline Issues (Now Fixed!) +## What We Fixed -❌ **REMOVED**: Auto-version-bump with `[skip ci]` that prevented Docker builds -❌ **REMOVED**: Disconnected workflows requiring manual tag juggling -❌ **REMOVED**: Complex multi-step process for releases +### Before (Nightmare 😱) +- Auto-version-bump with `[skip ci]` prevented Docker builds +- 6+ disconnected workflows +- Manual tag deletion and re-pushing +- Version conflicts everywhere -✅ **NEW**: Single unified workflow that does everything -✅ **NEW**: Manual control over versions -✅ **NEW**: Quick fix workflow for emergencies \ No newline at end of file +### After (Simple! 🎉) +- **3 total workflows** (down from 6+) +- **1 button** for complete releases +- **No more `[skip ci]`** blocking builds +- **Clear separation** of concerns \ No newline at end of file diff --git a/.github/workflows/helm-publish.yaml b/.github/workflows/helm-publish.yaml deleted file mode 100644 index 7be1275..0000000 --- a/.github/workflows/helm-publish.yaml +++ /dev/null @@ -1,38 +0,0 @@ -name: Publish Helm Chart - -on: - push: - tags: - - 'v*' - workflow_dispatch: - -permissions: - packages: write - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up Helm - uses: azure/setup-helm@v4 - - - name: Get Chart Version - id: version - run: | - VERSION=$(grep '^version:' chart/Chart.yaml | awk '{print $2}') - echo "version=${VERSION}" >> $GITHUB_OUTPUT - - - name: Log in to GHCR - run: | - helm registry login ghcr.io \ - --username ${{ github.actor }} \ - --password ${{ secrets.GITHUB_TOKEN }} - - - name: Package and Push Chart - run: | - helm package chart/ - helm push devcontainer-${{ steps.version.outputs.version }}.tgz oci://ghcr.io/cpfarhood/charts - echo "✅ Helm chart published: devcontainer-${{ steps.version.outputs.version }}" \ No newline at end of file diff --git a/.github/workflows/helm-release.yaml.old b/.github/workflows/helm-release.yaml.old deleted file mode 100644 index 0ab678d..0000000 --- a/.github/workflows/helm-release.yaml.old +++ /dev/null @@ -1,57 +0,0 @@ -name: Publish Helm Chart - -on: - push: - branches: - - main - paths: - - 'chart/**' - workflow_dispatch: - -permissions: - contents: write - packages: write - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Helm - uses: azure/setup-helm@v4 - - - name: Bump patch version - id: bump - run: | - CURRENT=$(grep '^version:' chart/Chart.yaml | awk '{print $2}') - MAJOR=$(echo $CURRENT | cut -d. -f1) - MINOR=$(echo $CURRENT | cut -d. -f2) - PATCH=$(echo $CURRENT | cut -d. -f3) - NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" - sed -i "s/^version: .*/version: ${NEW_VERSION}/" chart/Chart.yaml - echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT - - - name: Commit version bump - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add chart/Chart.yaml - git commit -m "chore: bump chart version to ${{ steps.bump.outputs.version }} [skip ci]" - git push - - - name: Log in to GHCR - run: | - helm registry login ghcr.io \ - --username ${{ github.actor }} \ - --password ${{ secrets.GITHUB_TOKEN }} - - - name: Package chart - run: helm package chart/ - - - name: Push chart to GHCR - run: | - helm push devcontainer-${{ steps.bump.outputs.version }}.tgz oci://ghcr.io/cpfarhood/charts diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 573191e..0000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,51 +0,0 @@ -name: Release - -on: - push: - tags: - - 'v*' - -permissions: - contents: write - packages: write - -jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - name: Generate Release Notes - id: notes - run: | - # Get the tag message or generate from commits - TAG_MESSAGE=$(git tag -l --format='%(contents)' ${{ github.ref_name }}) - if [ -z "$TAG_MESSAGE" ]; then - # Generate from commit messages since last tag - PREV_TAG=$(git describe --tags --abbrev=0 ${{ github.ref_name }}^ 2>/dev/null || echo "") - if [ -z "$PREV_TAG" ]; then - COMMITS=$(git log --pretty=format:"- %s (%h)" ${{ github.ref_name }}) - else - COMMITS=$(git log --pretty=format:"- %s (%h)" ${PREV_TAG}..${{ github.ref_name }}) - fi - NOTES="## Changes\n\n${COMMITS}\n\n## Docker Image\n\n\`\`\`bash\ndocker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }}\n\`\`\`" - else - NOTES="${TAG_MESSAGE}\n\n## Docker Image\n\n\`\`\`bash\ndocker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }}\n\`\`\`" - fi - echo "notes<> $GITHUB_OUTPUT - echo -e "$NOTES" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Create Release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref_name }} - release_name: Release ${{ github.ref_name }} - body: ${{ steps.notes.outputs.notes }} - draft: false - prerelease: false diff --git a/.github/workflows/tag-release.md b/.github/workflows/tag-release.md deleted file mode 100644 index 66bd60a..0000000 --- a/.github/workflows/tag-release.md +++ /dev/null @@ -1,259 +0,0 @@ -# Release Process - -This document describes how to create releases for this project. - -## Semantic Versioning - -We follow [Semantic Versioning 2.0.0](https://semver.org/): - -- **MAJOR** version (v2.0.0): Incompatible API/breaking changes -- **MINOR** version (v1.1.0): New features, backwards compatible -- **PATCH** version (v1.0.1): Bug fixes, backwards compatible - -## Creating a Release - -### Method 1: Using GitHub CLI (Recommended) - -```bash -# Ensure you're on main branch and up to date -git checkout main -git pull - -# Create and push a tag -VERSION="v1.0.0" # Change this -git tag -a "$VERSION" -m "Release $VERSION - -## What's New -- Feature 1 -- Feature 2 -- Bug fix 1 - -## Docker Image -\`\`\`bash -docker pull ghcr.io/cpfarhood/devcontainer:$VERSION -\`\`\` -" - -git push origin "$VERSION" - -# The GitHub Actions workflow will automatically: -# 1. Build the Docker image -# 2. Push to ghcr.io with multiple tags -# 3. Create a GitHub release with notes -``` - -### Method 2: Using Git Tags Only - -```bash -git checkout main -git pull - -# Create annotated tag -git tag -a v1.0.0 -m "Release v1.0.0" - -# Push tag -git push origin v1.0.0 -``` - -### Method 3: Using GitHub Web UI - -1. Go to https://github.com/cpfarhood/devcontainer/releases -2. Click "Draft a new release" -3. Click "Choose a tag" -4. Type the new version (e.g., `v1.0.0`) -5. Click "Create new tag on publish" -6. Fill in the release title and description -7. Click "Publish release" - -## What Happens Automatically - -When you push a version tag (`v*`), GitHub Actions will: - -1. **Build Docker image** with multiple tags: - - `ghcr.io/cpfarhood/devcontainer:v1.2.3` (exact version) - - `ghcr.io/cpfarhood/devcontainer:1.2` (minor version) - - `ghcr.io/cpfarhood/devcontainer:1` (major version) - - `ghcr.io/cpfarhood/devcontainer:latest` (if on default branch) - -2. **Create GitHub Release** with: - - Auto-generated release notes from commits - - Docker pull command in the description - -## Version Bump Guidelines - -### Patch Release (v1.0.X) -- Bug fixes -- Documentation updates -- Minor dependency updates -- No new features -- No breaking changes - -**Example:** v1.0.1 -```bash -git tag -a v1.0.1 -m "Release v1.0.1 - Bug fixes" -git push origin v1.0.1 -``` - -### Minor Release (v1.X.0) -- New features -- New optional configuration variables -- Enhancements to existing features -- Backwards compatible -- No breaking changes - -**Example:** v1.1.0 -```bash -git tag -a v1.1.0 -m "Release v1.1.0 - New Happy Coder features" -git push origin v1.1.0 -``` - -### Major Release (vX.0.0) -- Breaking changes -- Required configuration changes -- Removal of deprecated features -- Incompatible API changes - -**Example:** v2.0.0 -```bash -git tag -a v2.0.0 -m "Release v2.0.0 - Breaking: New storage architecture" -git push origin v2.0.0 -``` - -## Pre-releases - -For alpha, beta, or release candidates: - -```bash -# Alpha -git tag -a v1.1.0-alpha.1 -m "Release v1.1.0-alpha.1" -git push origin v1.1.0-alpha.1 - -# Beta -git tag -a v1.1.0-beta.1 -m "Release v1.1.0-beta.1" -git push origin v1.1.0-beta.1 - -# Release Candidate -git tag -a v1.1.0-rc.1 -m "Release v1.1.0-rc.1" -git push origin v1.1.0-rc.1 -``` - -## Release Checklist - -Before creating a release: - -- [ ] All tests pass -- [ ] Documentation is up to date -- [ ] CHANGELOG.md is updated (if you maintain one) -- [ ] Version number follows semver -- [ ] On main/master branch -- [ ] All changes are committed -- [ ] Tag message includes release notes - -## Docker Image Tags - -Each release creates multiple Docker tags for flexibility: - -| Git Tag | Docker Tags Created | -|---------|---------------------| -| v1.2.3 | `:v1.2.3`, `:1.2`, `:1`, `:latest` | -| v2.0.0 | `:v2.0.0`, `:2.0`, `:2`, `:latest` | -| v1.2.4-beta.1 | `:v1.2.4-beta.1`, `:1.2-beta` | - -**Usage examples:** -```bash -# Specific version (recommended for production) -docker pull ghcr.io/cpfarhood/devcontainer:v1.2.3 - -# Minor version (gets patches automatically) -docker pull ghcr.io/cpfarhood/devcontainer:1.2 - -# Major version (gets minor updates and patches) -docker pull ghcr.io/cpfarhood/devcontainer:1 - -# Latest (always gets newest stable release) -docker pull ghcr.io/cpfarhood/devcontainer:latest -``` - -## Viewing Releases - -- **GitHub Releases:** https://github.com/cpfarhood/devcontainer/releases -- **Docker Images:** https://github.com/cpfarhood/devcontainer/pkgs/container/devcontainer -- **Git Tags:** `git tag -l` - -## Deleting a Release - -If you need to delete a bad release: - -```bash -# Delete local tag -git tag -d v1.0.0 - -# Delete remote tag -git push origin :refs/tags/v1.0.0 - -# Delete GitHub release (use web UI or gh CLI) -gh release delete v1.0.0 -``` - -**Note:** Docker images pushed to ghcr.io cannot be easily deleted. It's better to create a new patch version. - -## First Release - -For the initial v1.0.0 release: - -```bash -git checkout main -git pull - -git tag -a v1.0.0 -m "Release v1.0.0 - Initial Release - -## Features -- Antigravity IDE with web-based VNC access -- Happy Coder AI assistant integration -- Automatic GitHub repository cloning -- Persistent home directory with ReadWriteMany PVC -- Secure non-root execution (claude user, UID 1000) -- Support for private repositories with GitHub token -- HTTPRoute (Gateway API) support -- Multi-platform Docker images -- Comprehensive deployment documentation - -## Docker Image -\`\`\`bash -docker pull ghcr.io/cpfarhood/devcontainer:v1.0.0 -\`\`\` - -## Deployment -See DEPLOYMENT.md for complete deployment instructions. -" - -git push origin v1.0.0 -``` - -## Example Release Workflow - -```bash -# 1. Finish your feature/fix on a branch -git checkout feature/new-feature -git commit -m "feat: Add new feature" -git push - -# 2. Create PR and merge to main -gh pr create -# ... get approval and merge ... - -# 3. Pull latest main -git checkout main -git pull - -# 4. Create release tag -git tag -a v1.1.0 -m "Release v1.1.0 - New feature" -git push origin v1.1.0 - -# 5. Wait for GitHub Actions -# - Check: https://github.com/cpfarhood/devcontainer/actions - -# 6. Verify release -# - GitHub: https://github.com/cpfarhood/devcontainer/releases -# - Docker: docker pull ghcr.io/cpfarhood/devcontainer:v1.1.0 -```