Skip to content

Latest commit

 

History

21 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

Issue-Controlled Deployment Workflow

A small GitHub Actions experiment for controlling environment promotion through a GitHub Issue.

The main idea is simple: a release is identified by a single commit SHA, automatically deployed to TEST, and then promoted through STAGE and PROD from a release issue.

Instead of selecting a new source revision for each environment, the same commit SHA is promoted forward.

Why

I wanted to experiment with a deployment flow that is:

  • easy to follow
  • auditable
  • explicit about what version is being promoted
  • reusable across environments
  • controlled without requiring a separate deployment UI

The release issue acts as both the control surface and a lightweight audit trail.

Flow

flowchart TD
    A[Push to main] --> B[Deploy commit to TEST]
    B --> C[Create release issue]

    C --> D{Promote to STAGE?}
    D -->|Checkbox selected| E[Deploy same SHA to STAGE]
    E --> F[Mark STAGE as completed]

    F --> G{Promote to PROD?}
    G -->|Checkbox selected| H[Deploy same SHA to PROD]
    H --> I[Mark PROD as completed]

    I --> J[Close release issue]
Loading

A release issue starts roughly like this:

## 🚀 Release <commit-sha>

Commit: <commit-sha>

### Promotion

- ✅ TEST
- [ ] STAGE
- 🚫 PROD

After STAGE is selected, the workflow marks it as deploying:

- ✅ TEST
- 🔁 STAGE
- 🚫 PROD

When the deployment completes successfully, STAGE is marked as done and PROD becomes available:

- ✅ TEST
- ✅ STAGE
- [ ] PROD

The issue is automatically closed after all environments have been promoted.

Workflow structure

release-on-main.yaml

Triggered by a push to main.

It:

  1. deploys the new commit to TEST
  2. creates a release issue
  3. stores the commit SHA in the release issue labels
  4. exposes STAGE as the next available promotion target

issue-promotion.yml

Triggered when the release issue is edited.

It:

  1. detects the selected environment
  2. reads the release SHA
  3. marks the environment as deploying
  4. invokes the reusable deployment workflow
  5. marks the deployment as completed
  6. unlocks the next environment
  7. closes the issue when the promotion chain is finished

deploy-reusable.yaml

Reusable deployment workflow shared by the automatic TEST deployment and manually controlled environment promotions.

Inputs:

environment:
sha:

The current repository intentionally contains only placeholder deployment logic.

In a real environment this would typically include steps such as:

Cloud authentication
        ↓
Build or retrieve artifact
        ↓
Push image
        ↓
Deploy with Helm / Kubernetes
        ↓
Health checks

Design decisions

Promote the same revision

The commit SHA is captured when the release is created and passed through the promotion workflow.

This keeps the promoted source revision explicit and consistent across TEST, STAGE and PROD.

Reusable deployment workflow

Environment-specific promotion logic calls the same deployment workflow instead of maintaining separate TEST, STAGE and PROD pipelines.

This keeps the actual deployment mechanism in one place while allowing the release orchestration to remain separate from deployment implementation.

Sequential promotion

The next environment is locked until the previous one has completed.

A typical release therefore moves through:

TEST → STAGE → PROD

rather than allowing environments to be promoted independently.

GitHub Issues as a control surface

The release issue provides a simple human-readable interface for controlling promotion without introducing a separate deployment UI.

The issue also shows:

  • which commit is being released
  • which environments have completed
  • which environment is currently deploying
  • which environment is available next

This makes the release state visible directly next to the source repository.

Separate orchestration from deployment

The issue workflow controls when and where a release is promoted.

The reusable deployment workflow controls how that version is deployed.

Keeping these responsibilities separate makes it possible to replace the placeholder deployment implementation without changing the promotion model.

Example release lifecycle

After a merge to main:

Push to main
    │
    ▼
Automatic TEST deployment
    │
    ▼
Release issue created
    │
    ▼
✅ TEST
☐ STAGE
🚫 PROD

The user selects STAGE:

✅ TEST
🔁 STAGE
🚫 PROD

After a successful deployment:

✅ TEST
✅ STAGE
☐ PROD

The user selects PROD:

✅ TEST
✅ STAGE
🔁 PROD

After PROD completes:

✅ TEST
✅ STAGE
✅ PROD

The release issue is then automatically closed.

Warning

This is an experimental proof of concept, not a production-ready deployment solution.

I built it to explore an idea: using GitHub Issues as a lightweight control surface for promoting the same release through multiple environments.

Security hardening, failure scenarios and production deployment details are intentionally out of scope.

Repository structure

.github/
└── workflows/
    ├── release-on-main.yaml
    ├── issue-promotion.yml
    └── deploy-reusable.yaml

The repository separates release orchestration from the reusable deployment workflow.

Scope

The main areas of focus are:

  • release orchestration
  • reusable workflows
  • sequential environment promotion
  • human-controlled production promotion
  • automation of release state

The deployment implementation is intentionally kept minimal so the repository can focus on the orchestration and promotion model.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors