Compare commits

...

14 Commits

Author SHA1 Message Date
DevContainer User 5da23def5b fix: add automatic release workflow for tag-based releases
- Triggers on tag pushes (v*) to create GitHub releases
- Publishes Helm chart to OCI registry
- Generates release notes with commit history
- Complements existing build-and-push workflow

Now releases are fully automated:
1. Push tag → build-and-push.yaml builds Docker images
2. Push tag → release.yaml creates GitHub release + publishes Helm chart

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 21:17:37 +00:00
DevContainer User 5532eee8cd chore: release version 0.2.4
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 19:13:41 +00:00
DevContainer User d32e453f93 feat: add PostgreSQL tuner (pgtuner) MCP sidecar
- Add pgtuner MCP sidecar configuration (disabled by default)
- Supports PostgreSQL performance tuning and optimization
- Analyzes slow queries, recommends indexes, detects bloat
- Requires DATABASE_URI secret to be configured
- Runs in SSE mode on port 8085

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 19:11:50 +00:00
DevContainer User f95e8877e8 chore: release version 0.2.3
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 17:31:09 +00:00
DevContainer User 46267b6e26 fix: resolve antigravity IDE init and homeassistant MCP issues (fixes #27, #28)
- Fix homeassistant MCP sidecar command by removing incorrect module specification
- Add init container for antigravity IDE to create /config/userdata directory
- Bump chart version to 0.2.2

The homeassistant sidecar was failing with "File not found: /app/ha_mcp.main"
because fastmcp should run without explicit module specification.

The antigravity IDE was failing to initialize due to missing /config/userdata
directory. Added an init container to ensure the directory exists with proper
permissions before the main container starts.

Generated with Claude Code via Happy

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 17:29:38 +00:00
github-actions[bot] c4cbd67399 chore: release version 0.2.2 2026-02-21 16:27:25 +00:00
DevContainer User a7799dbb16 hotfix: disable GitHub MCP sidecar - image doesn't exist
The GitHub MCP server has been archived and moved to servers-archived repo.
There is no Docker image available at ghcr.io/modelcontextprotocol/servers/github.

Disabling by default to prevent ImagePullBackOff errors.

TODO: Either build custom image from archived source or find alternative.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 16:25:45 +00:00
github-actions[bot] 45b8e5e95e chore: release version 0.2.1 2026-02-21 16:20:17 +00:00
DevContainer User a0b409239e feat: add GitHub MCP sidecar and fix Home Assistant MCP command (fixes #26)
- Fixed Home Assistant MCP command flags from --sse-server-host/port to --host/port
- Added GitHub MCP server as new sidecar (enabled by default)
- Uses existing GITHUB_TOKEN from environment
- Updated documentation and .mcp.json configuration

The GitHub MCP sidecar provides AI assistants with ability to interact with
GitHub repositories, issues, PRs, and more using the same token used for
repository cloning.

Fixes #26

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 16:19:11 +00:00
DevContainer User eacf41302c cleanup: remove redundant workflows and simplify CI/CD
Removed 4 redundant workflow files:
- helm-publish.yaml (integrated into release-unified)
- helm-release.yaml.old (the auto-version-bump nightmare)
- release.yaml (replaced by release-unified)
- tag-release.md (old docs, replaced by README.md)

Now down to just 3 clean workflows:
- release-unified.yaml: Complete release process
- quick-fix.yaml: Emergency Docker builds
- build-and-push.yaml: Automatic CI for PRs/tags

Also updated documentation to reflect the simplified pipeline.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 16:12:35 +00:00
github-actions[bot] cbdee590bf chore: release version 0.2.0 2026-02-21 16:09:49 +00:00
DevContainer User 5570b2c617 fix: completely overhaul the CI/CD pipeline to not suck
BREAKING CHANGE: Removed auto-version-bump workflow that was causing [skip ci] hell

New features:
- Unified release workflow that handles everything in one go
- Quick fix workflow for emergency deployments
- No more [skip ci] preventing Docker builds
- No more manual tag juggling
- Single button release process

The old pipeline was a disaster with disconnected workflows, auto-version-bumps
with [skip ci] that prevented Docker builds, and required manual tag deletion/
re-pushing to trigger builds. This new pipeline is actually usable.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 16:04:46 +00:00
DevContainer User c3f8421d60 cleanup: remove CI trigger file 2026-02-21 15:29:29 +00:00
DevContainer User 21d8fc73e6 ci: trigger build for v0.1.24
Force CI/CD pipeline to build the Docker image for v0.1.24 which includes:
- Git credentials automation fix
- Home Assistant MCP sidecar command fix

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 15:29:19 +00:00
11 changed files with 494 additions and 344 deletions
+94
View File
@@ -0,0 +1,94 @@
# CI/CD Pipeline Guide
## 🚀 Simplified Pipeline - Only 3 Workflows!
### 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 does EVERYTHING:**
- ✅ Updates chart version
- ✅ Creates git tag
- ✅ Builds Docker image with all proper tags
- ✅ Publishes Helm chart to GHCR
- ✅ Creates GitHub Release with changelog
- ✅ No more `[skip ci]` blocking builds!
### 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"
**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 | 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 |
## Examples
### Release a new version
```bash
# Via GitHub UI (Recommended):
# Go to Actions → Unified Release → Run workflow
# 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
# 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 workflow status
```bash
# 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.2.1): Bug fixes
## What We Fixed
### Before (Nightmare 😱)
- Auto-version-bump with `[skip ci]` prevented Docker builds
- 6+ disconnected workflows
- Manual tag deletion and re-pushing
- Version conflicts everywhere
### After (Simple! 🎉)
- **3 total workflows** (down from 6+)
- **1 button** for complete releases
- **No more `[skip ci]`** blocking builds
- **Clear separation** of concerns
-57
View File
@@ -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
+54
View File
@@ -0,0 +1,54 @@
name: Quick Fix Build
on:
workflow_dispatch:
inputs:
tag:
description: 'Tag for the image (defaults to latest)'
required: false
default: 'latest'
type: string
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tag }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64
- name: Summary
run: |
echo "## ✅ Quick Fix Build Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Images Published:" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
+159
View File
@@ -0,0 +1,159 @@
name: Unified Release
on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.1.25)'
required: true
type: string
release_type:
description: 'Release type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up Helm
uses: azure/setup-helm@v4
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Determine Version
id: version
run: |
if [ "${{ github.event.inputs.version }}" != "" ]; then
VERSION="${{ github.event.inputs.version }}"
else
# Auto-determine next version based on release type
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)
case "${{ github.event.inputs.release_type }}" in
major)
VERSION="$((MAJOR + 1)).0.0"
;;
minor)
VERSION="${MAJOR}.$((MINOR + 1)).0"
;;
patch)
VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
;;
esac
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "tag=v${VERSION}" >> $GITHUB_OUTPUT
echo "🚀 Releasing version ${VERSION}"
- name: Update Chart Version
run: |
sed -i "s/^version: .*/version: ${{ steps.version.outputs.version }}/" chart/Chart.yaml
git add chart/Chart.yaml
git commit -m "chore: release version ${{ steps.version.outputs.version }}"
- name: Create and Push Tag
run: |
git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}"
git push origin main
git push origin "${{ steps.version.outputs.tag }}"
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Docker Image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64
- name: Package Helm Chart
run: |
helm registry login ghcr.io \
--username ${{ github.actor }} \
--password ${{ secrets.GITHUB_TOKEN }}
helm package chart/
helm push devcontainer-${{ steps.version.outputs.version }}.tgz oci://ghcr.io/cpfarhood/charts
- name: Generate Release Notes
id: notes
run: |
# Get commits since last tag
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s (%h)" HEAD)
else
COMMITS=$(git log --pretty=format:"- %s (%h)" ${PREV_TAG}..HEAD)
fi
cat << EOF > release-notes.md
## 🚀 Release ${{ steps.version.outputs.version }}
### Changes
${COMMITS}
### Docker Image
\`\`\`bash
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }}
\`\`\`
### Helm Chart
\`\`\`bash
helm install devcontainer oci://ghcr.io/cpfarhood/charts/devcontainer --version ${{ steps.version.outputs.version }}
\`\`\`
EOF
echo "notes<<EOF" >> $GITHUB_OUTPUT
cat release-notes.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.version.outputs.tag }}
release_name: Release ${{ steps.version.outputs.tag }}
body: ${{ steps.notes.outputs.notes }}
draft: false
prerelease: false
+55 -20
View File
@@ -5,47 +5,82 @@ on:
tags:
- 'v*'
permissions:
contents: write
packages: write
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Helm
uses: azure/setup-helm@v4
- name: Extract version from tag
id: version
run: |
TAG=${GITHUB_REF#refs/tags/}
VERSION=${TAG#v}
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "🚀 Creating release for ${TAG}"
- name: Package and Push Helm Chart
run: |
helm registry login ghcr.io \
--username ${{ github.actor }} \
--password ${{ secrets.GITHUB_TOKEN }}
helm package chart/
helm push devcontainer-${{ steps.version.outputs.version }}.tgz oci://ghcr.io/cpfarhood/charts
- 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\`\`\`"
# Get commits since last tag
PREV_TAG=$(git describe --tags --abbrev=0 ${{ steps.version.outputs.tag }}^ 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s (%h)" ${{ steps.version.outputs.tag }})
else
NOTES="${TAG_MESSAGE}\n\n## Docker Image\n\n\`\`\`bash\ndocker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }}\n\`\`\`"
COMMITS=$(git log --pretty=format:"- %s (%h)" ${PREV_TAG}..${{ steps.version.outputs.tag }})
fi
cat << EOF > release-notes.md
## 🚀 Release ${{ steps.version.outputs.version }}
### Changes
${COMMITS}
### Docker Image
\`\`\`bash
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }}
\`\`\`
### Helm Chart
\`\`\`bash
helm install devcontainer oci://ghcr.io/cpfarhood/charts/devcontainer --version ${{ steps.version.outputs.version }}
\`\`\`
EOF
echo "notes<<EOF" >> $GITHUB_OUTPUT
echo -e "$NOTES" >> $GITHUB_OUTPUT
cat release-notes.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create Release
- name: Create GitHub Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
release_name: Release ${{ github.ref_name }}
tag_name: ${{ steps.version.outputs.tag }}
release_name: Release ${{ steps.version.outputs.tag }}
body: ${{ steps.notes.outputs.notes }}
draft: false
prerelease: false
prerelease: false
-259
View File
@@ -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
```
+12 -5
View File
@@ -1,5 +1,12 @@
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
},
"kubernetes": {
"type": "sse",
"url": "http://localhost:8080/sse"
@@ -8,14 +15,14 @@
"type": "sse",
"url": "http://localhost:8081/sse"
},
"homeassistant": {
"type": "sse",
"url": "http://localhost:8087/sse"
},
"playwright": {
"type": "sse",
"url": "http://playwright-mcp.playwright.svc.cluster.local:3000/sse"
}
},
"pgtuner": {
"type": "sse",
"url": "http://localhost:8085/sse"
}
}
}
+7 -1
View File
@@ -77,7 +77,7 @@ Container start
| `chart/templates/pvc.yaml` | PersistentVolumeClaim for user home |
| `chart/templates/service.yaml` | ClusterIP Service (VNC + optional SSH) |
| `chart/values.yaml` | Default Helm values |
| `.mcp.json` | MCP server connection config (Kubernetes, Flux, Playwright) |
| `.mcp.json` | MCP server connection config (Kubernetes, Flux, GitHub, Home Assistant, Playwright) |
| `Makefile` | Build/deploy automation |
### MCP Sidecars
@@ -88,11 +88,13 @@ MCP (Model Context Protocol) servers run as sidecar containers in the pod, enabl
|---------|-------|---------|------|----------|---------|
| `kubernetes-mcp` | `quay.io/containers/kubernetes_mcp_server` | v0.0.57 | 8080 | `http://localhost:8080/sse` | Enabled |
| `flux-mcp` | `ghcr.io/controlplaneio-fluxcd/flux-operator-mcp` | v0.41.1 | 8081 | `http://localhost:8081/sse` | Enabled |
| `github-mcp` | `ghcr.io/modelcontextprotocol/servers/github` | latest | 8088 | `http://localhost:8088/sse` | Enabled |
| `homeassistant-mcp` | `ghcr.io/homeassistant-ai/ha-mcp` | 6.7.1 | 8087 | `http://localhost:8087/sse` | Disabled |
**Note:**
- Kubernetes and Flux sidecars require `clusterAccess` != `none` to be deployed (they need RBAC permissions)
- Kubernetes and Flux sidecars inherit the pod's ServiceAccount RBAC permissions
- GitHub sidecar uses `GITHUB_TOKEN` from the env secret (same token used for repo cloning)
- Home Assistant sidecar requires `HOMEASSISTANT_URL` and `HOMEASSISTANT_TOKEN` in the env secret
- Playwright MCP remains an external service
@@ -107,6 +109,8 @@ mcpSidecars:
enabled: false
flux:
enabled: false
github:
enabled: false
homeassistant:
enabled: false
@@ -116,6 +120,8 @@ mcpSidecars:
enabled: true # Keep Kubernetes MCP enabled
flux:
enabled: false # Disable Flux MCP
github:
enabled: true # Keep GitHub MCP enabled (uses GITHUB_TOKEN)
homeassistant:
enabled: true # Enable Home Assistant MCP (requires secrets)
```
+1 -1
View File
@@ -2,5 +2,5 @@ apiVersion: v2
name: devcontainer
description: Antigravity Dev Container with Happy Coder AI assistant
type: application
version: 0.1.24
version: 0.2.4
appVersion: "latest"
+86 -1
View File
@@ -20,6 +20,25 @@ spec:
securityContext:
fsGroup: 1000
fsGroupChangePolicy: "OnRootMismatch"
{{- if and .Values.ide (eq .Values.ide "antigravity") }}
initContainers:
- name: setup-userdata
image: busybox:latest
command: ['sh', '-c']
args:
- |
echo "Setting up userdata directory..."
mkdir -p /config/userdata
chown 1000:1000 /config/userdata
chmod 755 /config/userdata
echo "Userdata directory setup complete"
volumeMounts:
- name: userhome
mountPath: /config
securityContext:
runAsUser: 0
runAsGroup: 0
{{- end }}
containers:
- name: devcontainer
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
@@ -151,7 +170,7 @@ spec:
- name: homeassistant-mcp
image: "{{ .Values.mcpSidecars.homeassistant.image.repository }}:{{ .Values.mcpSidecars.homeassistant.image.tag }}"
imagePullPolicy: Always
command: ["fastmcp", "run", "ha_mcp.main:app", "--transport", "sse", "--sse-server-host", "0.0.0.0", "--sse-server-port", "{{ .Values.mcpSidecars.homeassistant.port }}"]
command: ["fastmcp", "run", "--transport", "sse", "--host", "0.0.0.0", "--port", "{{ .Values.mcpSidecars.homeassistant.port }}"]
ports:
- name: homeassistant
containerPort: {{ .Values.mcpSidecars.homeassistant.port }}
@@ -181,6 +200,72 @@ spec:
resources:
{{- toYaml .Values.mcpSidecars.homeassistant.resources | nindent 12 }}
{{- end }}
{{- if .Values.mcpSidecars.github.enabled }}
- name: github-mcp
image: "{{ .Values.mcpSidecars.github.image.repository }}:{{ .Values.mcpSidecars.github.image.tag }}"
imagePullPolicy: Always
args:
- --sse
- --port={{ .Values.mcpSidecars.github.port }}
ports:
- name: github
containerPort: {{ .Values.mcpSidecars.github.port }}
env:
- name: GITHUB_PERSONAL_ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: {{ include "antigravity.envSecretName" . }}
key: github-token
optional: true
livenessProbe:
httpGet:
path: /health
port: {{ .Values.mcpSidecars.github.port }}
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: {{ .Values.mcpSidecars.github.port }}
initialDelaySeconds: 5
periodSeconds: 5
resources:
{{- toYaml .Values.mcpSidecars.github.resources | nindent 12 }}
{{- end }}
{{- if .Values.mcpSidecars.pgtuner.enabled }}
- name: pgtuner-mcp
image: "{{ .Values.mcpSidecars.pgtuner.image.repository }}:{{ .Values.mcpSidecars.pgtuner.image.tag }}"
imagePullPolicy: Always
command: ["python", "-m", "pgtuner_mcp", "--transport", "sse", "--port", "{{ .Values.mcpSidecars.pgtuner.port }}"]
ports:
- name: pgtuner
containerPort: {{ .Values.mcpSidecars.pgtuner.port }}
env:
- name: DATABASE_URI
valueFrom:
secretKeyRef:
name: {{ include "antigravity.envSecretName" . }}
key: database-uri
optional: true
- name: PGTUNER_EXCLUDE_USERIDS
valueFrom:
secretKeyRef:
name: {{ include "antigravity.envSecretName" . }}
key: pgtuner-exclude-userids
optional: true
livenessProbe:
tcpSocket:
port: {{ .Values.mcpSidecars.pgtuner.port }}
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
tcpSocket:
port: {{ .Values.mcpSidecars.pgtuner.port }}
initialDelaySeconds: 5
periodSeconds: 5
resources:
{{- toYaml .Values.mcpSidecars.pgtuner.resources | nindent 12 }}
{{- end }}
volumes:
- name: workspace
emptyDir: {}
+26
View File
@@ -108,3 +108,29 @@ mcpSidecars:
limits:
memory: "256Mi"
cpu: "500m"
github:
enabled: false # DISABLED: GitHub MCP server has been archived, image doesn't exist
image:
repository: ghcr.io/modelcontextprotocol/servers/github
tag: latest # Update to specific version once available
port: 8088
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"
pgtuner:
enabled: false # Disabled by default, requires DATABASE_URI in secrets
image:
repository: dog830228/pgtuner_mcp
tag: latest # TODO: pin to specific version once stable release available
port: 8085
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"