Add comprehensive release process documentation
- Multi-architecture build instructions (AMD64, ARM64) - Publishing to Docker Hub, GHCR, GitLab, self-hosted registries - Git tagging and GitHub/GitLab release creation - Release notes template - CI/CD automation examples (GitLab CI, GitHub Actions) - Rollback procedures - Release checklist
This commit is contained in:
parent
316c0b04f9
commit
273c7b79e6
1 changed files with 441 additions and 0 deletions
441
RELEASE.md
Normal file
441
RELEASE.md
Normal file
|
|
@ -0,0 +1,441 @@
|
|||
# Release Process for Towerops Agent
|
||||
|
||||
This document describes how to build, tag, and publish releases of the Towerops agent Docker image.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Podman or Docker installed
|
||||
- Access to container registry (Docker Hub, GitHub Container Registry, GitLab Registry, etc.)
|
||||
- Agent code built and tested
|
||||
|
||||
## Version Numbering
|
||||
|
||||
Follow semantic versioning (SemVer):
|
||||
- **MAJOR**: Incompatible API/protocol changes
|
||||
- **MINOR**: New functionality, backwards compatible
|
||||
- **PATCH**: Bug fixes, backwards compatible
|
||||
|
||||
Current version: **0.1.0**
|
||||
|
||||
## Build Process
|
||||
|
||||
### 1. Update Version Numbers
|
||||
|
||||
Before building a release, update version numbers in:
|
||||
|
||||
1. **Cargo.toml**:
|
||||
```toml
|
||||
[package]
|
||||
name = "towerops-agent"
|
||||
version = "0.1.0" # Update this
|
||||
```
|
||||
|
||||
2. **CLAUDE.md** - Update status section
|
||||
|
||||
3. **README.md** - Update any version references
|
||||
|
||||
### 2. Build Multi-Architecture Images
|
||||
|
||||
Build for both AMD64 and ARM64:
|
||||
|
||||
```bash
|
||||
cd /Users/graham/dev/towerops/towerops-agent
|
||||
|
||||
# Build for ARM64 (Apple Silicon)
|
||||
podman build --platform linux/arm64 -t towerops-agent:0.1.0-arm64 .
|
||||
|
||||
# Build for AMD64 (Intel/AMD)
|
||||
podman build --platform linux/amd64 -t towerops-agent:0.1.0-amd64 .
|
||||
```
|
||||
|
||||
### 3. Tag Images
|
||||
|
||||
Tag with version and 'latest':
|
||||
|
||||
```bash
|
||||
# Tag ARM64
|
||||
podman tag towerops-agent:0.1.0-arm64 localhost/towerops-agent:0.1.0
|
||||
podman tag towerops-agent:0.1.0-arm64 localhost/towerops-agent:latest
|
||||
|
||||
# Tag AMD64
|
||||
podman tag towerops-agent:0.1.0-amd64 localhost/towerops-agent:0.1.0-amd64
|
||||
```
|
||||
|
||||
### 4. Test Images Locally
|
||||
|
||||
Before publishing, test both images:
|
||||
|
||||
```bash
|
||||
# Test ARM64
|
||||
podman run --rm \
|
||||
-e TOWEROPS_API_URL=http://localhost:4000 \
|
||||
-e TOWEROPS_AGENT_TOKEN=test-token \
|
||||
localhost/towerops-agent:0.1.0 --version
|
||||
|
||||
# Test AMD64 (if on compatible platform)
|
||||
podman run --rm --platform linux/amd64 \
|
||||
-e TOWEROPS_API_URL=http://localhost:4000 \
|
||||
-e TOWEROPS_AGENT_TOKEN=test-token \
|
||||
localhost/towerops-agent:0.1.0-amd64 --version
|
||||
```
|
||||
|
||||
## Publishing to Container Registries
|
||||
|
||||
### Option 1: Docker Hub
|
||||
|
||||
**Registry**: `docker.io/username/towerops-agent`
|
||||
|
||||
1. **Login**:
|
||||
```bash
|
||||
podman login docker.io
|
||||
# Enter username and password/token
|
||||
```
|
||||
|
||||
2. **Tag for Docker Hub**:
|
||||
```bash
|
||||
# Replace 'username' with your Docker Hub username
|
||||
DOCKER_USER="username"
|
||||
|
||||
podman tag localhost/towerops-agent:0.1.0 docker.io/${DOCKER_USER}/towerops-agent:0.1.0
|
||||
podman tag localhost/towerops-agent:latest docker.io/${DOCKER_USER}/towerops-agent:latest
|
||||
podman tag localhost/towerops-agent:0.1.0-amd64 docker.io/${DOCKER_USER}/towerops-agent:0.1.0-amd64
|
||||
```
|
||||
|
||||
3. **Push**:
|
||||
```bash
|
||||
podman push docker.io/${DOCKER_USER}/towerops-agent:0.1.0
|
||||
podman push docker.io/${DOCKER_USER}/towerops-agent:latest
|
||||
podman push docker.io/${DOCKER_USER}/towerops-agent:0.1.0-amd64
|
||||
```
|
||||
|
||||
4. **Create multi-arch manifest** (optional, for `docker pull` without specifying platform):
|
||||
```bash
|
||||
podman manifest create docker.io/${DOCKER_USER}/towerops-agent:0.1.0
|
||||
podman manifest add docker.io/${DOCKER_USER}/towerops-agent:0.1.0 docker.io/${DOCKER_USER}/towerops-agent:0.1.0-arm64
|
||||
podman manifest add docker.io/${DOCKER_USER}/towerops-agent:0.1.0 docker.io/${DOCKER_USER}/towerops-agent:0.1.0-amd64
|
||||
podman manifest push docker.io/${DOCKER_USER}/towerops-agent:0.1.0
|
||||
```
|
||||
|
||||
### Option 2: GitHub Container Registry (ghcr.io)
|
||||
|
||||
**Registry**: `ghcr.io/username/towerops-agent`
|
||||
|
||||
1. **Create Personal Access Token**:
|
||||
- Go to GitHub Settings → Developer settings → Personal access tokens
|
||||
- Generate new token with `write:packages` and `read:packages` scopes
|
||||
- Save the token securely
|
||||
|
||||
2. **Login**:
|
||||
```bash
|
||||
echo $GITHUB_TOKEN | podman login ghcr.io -u USERNAME --password-stdin
|
||||
```
|
||||
|
||||
3. **Tag for GHCR**:
|
||||
```bash
|
||||
GITHUB_USER="username"
|
||||
|
||||
podman tag localhost/towerops-agent:0.1.0 ghcr.io/${GITHUB_USER}/towerops-agent:0.1.0
|
||||
podman tag localhost/towerops-agent:latest ghcr.io/${GITHUB_USER}/towerops-agent:latest
|
||||
```
|
||||
|
||||
4. **Push**:
|
||||
```bash
|
||||
podman push ghcr.io/${GITHUB_USER}/towerops-agent:0.1.0
|
||||
podman push ghcr.io/${GITHUB_USER}/towerops-agent:latest
|
||||
```
|
||||
|
||||
5. **Make Package Public** (optional):
|
||||
- Go to package settings on GitHub
|
||||
- Change visibility to public
|
||||
|
||||
### Option 3: GitLab Container Registry
|
||||
|
||||
**Registry**: `registry.gitlab.com/username/towerops-agent`
|
||||
|
||||
1. **Create Deploy Token or Personal Access Token**:
|
||||
- GitLab Project → Settings → Repository → Deploy tokens
|
||||
- Or use personal access token with `read_registry` and `write_registry` scopes
|
||||
|
||||
2. **Login**:
|
||||
```bash
|
||||
podman login registry.gitlab.com
|
||||
# Username: your GitLab username or deploy token name
|
||||
# Password: personal access token or deploy token
|
||||
```
|
||||
|
||||
3. **Tag for GitLab**:
|
||||
```bash
|
||||
GITLAB_USER="username"
|
||||
|
||||
podman tag localhost/towerops-agent:0.1.0 registry.gitlab.com/${GITLAB_USER}/towerops-agent:0.1.0
|
||||
podman tag localhost/towerops-agent:latest registry.gitlab.com/${GITLAB_USER}/towerops-agent:latest
|
||||
```
|
||||
|
||||
4. **Push**:
|
||||
```bash
|
||||
podman push registry.gitlab.com/${GITLAB_USER}/towerops-agent:0.1.0
|
||||
podman push registry.gitlab.com/${GITLAB_USER}/towerops-agent:latest
|
||||
```
|
||||
|
||||
### Option 4: Self-Hosted Registry
|
||||
|
||||
**Registry**: `registry.example.com/towerops-agent`
|
||||
|
||||
1. **Login** (if authentication required):
|
||||
```bash
|
||||
podman login registry.example.com
|
||||
```
|
||||
|
||||
2. **Tag**:
|
||||
```bash
|
||||
podman tag localhost/towerops-agent:0.1.0 registry.example.com/towerops-agent:0.1.0
|
||||
podman tag localhost/towerops-agent:latest registry.example.com/towerops-agent:latest
|
||||
```
|
||||
|
||||
3. **Push**:
|
||||
```bash
|
||||
podman push registry.example.com/towerops-agent:0.1.0
|
||||
podman push registry.example.com/towerops-agent:latest
|
||||
```
|
||||
|
||||
## Git Release Tagging
|
||||
|
||||
After publishing the Docker images:
|
||||
|
||||
1. **Commit all changes**:
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "Release v0.1.0"
|
||||
```
|
||||
|
||||
2. **Create and push git tag**:
|
||||
```bash
|
||||
git tag -a v0.1.0 -m "Release v0.1.0 - Initial production release"
|
||||
git push origin v0.1.0
|
||||
git push origin main
|
||||
```
|
||||
|
||||
3. **Create GitHub/GitLab Release**:
|
||||
- Go to repository releases page
|
||||
- Create new release from tag v0.1.0
|
||||
- Add release notes (see template below)
|
||||
|
||||
## Release Notes Template
|
||||
|
||||
```markdown
|
||||
# Towerops Agent v0.1.0
|
||||
|
||||
## Features
|
||||
|
||||
- Remote SNMP polling for Towerops equipment
|
||||
- Protocol Buffers API communication
|
||||
- SQLite-based metric buffering (24-hour retention)
|
||||
- Automatic reconnection and retry logic
|
||||
- Multi-architecture support (AMD64, ARM64)
|
||||
- Minimal footprint: 11.8 MB Docker image
|
||||
|
||||
## Configuration
|
||||
|
||||
- API URL and authentication token via environment variables
|
||||
- Configurable poll intervals per equipment
|
||||
- Customizable database path
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/username/towerops-agent:0.1.0
|
||||
```
|
||||
|
||||
See [USER_GUIDE.md](USER_GUIDE.md) for deployment instructions.
|
||||
|
||||
## System Requirements
|
||||
|
||||
- Docker or Podman
|
||||
- Network access to Towerops API
|
||||
- Network access to SNMP devices (UDP port 161)
|
||||
- 50-100 MB disk space for database
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
None (initial release)
|
||||
|
||||
## Known Issues
|
||||
|
||||
None
|
||||
|
||||
## Contributors
|
||||
|
||||
- [List contributors]
|
||||
```
|
||||
|
||||
## CI/CD Automation (Optional)
|
||||
|
||||
### GitLab CI Example
|
||||
|
||||
Create `.gitlab-ci.yml`:
|
||||
|
||||
```yaml
|
||||
variables:
|
||||
REGISTRY_IMAGE: $CI_REGISTRY_IMAGE
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- release
|
||||
|
||||
test:
|
||||
stage: test
|
||||
image: rust:1.83-alpine
|
||||
before_script:
|
||||
- apk add --no-cache musl-dev protobuf-dev
|
||||
script:
|
||||
- cargo test --release
|
||||
only:
|
||||
- branches
|
||||
|
||||
build:
|
||||
stage: build
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- docker build -t $REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
|
||||
- docker push $REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
|
||||
only:
|
||||
- main
|
||||
|
||||
release:
|
||||
stage: release
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
script:
|
||||
- docker pull $REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
|
||||
- docker tag $REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||
- docker tag $REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $REGISTRY_IMAGE:latest
|
||||
- docker push $REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||
- docker push $REGISTRY_IMAGE:latest
|
||||
only:
|
||||
- tags
|
||||
```
|
||||
|
||||
### GitHub Actions Example
|
||||
|
||||
Create `.github/workflows/release.yml`:
|
||||
|
||||
```yaml
|
||||
name: Build and Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- 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: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract version from tag
|
||||
id: version
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ github.repository }}:${{ steps.version.outputs.VERSION }}
|
||||
ghcr.io/${{ github.repository }}:latest
|
||||
```
|
||||
|
||||
## Verification After Release
|
||||
|
||||
1. **Test pulling image**:
|
||||
```bash
|
||||
podman pull ghcr.io/username/towerops-agent:0.1.0
|
||||
```
|
||||
|
||||
2. **Verify image size**:
|
||||
```bash
|
||||
podman images towerops-agent
|
||||
# Should be ~11-12 MB
|
||||
```
|
||||
|
||||
3. **Test image runs**:
|
||||
```bash
|
||||
podman run --rm ghcr.io/username/towerops-agent:0.1.0 --help
|
||||
```
|
||||
|
||||
4. **Update documentation**:
|
||||
- Update USER_GUIDE.md with new image URL
|
||||
- Update example docker-compose files
|
||||
- Update Phoenix UI modal with new image reference
|
||||
|
||||
## Rollback Procedure
|
||||
|
||||
If a release has critical issues:
|
||||
|
||||
1. **Revert 'latest' tag** to previous version:
|
||||
```bash
|
||||
# Find previous working version
|
||||
podman pull ghcr.io/username/towerops-agent:0.0.9
|
||||
|
||||
# Re-tag as latest
|
||||
podman tag ghcr.io/username/towerops-agent:0.0.9 ghcr.io/username/towerops-agent:latest
|
||||
|
||||
# Push
|
||||
podman push ghcr.io/username/towerops-agent:latest
|
||||
```
|
||||
|
||||
2. **Notify users**:
|
||||
- Update release notes with issue details
|
||||
- Mark release as "yanked" or pre-release
|
||||
- Provide migration path or workaround
|
||||
|
||||
3. **Fix and re-release**:
|
||||
- Fix issues in code
|
||||
- Release as patch version (e.g., 0.1.1)
|
||||
|
||||
## Release Checklist
|
||||
|
||||
Before each release:
|
||||
|
||||
- [ ] All tests passing (`cargo test`)
|
||||
- [ ] Code formatted (`cargo fmt`)
|
||||
- [ ] No clippy warnings (`cargo clippy`)
|
||||
- [ ] Version numbers updated in Cargo.toml, CLAUDE.md
|
||||
- [ ] CHANGELOG.md updated with release notes
|
||||
- [ ] Docker images build successfully for both platforms
|
||||
- [ ] Images tested locally with sample configuration
|
||||
- [ ] Integration tests pass (if available)
|
||||
- [ ] Documentation updated
|
||||
- [ ] Git commit and tag created
|
||||
- [ ] Images pushed to registry
|
||||
- [ ] GitHub/GitLab release created with notes
|
||||
- [ ] Verify images are publicly accessible
|
||||
- [ ] Notify stakeholders of release
|
||||
|
||||
## Support
|
||||
|
||||
For issues with releases:
|
||||
- Open an issue on GitHub/GitLab
|
||||
- Check TROUBLESHOOTING.md in USER_GUIDE
|
||||
- Review logs from agent: `podman logs <container-id>`
|
||||
Loading…
Add table
Reference in a new issue