feat: add in copy of updated shared deployment workflows for now until they are
Some checks failed
Build/Deploy / trigger-dev-build (push) Has been cancelled
Build/Deploy / trigger-staging-build (push) Has been cancelled
Build/Deploy / trigger-main-build (push) Has been cancelled

published
This commit is contained in:
badblocks 2025-08-14 15:08:23 -07:00
parent bcb7f86b7f
commit e245bcbe96
No known key found for this signature in database
12 changed files with 1113 additions and 0 deletions

240
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,240 @@
# yaml-language-server: $schema=https://json-schema.org/draft-07/schema#
name: _build
concurrency:
group: build
cancel-in-progress: false
on:
workflow_call:
jobs:
check:
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
outputs:
should-build: ${{ steps.check.outputs.should-build }}
artifact-run-id: ${{ steps.check.outputs.artifact-run-id }}
artifact-id: ${{ steps.check.outputs.artifact-id }}
build-sha: ${{ steps.check.outputs.build-sha }}
repo-name: ${{ steps.meta.outputs.repo-name }}
repo-path: ${{ steps.meta.outputs.repo-path }}
image-tar: ${{ steps.check.outputs.image-tar }}
prod: ${{ steps.meta.outputs.prod }}
tag: ${{ steps.check.outputs.tag }}
should-deploy: ${{ steps.check.outputs.should-deploy }}
steps:
- name: Checkout the repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Determine build metadata
id: meta
uses: ./.github/actions/determine-build-metadata
with:
repository: ${{ github.repository }}
github-ref: ${{ github.ref }}
- name: Check if build/deploy needed
id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
set -eu -o pipefail
SHOULD_BUILD=false
SHOULD_DEPLOY=false
SHORT_SHA="${{ github.sha }}"
SHORT_SHA="${SHORT_SHA:0:7}"
IMAGE_TAR="${{ steps.meta.outputs.repo-name }}-${{github.sha}}.tar"
VERSION="$(git tag --points-at ${{ github.sha }})"
IS_VERSION_TAGGED="$([[ "$VERSION" =~ ^v ]] && echo "true" || echo "false")"
BRANCH_NAME="$([[ "${{ github.ref }}" =~ ^refs/tags/v ]] && echo "main" || echo "${{ github.ref }}" | sed 's/refs\/heads\///')"
COMMIT_MESSAGE="$(git log --format=%s -n 1 ${{ github.sha }})"
if [[ "${{ steps.meta.outputs.prod }}" == "true" ]]; then
TAG="${{ steps.meta.outputs.repo-name }}:sha-${SHORT_SHA},${{ steps.meta.outputs.repo-name }}:latest"
else
TAG="${{ steps.meta.outputs.repo-name }}-dev:sha-${SHORT_SHA}"
fi
if [[ "$BRANCH_NAME" == "staging" ]]; then
echo "🔨 Build is on staging - will also deploy to staging"
SHOULD_DEPLOY="true"
elif [[ "$BRANCH_NAME" == "main" ]]; then
if [[ ! "$COMMIT_MESSAGE" =~ ^chore:\ Release ]] || [[ "$IS_VERSION_TAGGED" == "false" ]]; then
echo "❌ Skipping build for main: $COMMIT_MESSAGE. Not a version release. Missing tag or proper commit message for release."
exit 1
fi
echo "🏷️ Version tagged build on main: $VERSION - will also deploy to production"
SHOULD_DEPLOY="true"
fi
echo "🔍 Checking for in progress builds with git SHA ${{github.sha}}"
IN_PROGRESS_BUILDS=""
if ! IN_PROGRESS_BUILDS=$(gh api repos/${{github.repository}}/actions/runs --jq '.workflow_runs[] | select(.head_sha == "${{github.sha}}" and .status == "in_progress" and .name == "Build/Deploy" and .id != ${{ github.run_id }}) | .id' 2>/dev/null); then
echo "❌ Failed to check for in-progress builds via GitHub API"
echo "::error::GitHub API call failed while checking for in-progress builds"
exit 1
fi
IN_PROGRESS_BUILDS=$(echo "$IN_PROGRESS_BUILDS" | head -1)
if [[ -n "$IN_PROGRESS_BUILDS" ]]; then
echo "❌ Found in-progress build for SHA ${{github.sha}}: $IN_PROGRESS_BUILDS - wait for existing build to complete before triggering a new one or rerunning this workflow"
exit 1
fi
echo "🔍 Checking for existing build artifacts with git SHA ${{github.sha}}"
# Check for existing artifacts with this SHA across all workflow runs
ARTIFACT_INFO=""
if ! ARTIFACT_INFO=$(gh api repos/${{github.repository}}/actions/artifacts --jq '.artifacts[] | select(.name | endswith("-${{github.sha}}.tar")) | {id, name, workflow_run} | @json' 2>/dev/null); then
echo "❌ Failed to check for existing artifacts via GitHub API"
echo "::error::GitHub API call failed while checking for existing artifacts"
exit 1
fi
ARTIFACT_INFO=$(echo "$ARTIFACT_INFO" | head -1)
if [[ -n "$ARTIFACT_INFO" ]]; then
ARTIFACT_ID=$(echo "$ARTIFACT_INFO" | jq -r '.id')
ARTIFACT_NAME=$(echo "$ARTIFACT_INFO" | jq -r '.name')
RUN_ID=$(echo "$ARTIFACT_INFO" | jq -r '.workflow_run.id')
echo "✅ Found existing artifact $ARTIFACT_NAME from run: $RUN_ID"
echo "artifact-id=$ARTIFACT_ID" >> $GITHUB_OUTPUT
echo "artifact-id -> $ARTIFACT_ID"
else
RUN_ID="${{ github.run_id }}"
SHOULD_BUILD="true"
echo "🔨 No existing build artifact found; will build..."
fi
echo "should-build=$SHOULD_BUILD" >> $GITHUB_OUTPUT
echo "should-build -> $SHOULD_BUILD"
echo "should-deploy=$SHOULD_DEPLOY" >> $GITHUB_OUTPUT
echo "should-deploy -> $SHOULD_DEPLOY"
echo "artifact-run-id=$RUN_ID" >> $GITHUB_OUTPUT
echo "artifact-run-id -> $RUN_ID"
echo "build-sha=${{github.sha}}" >> $GITHUB_OUTPUT
echo "build-sha -> ${{github.sha}}"
echo "image-tar=$IMAGE_TAR" >> $GITHUB_OUTPUT
echo "image-tar -> $IMAGE_TAR"
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "tag -> $TAG"
build:
needs: check
if: ${{ needs.check.outputs.should-build == 'true' }}
runs-on: ubuntu-latest
outputs:
artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }}
steps:
- name: Checkout the repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Ensure scripts are executable
run: chmod +x deploy/scripts/*.sh
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Generate cache keys
id: cache-keys
run: |
# Generate cache key based on package-lock.json for dependencies
DEPS_HASH=$(sha256sum package-lock.json | cut -d' ' -f1 | cut -c1-8)
echo "deps-hash=${DEPS_HASH}" >> $GITHUB_OUTPUT
echo "deps-hash -> $DEPS_HASH"
# Generate cache key based on source files and paths
SOURCE_PATHS="app/ server/ public/ nuxt.config.ts tsconfig.json tailwind.config.js package.json"
SRC_HASH=$(find $SOURCE_PATHS -type f 2>/dev/null -exec sha256sum {} + | sha256sum | cut -d' ' -f1 | cut -c1-8 || echo "fallback-$(date +%s)")
echo "src-hash=${SRC_HASH}" >> $GITHUB_OUTPUT
echo "src-hash -> $SRC_HASH"
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-deps-${{ steps.cache-keys.outputs.deps-hash }}-src-${{ steps.cache-keys.outputs.src-hash }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-deps-${{ steps.cache-keys.outputs.deps-hash }}-src-${{ steps.cache-keys.outputs.src-hash }}-
${{ runner.os }}-buildx-deps-${{ steps.cache-keys.outputs.deps-hash }}-
${{ runner.os }}-buildx-
- name: Extract version for Docker build
id: extract_version
run: |
if [[ "${{ github.ref }}" =~ ^refs/tags/v([0-9]+\.[0-9]+\.[0-9]+)(-.*)?$ ]]; then
VERSION="${BASH_REMATCH[1]}"
if [[ -n "${BASH_REMATCH[2]}" ]]; then
VERSION="${VERSION}${BASH_REMATCH[2]}"
fi
echo "🏷️ Using git tag version: ${VERSION}"
else
VERSION=$(node -p "require('./package.json').version || '0.0.0'")
SHA="${{ github.sha }}"
GIT_SHA_SHORT="${SHA:0:7}"
VERSION="${VERSION}+${GIT_SHA_SHORT}"
echo "📦 Using package.json + SHA version: ${VERSION}"
fi
echo "VERSION=${VERSION}" >> $GITHUB_ENV
- name: Build container
uses: docker/build-push-action@v6
with:
outputs: type=docker,dest=${{ runner.temp }}/${{ needs.check.outputs.image-tar }}
tags: ${{ needs.check.outputs.tag }}
build-args: |
VERSION=${{ env.VERSION }}
context: .
target: runtime
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
platforms: linux/amd64
- name: Rotate cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Upload container as artifact
id: upload-artifact
uses: actions/upload-artifact@v4
with:
name: ${{ needs.check.outputs.image-tar }}
path: ${{ runner.temp }}/${{ needs.check.outputs.image-tar }}
if-no-files-found: error
retention-days: 30
compression-level: 0
- name: Notify successful build
run: |
echo "🎉 Build completed successfully!"
echo "📋 Summary:"
echo " - Source: ${{ github.ref }}"
echo " - Status: ✅ Build Successful"
echo " - Next: Stage this build manually or wait for the next scheduled staging."
deploy:
needs: [check, build]
if: ${{ always() && needs.check.outputs.should-deploy == 'true' }}
permissions:
actions: read
contents: read
uses: ./.github/workflows/deploy.yml
with:
artifact-run-id: ${{ needs.check.outputs.artifact-run-id }}
artifact-id: ${{ needs.check.outputs.should-build == 'true' && needs.build.outputs.artifact-id || needs.check.outputs.artifact-id }}
build-sha: ${{ needs.check.outputs.build-sha }}
repo-name: ${{ needs.check.outputs.repo-name }}
repo-path: ${{ needs.check.outputs.repo-path }}
image-tar: ${{ needs.check.outputs.image-tar }}
prod: ${{ needs.check.outputs.prod == 'true' }}
tag: ${{ needs.check.outputs.tag }}
secrets: inherit

159
.github/workflows/deploy.yml vendored Normal file
View file

@ -0,0 +1,159 @@
# yaml-language-server: $schema=https://json-schema.org/draft-07/schema#
name: _deploy
concurrency:
group: deploy
cancel-in-progress: false
on:
workflow_call:
inputs:
tag:
description: "Tag to deploy"
required: true
type: string
prod:
description: "Whether to deploy to production"
required: true
type: boolean
image-tar:
description: "Name of image tarball"
required: true
type: string
artifact-run-id:
description: "ID of workflow run where artifact was created"
required: true
type: string
artifact-id:
description: "ID of artifact"
required: true
type: string
build-sha:
description: "SHA of build"
required: true
type: string
repo-name:
description: "Name of repository"
required: true
type: string
repo-path:
description: "Path to repository on server"
required: true
type: string
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.prod && 'production' || 'staging' }}
env:
RELEASE_TYPE: ${{ inputs.prod && 'prod' || 'staging' }}
permissions:
actions: read
contents: read
steps:
- name: Checkout the repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Ensure scripts are executable
run: chmod +x deploy/scripts/*.sh
- name: Setup environment configuration
uses: ./.github/actions/setup-environment
with:
release-type: ${{ inputs.prod && 'prod' || 'staging' }}
domain: ${{ secrets.DOMAIN }}
android-sms-gateway-url: ${{ secrets.NUXT_ANDROID_SMS_GATEWAY_URL }}
android-sms-gateway-login: ${{ secrets.NUXT_ANDROID_SMS_GATEWAY_LOGIN }}
android-sms-gateway-password: ${{ secrets.NUXT_ANDROID_SMS_GATEWAY_PASSWORD }}
my-phone-number: ${{ secrets.NUXT_MY_PHONE_NUMBER }}
super-secret-salt: ${{ secrets.NUXT_SUPER_SECRET_SALT }}
wireguard-allowed-ips: ${{ secrets.WIREGUARD_ALLOWED_IPS }}
wireguard-private-key: ${{ secrets.WIREGUARD_PRIVATE_KEY }}
wireguard-addresses: ${{ secrets.WIREGUARD_ADDRESSES }}
wireguard-public-key: ${{ secrets.WIREGUARD_PUBLIC_KEY }}
wireguard-endpoint-host: ${{ secrets.WIREGUARD_ENDPOINT_HOST }}
wireguard-endpoint-port: ${{ secrets.WIREGUARD_ENDPOINT_PORT }}
prod: ${{ inputs.prod }}
- name: Set up SSH
run: |
mkdir -p $HOME/.ssh
echo -e "${{ secrets.DEPLOY_KEY }}" > $HOME/.ssh/deploy.key
chmod 700 $HOME/.ssh
chmod 600 $HOME/.ssh/deploy.key
cat >>$HOME/.ssh/config <<END
Host deploy
HostName ${{ secrets.DEPLOY_HOST }}
Port ${{ secrets.DEPLOY_PORT }}
User ${{ secrets.DEPLOY_USER }}
IdentityFile $HOME/.ssh/deploy.key
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
ControlMaster auto
ControlPath $HOME/.ssh/control-%C
ControlPersist yes
LogLevel QUIET
ConnectionAttempts 3
ConnectTimeout 10
ServerAliveInterval 10
END
- name: Download container image artifact
id: download-artifact
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}
github-token: ${{ github.token }}
artifact-ids: ${{ inputs.artifact-id }}
run-id: ${{ inputs.artifact-run-id }}
- name: Configure HAProxy
env:
DOCKER_HOST: ssh://deploy
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DOMAIN: ${{ secrets.DOMAIN }}
BACKEND_NAME: ${{ inputs.repo-name }}-${{ env.RELEASE_TYPE }}
CF_PEM_CERT: ${{ secrets.CF_PEM_CERT }}
CF_PEM_CA: ${{ secrets.CF_PEM_CA }}
run: |
echo "✅ Exit on any error"
set -eu -o pipefail
echo "🔄 Load environment variables"
set -a
source .env
set +a
echo "🎯 Running HAProxy configuration script"
./deploy/scripts/configure-haproxy.sh add "$BACKEND_NAME"
- name: Deploy to Server
env:
IMAGE_TAR: ${{ steps.download-artifact.outputs.download-path }}/${{ inputs.image-tar }}/${{ inputs.image-tar }}
REPO_PROJECT_PATH: ${{ inputs.repo-path }}
IMAGE_TAG: ${{ inputs.tag }}
GIT_SHA: ${{ inputs.build-sha }}
DOCKER_HOST: ssh://deploy
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
run: |
echo "✅ Exit on any error"
set -eu -o pipefail
echo "🔄 Load environment variables"
set -a
source .env
set +a
echo "🎯 Running deployment script"
./deploy/scripts/deploy-blue-green.sh
- name: Notify successful deployment
run: |
echo "🎉 Deployment completed successfully!"
echo "📋 Summary:"
echo " - Source: ${{ inputs.prod && 'main (production)' || 'staging' }} branch"
echo " - Status: ✅ Deployed Successfully"
echo " - Next: Verify deployment status!"

162
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,162 @@
name: _release
#TODO test without these
permissions:
actions: read
contents: write
issues: write
pull-requests: write
concurrency:
group: release
cancel-in-progress: false
on:
workflow_call:
inputs:
force_release:
description: "Force release even if validation fails"
required: false
default: false
type: boolean
jobs:
validate-staging-build:
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.validation.outputs.should-proceed }}
steps:
- name: Checkout staging
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: staging
- name: Validate staging build status
id: validation
uses: ./.github/actions/validate-build-status
with:
job-name: trigger-staging-build / build
from-branch: staging
to-branch: main
force: ${{ inputs.force_release }}
generate-release-and-push-all:
needs: validate-staging-build
runs-on: ubuntu-latest
if: ${{ inputs.force_release == true || needs.validate-staging-build.outputs.should_release == 'true' }}
outputs:
skip-release: ${{steps.semantic-release.outputs.skip-release }}
steps:
- name: Checkout staging
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: staging
- name: Setup Git SSH for commit signing and push operations
uses: ./.github/actions/setup-git-ssh
with:
commit-ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
push-ssh-private-key: ${{ secrets.PUSH_SSH_PRIVATE_KEY }}
actor: ${{ github.actor }}
actor-id: ${{ github.actor_id }}
- name: Set git origin to GIT_ORIGIN_REPO_URL
run: |
GIT_ORIGIN_URL="${{ secrets.GIT_ORIGIN_REPO_URL }}"
if [ -n "$GIT_ORIGIN_URL" ]; then
git remote remove origin
if git remote add -f --tags origin "$GIT_ORIGIN_URL"; then
echo "✅ Git origin configured correctly"
else
echo "❌ Failed to configure Git origin"
echo "::error::Failed to configure Git origin"
exit 1
fi
else
echo "❌ No Git origin URL configured - cannot proceed without origin URL"
echo "::error::GIT_ORIGIN_REPO_URL secret is required but not configured"
exit 1
fi
- name: Merge staging commits to main
run: |
echo "🔄 Merging staging commits to main..."
git checkout main
STAGING_COMMITS=$(git log --oneline main..staging --pretty=format:"* %s")
if [ -z "$STAGING_COMMITS" ]; then
if [[ "${{inputs.force_release}}" == "true" ]]; then
echo "⚠️ No new commits in staging to merge, but force release is enabled"
echo "::warning::No commits to merge from staging to main"
exit 0
else
echo "❌ No new commits in staging to merge"
echo "::error::No commits to merge from staging to main"
exit 1
fi
else
echo "📋 Commits to be merged:"
echo "$STAGING_COMMITS"
if git merge staging -X theirs -m "chore: merge staging changes for next release"; then
echo "✅ Staging commits merged to main successfully"
else
echo "⚠️ Merge conflicts detected - resolving with staging preference..."
git checkout staging -- .
if [ -f CHANGELOG.md ]; then
git checkout HEAD -- CHANGELOG.md
echo "📋 Kept main's CHANGELOG.md (managed by semantic-release)"
fi
git add -A
git commit -m "chore: merge staging changes for next release"
echo "✅ Conflicts resolved - staging files preferred, main's CHANGELOG.md kept"
fi
fi
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- name: Install semantic-release
run: npm install semantic-release
- name: Run semantic-release on main, generate release, and push
id: semantic-release
env:
GITHUB_TOKEN: "${{ github.token }}" # used for release generation
GIT_AUTHOR_NAME: "${{ github.actor }}"
GIT_AUTHOR_EMAIL: "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
GIT_COMMITTER_NAME: "${{ github.actor }}"
GIT_COMMITTER_EMAIL: "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
run: |
echo "🚀 Running semantic-release on main branch..."
npx semantic-release
if git log main -1 --format="%s" | grep -q "^chore: Release"; then
echo "✅ Semantic-release completed and pushed to origin/main"
echo "skip-release=false" >> $GITHUB_OUTPUT
else
echo "❌ Semantic-release did not generate a release, exiting."
echo "skip-release=true" >> $GITHUB_OUTPUT
[[ "${{ inputs.force_release }}" == "true" ]] && exit 1
fi
- name: Notify successful release
if: ${{ steps.semantic-release.outputs.skip-release != 'true' }}
run: |
echo "🎉 Production release completed successfully!"
echo "📋 Summary:"
echo " - Source: staging branch commits (regular merged)"
echo " - Target: main branch (semantic-release)"
echo " - Semantic-release: ✅ Complete on main"
echo " - staging branch: Maintains independent history"
echo " - dev branch: Maintains independent history"
echo " - Tags: ✅ Created and pushed"
echo " - GitHub & Git Origin: ✅ Main branch synchronized"
echo " - Status: 🚀 Ready to build and deploy!"

37
.github/workflows/scheduler-release.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: Release
permissions:
actions: read
contents: write
issues: write
pull-requests: write
on:
schedule:
# Run weekly on Mondays 12:00 UTC/04:00 PST (UTC-08)
- cron: "0 12 * * 1"
workflow_dispatch:
inputs:
force_release:
description: "Force release even if validation fails"
required: false
default: false
type: boolean
note_for_dispatch:
description: "Note: This workflow will always call release.yml@staging, but it MUST BE RUN FROM THE MAIN BRANCH to ensure environment consistency."
required: false
default: false
type: boolean
jobs:
call-release-workflow:
permissions:
actions: read
contents: write
issues: write
pull-requests: write
uses: badbl0cks/portfolio/.github/workflows/release.yml@staging
if: github.ref == 'refs/heads/main'
with:
force_release: ${{ inputs.force_release || false }}
secrets: inherit

33
.github/workflows/scheduler-stage.yml vendored Normal file
View file

@ -0,0 +1,33 @@
name: Stage
permissions:
actions: read
contents: write
on:
schedule:
# Run daily Monday-Friday at 13:00 UTC/05:00 PST (UTC-08)
- cron: "0 13 * * 1-5"
workflow_dispatch:
inputs:
force_staging:
description: "Force staging even if validation fails"
required: false
default: false
type: boolean
note_for_dispatch:
description: "Note: This workflow will always call stage.yml@dev, but it MUST BE RUN FROM THE MAIN BRANCH to ensure environment consistency."
required: false
default: false
type: boolean
jobs:
call-staging-workflow:
permissions:
actions: read
contents: write
uses: badbl0cks/portfolio/.github/workflows/stage.yml@dev
if: github.ref == 'refs/heads/main'
with:
force_staging: ${{ inputs.force_staging || false }}
secrets: inherit

80
.github/workflows/stage.yml vendored Normal file
View file

@ -0,0 +1,80 @@
name: _stage
permissions:
actions: read
contents: write
concurrency:
group: stage
cancel-in-progress: false
on:
workflow_call:
inputs:
force_staging:
description: "Force staging even if validation fails"
required: false
default: false
type: boolean
jobs:
validate-dev-build:
runs-on: ubuntu-latest
outputs:
should_stage: ${{ steps.validation.outputs.should-proceed }}
steps:
- name: Checkout dev
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: dev
- name: Validate dev build status
id: validation
uses: ./.github/actions/validate-build-status
with:
job-name: trigger-dev-build / build
from-branch: dev
to-branch: staging
force: ${{ inputs.force_staging }}
push-to-staging:
needs: validate-dev-build
runs-on: ubuntu-latest
if: ${{ inputs.force_staging == true || needs.validate-dev-build.outputs.should_stage == 'true' }}
steps:
- name: Checkout dev
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: dev
- name: Setup Git SSH for push operations
uses: ./.github/actions/setup-git-ssh
with:
push-ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
actor: ${{ github.actor }}
actor-id: ${{ github.actor_id }}
- name: Reset staging branch to refs/heads/dev
run: |
echo "🚀 Resetting staging branch..."
git checkout staging
git reset --hard dev
echo "✅ Staging branch reset to refs/heads/dev"
- name: Push to git origin
uses: ./.github/actions/push-to-origin
with:
git-origin-url: ${{ secrets.GIT_ORIGIN_REPO_URL }}
branches: staging
force: true
- name: Notify successful staging
run: |
echo "🎉 Staging completed successfully!"
echo "📋 Summary:"
echo " - Source: dev branch"
echo " - Status: ✅ Pushed to staging"
echo " - Next: Perform staging and integration tests. If satisfactory, manually dispatch the staging-to-main workflow to generate a production release, which will then trigger a production build and deployment."

30
.github/workflows/trigger-build.yml vendored Normal file
View file

@ -0,0 +1,30 @@
# yaml-language-server: $schema=https://json-schema.org/draft-07/schema#
name: Build/Deploy
on:
workflow_dispatch:
push:
branches: [dev, staging, main]
jobs:
trigger-dev-build:
permissions:
actions: read
contents: read
if: ${{ github.ref == 'refs/heads/dev' }}
uses: badbl0cks/portfolio/.github/workflows/build.yml@dev
secrets: inherit
trigger-staging-build:
permissions:
actions: read
contents: read
if: ${{ github.ref == 'refs/heads/staging' }}
uses: badbl0cks/portfolio/.github/workflows/build.yml@staging
secrets: inherit
trigger-main-build:
permissions:
actions: read
contents: read
if: ${{ github.ref == 'refs/heads/main' }}
uses: badbl0cks/portfolio/.github/workflows/build.yml@main
secrets: inherit