Add CI workflows for dual-image channel pattern
- Non-prod workflow: builds on push to main, pushes to acme-nonprod registry, creates Octopus release in Non-Prod channel - Prod workflow: builds on v* tags, pushes to acme-prod registry, creates Octopus release in Prod channel - Simple Alpine Dockerfile for demo purposes
This commit is contained in:
62
.gitea/workflows/build-nonprod.yml
Normal file
62
.gitea/workflows/build-nonprod.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Build Non-Prod Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
env:
|
||||
REGISTRY: gitea.oreillyit.nz
|
||||
IMAGE: acme-nonprod/demo-app
|
||||
OCTOPUS_SERVER: https://taniwha.octopus.app
|
||||
OCTOPUS_SPACE_ID: Spaces-102
|
||||
OCTOPUS_PROJECT_ID: Projects-101
|
||||
OCTOPUS_CHANNEL_ID: Channels-124
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Generate version
|
||||
id: version
|
||||
run: echo "sha=sha-${GITHUB_SHA::8}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Login to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
run: |
|
||||
docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.version.outputs.sha }} .
|
||||
docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.version.outputs.sha }}
|
||||
|
||||
- name: Create Octopus Release
|
||||
run: |
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
|
||||
-H "X-Octopus-ApiKey: ${{ secrets.OCTOPUS_API_KEY }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${{ env.OCTOPUS_SERVER }}/api/${{ env.OCTOPUS_SPACE_ID }}/releases" \
|
||||
-d '{
|
||||
"ProjectId": "${{ env.OCTOPUS_PROJECT_ID }}",
|
||||
"ChannelId": "${{ env.OCTOPUS_CHANNEL_ID }}",
|
||||
"Version": "${{ steps.version.outputs.sha }}",
|
||||
"SelectedPackages": [
|
||||
{
|
||||
"ActionName": "Deploy Non-Prod Image",
|
||||
"PackageReferenceName": "demo-app",
|
||||
"Version": "${{ steps.version.outputs.sha }}"
|
||||
}
|
||||
]
|
||||
}')
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||||
BODY=$(echo "$RESPONSE" | sed '$d')
|
||||
echo "Response: $BODY"
|
||||
if [ "$HTTP_CODE" -ge 400 ]; then
|
||||
echo "::error::Failed to create release (HTTP $HTTP_CODE)"
|
||||
exit 1
|
||||
fi
|
||||
echo "Release created successfully"
|
||||
62
.gitea/workflows/build-prod.yml
Normal file
62
.gitea/workflows/build-prod.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Build Prod Image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ['v*']
|
||||
|
||||
env:
|
||||
REGISTRY: gitea.oreillyit.nz
|
||||
IMAGE: acme-prod/demo-app
|
||||
OCTOPUS_SERVER: https://taniwha.octopus.app
|
||||
OCTOPUS_SPACE_ID: Spaces-102
|
||||
OCTOPUS_PROJECT_ID: Projects-101
|
||||
OCTOPUS_CHANNEL_ID: Channels-125
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Generate version
|
||||
id: version
|
||||
run: echo "sha=sha-${GITHUB_SHA::8}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Login to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
run: |
|
||||
docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.version.outputs.sha }} .
|
||||
docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ steps.version.outputs.sha }}
|
||||
|
||||
- name: Create Octopus Release
|
||||
run: |
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
|
||||
-H "X-Octopus-ApiKey: ${{ secrets.OCTOPUS_API_KEY }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${{ env.OCTOPUS_SERVER }}/api/${{ env.OCTOPUS_SPACE_ID }}/releases" \
|
||||
-d '{
|
||||
"ProjectId": "${{ env.OCTOPUS_PROJECT_ID }}",
|
||||
"ChannelId": "${{ env.OCTOPUS_CHANNEL_ID }}",
|
||||
"Version": "prod-${{ steps.version.outputs.sha }}",
|
||||
"SelectedPackages": [
|
||||
{
|
||||
"ActionName": "Deploy Prod Image",
|
||||
"PackageReferenceName": "demo-app",
|
||||
"Version": "${{ steps.version.outputs.sha }}"
|
||||
}
|
||||
]
|
||||
}')
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||||
BODY=$(echo "$RESPONSE" | sed '$d')
|
||||
echo "Response: $BODY"
|
||||
if [ "$HTTP_CODE" -ge 400 ]; then
|
||||
echo "::error::Failed to create release (HTTP $HTTP_CODE)"
|
||||
exit 1
|
||||
fi
|
||||
echo "Release created successfully"
|
||||
3
Dockerfile
Normal file
3
Dockerfile
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM alpine:3.21
|
||||
LABEL org.opencontainers.image.source="https://gitea.oreillyit.nz/octopus.oreillyit.nz/demo-app"
|
||||
CMD ["echo", "Hello from demo-app"]
|
||||
17
README.md
17
README.md
@@ -1,3 +1,16 @@
|
||||
# demo-app
|
||||
# Demo App — Dual Image Channel Pattern
|
||||
|
||||
Demo app for dual-image channel pattern
|
||||
Demonstrates Octopus Deploy's channel pattern for routing non-prod and prod container images through separate lifecycles.
|
||||
|
||||
## How it works
|
||||
|
||||
- **Push to `main`** → builds non-prod image → pushes to `acme-nonprod/demo-app` → creates Octopus release in Non-Prod channel
|
||||
- **Push a `v*` tag** → builds prod image → pushes to `acme-prod/demo-app` → creates Octopus release in Prod channel
|
||||
|
||||
Each channel has its own lifecycle:
|
||||
- Non-Prod: Development → Staging (cannot reach Production)
|
||||
- Prod: Staging → Production
|
||||
|
||||
## Octopus Space
|
||||
|
||||
https://taniwha.octopus.app/app#/Spaces-102
|
||||
|
||||
Reference in New Issue
Block a user