Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 45 additions & 7 deletions .github/workflows/prod-server-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,62 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Parse deployment target from release
id: deployment_target
run: |
# Extract deployment target from release body or use current commit
RELEASE_BODY="${{ github.event.release.body }}"
TARGET_COMMIT="${{ github.sha }}"
TARGET_TAG=""

# Look for deployment target in release body
# Format: deploy-target: <commit-hash|tag|branch>
if echo "$RELEASE_BODY" | grep -i "deploy-target:"; then
TARGET_REF=$(echo "$RELEASE_BODY" | grep -i "deploy-target:" | head -1 | sed -E 's/.*[Dd][Ee][Pp][Ll][Oo][Yy]-[Tt][Aa][Rr][Gg][Ee][Tt]:[[:space:]]*//' | awk '{print $1}')
echo "Found deployment target: $TARGET_REF"

# Check if it's a valid commit/tag/branch
if git cat-file -e "$TARGET_REF" 2>/dev/null; then
TARGET_COMMIT=$(git rev-parse "$TARGET_REF")
if git tag --list | grep -q "^${TARGET_REF}$"; then
TARGET_TAG="$TARGET_REF"
fi
echo "Resolved target to commit: $TARGET_COMMIT"
else
echo "Invalid deployment target '$TARGET_REF', using current commit"
fi
else
echo "No deployment target specified, using current commit"
fi

echo "deploy_commit=$TARGET_COMMIT" >> $GITHUB_OUTPUT
echo "deploy_tag=$TARGET_TAG" >> $GITHUB_OUTPUT
echo "Using deployment commit: $TARGET_COMMIT"

- name: Checkout deployment target
if: steps.deployment_target.outputs.deploy_commit != github.sha
uses: actions/checkout@v4
with:
ref: ${{ steps.deployment_target.outputs.deploy_commit }}

- name: Build action runner
run: docker build -t "wgd-action-runner:prod" --build-arg "GIT_SHA=${GITHUB_SHA}" apps/wgd-action-runner
run: docker build -t "wgd-action-runner:prod" --build-arg "GIT_SHA=${{ steps.deployment_target.outputs.deploy_commit }}" apps/wgd-action-runner

- uses: docker/build-push-action@v6
with:
tags: "wikigdrive-prod:${{ github.sha }},wikigdrive-prod:latest"
tags: "wikigdrive-prod:${{ steps.deployment_target.outputs.deploy_commit }},wikigdrive-prod:latest"
push: false
build-args: |
GIT_SHA=${{ github.sha }}
GIT_SHA=${{ steps.deployment_target.outputs.deploy_commit }}
BUILD_UI=yes

- name: Build docs
run: |
docker run \
-v "/var/www/wikigdrive.com:/usr/src/app/website/.vitepress/dist" \
-e "GIT_SHA=${{ github.sha }}" \
"wikigdrive-prod:${{ github.sha }}" deno task -f wikigdrive-website build
-e "GIT_SHA=${{ steps.deployment_target.outputs.deploy_commit }}" \
"wikigdrive-prod:${{ steps.deployment_target.outputs.deploy_commit }}" deno task -f wikigdrive-website build

- name: Stop and remove
run: docker stop wikigdrive-prod ; docker rm wikigdrive-prod
Expand All @@ -69,10 +107,10 @@ jobs:
-v "/var/www/preview-prod:/var/www/preview-prod" \
-v "/srv/overlay_mounts:/srv/overlay_mounts" \
-e "DOMAIN=https://wikigdrive.com" \
-e "GIT_SHA=${GITHUB_SHA}" \
-e "GIT_SHA=${{ steps.deployment_target.outputs.deploy_commit }}" \
--publish 127.0.0.1:3000:3000 \
--restart unless-stopped \
"wikigdrive-prod:${GITHUB_SHA}" wikigdrive \
"wikigdrive-prod:${{ steps.deployment_target.outputs.deploy_commit }}" wikigdrive \
--service_account /service_account.json \
--share_email [email protected] \
--workdir /data \
Expand Down
8 changes: 8 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Documentation

This directory contains additional documentation for WikiGDrive development and operations.

## Files

- [deployment-control.md](deployment-control.md) - Guide for release-based deployment control
- [deployment-examples.md](deployment-examples.md) - Example release descriptions for deployment control
117 changes: 117 additions & 0 deletions docs/deployment-control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Release-based Deployment Control

This document describes how to control which version of the code is deployed to production using the GitHub release system.

## Overview

The production deployment system now supports deploying specific versions of the code without needing to reset the master branch. This is accomplished by specifying a deployment target in the release description.

## How it Works

When you create a GitHub release, the production deployment workflow will:

1. Check the release description for a deployment target specification
2. If found, checkout and deploy that specific commit/tag/branch
3. If not found, deploy the current commit (default behavior)

## Specifying a Deployment Target

To deploy a specific version, include the following line in your release description:

```
deploy-target: <commit-hash|tag|branch>
```

### Examples

**Deploy a specific commit:**
```
deploy-target: a1b2c3d4e5f6
```

**Deploy a specific tag:**
```
deploy-target: v2.15.14
```

**Deploy a specific branch:**
```
deploy-target: hotfix/security-patch
```

## Use Cases

### Rollback to Previous Version

To rollback to a previous release:

1. Create a new release with the title "Rollback to v2.15.14"
2. In the release description, add:
```
deploy-target: v2.15.14

Rolling back production to stable version due to issues with latest release.
```
3. Publish the release

### Deploy a Hotfix

To deploy a hotfix branch without merging to master:

1. Create a hotfix branch: `git checkout -b hotfix/critical-fix`
2. Make your changes and push the branch
3. Create a new release with the title "Hotfix: Critical Security Patch"
4. In the release description, add:
```
deploy-target: hotfix/critical-fix

Emergency deployment of security patch.
```
5. Publish the release

### Deploy for Testing

To deploy a specific commit for testing:

1. Find the commit hash you want to deploy
2. Create a new release with the title "Testing Deploy"
3. In the release description, add:
```
deploy-target: abc123def456

Deploying specific commit for testing purposes.
```
4. Publish the release

## Benefits

- **Safe Rollbacks**: Easily rollback to any previous version without touching master
- **Hotfix Deployment**: Deploy critical fixes without waiting for full merge cycle
- **Testing Flexibility**: Deploy specific versions for testing without disrupting development
- **Audit Trail**: All deployments are tracked through GitHub releases
- **No Master Branch Risk**: Never need to reset or force-push master branch

## Validation

The deployment workflow validates that the specified target exists before attempting deployment. If an invalid target is specified, the deployment will fall back to using the current commit and log a warning.

## Monitoring

You can verify which version is currently deployed by:

1. Checking the Docker container tags in production
2. Looking at the `GIT_SHA` environment variable in the running container
3. Reviewing the deployment logs in GitHub Actions

## Migration from Manual Process

Previously, deploying specific versions required:

1. Resetting master to the target commit
2. Creating a release from that reset
3. Resetting master back to its original state

With this new system, you simply:

1. Create a release with the deployment target specified
2. The system handles checkout and deployment automatically
104 changes: 104 additions & 0 deletions docs/deployment-examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Example Release Descriptions

This file provides examples of how to use the deployment control feature in GitHub releases.

## Example 1: Deploy Specific Tag (Rollback)

**Release Title:** Rollback to v2.15.14

**Release Description:**
```
deploy-target: v2.15.14

Rolling back production to stable version v2.15.14 due to critical issues discovered in v2.15.15.

This deployment will:
- Restore the stable codebase
- Fix the authentication issues reported in production
- Maintain data integrity

Once deployed, we will investigate the issues in v2.15.15 before the next release.
```

## Example 2: Deploy Hotfix Branch

**Release Title:** Emergency Security Patch

**Release Description:**
```
deploy-target: hotfix/security-cve-2024-001

Emergency deployment of security patch for CVE-2024-001.

This hotfix addresses:
- SQL injection vulnerability in user authentication
- Cross-site scripting vulnerability in file upload
- Privilege escalation in admin dashboard

The fix has been tested in staging and is ready for immediate production deployment.
```

## Example 3: Deploy Specific Commit

**Release Title:** Deploy Tested Build

**Release Description:**
```
deploy-target: a1b2c3d4e5f6789012345678901234567890abcd

Deploying specific commit that has been thoroughly tested in staging environment.

This commit includes:
- Performance improvements for large file processing
- Bug fixes for Google Drive synchronization
- UI improvements for mobile devices

Testing completed:
- ✅ Unit tests: 100% pass
- ✅ Integration tests: 100% pass
- ✅ Performance tests: Within acceptable limits
- ✅ Security scan: No vulnerabilities found
```

## Example 4: Regular Release (No Deploy Target)

**Release Title:** WikiGDrive v2.16.0

**Release Description:**
```
New features and improvements in this release:

- Added support for collaborative editing
- Improved markdown rendering performance
- Enhanced file synchronization reliability
- New authentication options

Full changelog: https://github.com/mieweb/wikiGDrive/compare/v2.15.14...v2.16.0

This release will deploy the current codebase automatically.
```

## Example 5: Deploy Feature Branch for Testing

**Release Title:** Testing New File Processor

**Release Description:**
```
deploy-target: feature/new-file-processor

Deploying feature branch for production testing of the new file processing engine.

⚠️ This is a testing deployment and may be unstable.

Changes in this branch:
- Rewritten file processing pipeline
- Improved error handling and recovery
- Better memory management for large files

Monitoring required:
- Watch for memory usage spikes
- Monitor file processing times
- Check error logs for any issues

Plan to rollback if issues are detected within 2 hours.
```
49 changes: 49 additions & 0 deletions test/test_deployment_parsing.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

# Test script for deployment target parsing
# This simulates the logic used in the GitHub Actions workflow

test_deployment_target_parsing() {
local release_body="$1"
local expected_target="$2"
local test_name="$3"

echo "Testing: $test_name"
echo "Release body: $release_body"

# Simulate the parsing logic
if echo "$release_body" | grep -i "deploy-target:"; then
target_ref=$(echo "$release_body" | grep -i "deploy-target:" | head -1 | sed -E 's/.*[Dd][Ee][Pp][Ll][Oo][Yy]-[Tt][Aa][Rr][Gg][Ee][Tt]:[[:space:]]*//' | awk '{print $1}')
echo "Found deployment target: $target_ref"
if [ "$target_ref" = "$expected_target" ]; then
echo "✅ PASS: Correctly parsed target '$target_ref'"
else
echo "❌ FAIL: Expected '$expected_target', got '$target_ref'"
fi
else
if [ "$expected_target" = "" ]; then
echo "✅ PASS: No deployment target found (as expected)"
else
echo "❌ FAIL: Expected target '$expected_target' but found none"
fi
fi
echo ""
}

# Test cases
test_deployment_target_parsing "deploy-target: v2.15.14" "v2.15.14" "Simple tag deployment"

test_deployment_target_parsing "Emergency fix

deploy-target: hotfix/security-patch

This deploys a critical security fix." "hotfix/security-patch" "Deployment target in multiline description"

test_deployment_target_parsing "Deploy-Target: a1b2c3d4e5f6" "a1b2c3d4e5f6" "Case insensitive matching"

test_deployment_target_parsing "Regular release without deployment target" "" "No deployment target specified"

test_deployment_target_parsing "deploy-target: main
Additional text here" "main" "Target with additional content"

echo "All deployment target parsing tests completed."
6 changes: 6 additions & 0 deletions website/docs/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ curl -fsSL https://deno.land/install.sh | DENO_INSTALL=/usr/local sh
## Version Strategy
* We use labels to set the version number based on https://github.com/marketplace/actions/create-tag-release
* See background info: https://github.com/mieweb/wikiGDrive/issues/297

## Deployment Control
* Production deployments support release-based version control
* You can deploy specific commits, tags, or branches without resetting master
* See [deployment-control.md](../../docs/deployment-control.md) for detailed instructions
* Specify deployment targets in release descriptions using: `deploy-target: <commit-hash|tag|branch>`


## Install locally
Expand Down