Update README.md #99
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Deploy | |
on: | |
push: | |
tags: | |
- '*.*.*' # Triggers on version tags like 1.0.0, 2.1.3, etc. | |
workflow_dispatch: | |
inputs: | |
version: | |
description: 'Version to deploy (e.g., 1.0.0)' | |
required: true | |
default: '1.0.0' | |
env: | |
DOCKER_REGISTRY: ghcr.io | |
IMAGE_NAME: safeturned/api | |
jobs: | |
deploy: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
packages: write | |
steps: | |
- name: Determine version | |
id: version | |
run: | | |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
VERSION="${{ github.event.inputs.version }}" | |
else | |
VERSION=${GITHUB_REF#refs/tags/} | |
fi | |
if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "❌ Invalid SemVer format: $VERSION" | |
exit 1 | |
fi | |
MAJOR=$(echo $VERSION | cut -d. -f1) | |
MINOR=$(echo $VERSION | cut -d. -f2) | |
PATCH=$(echo $VERSION | cut -d. -f3) | |
echo "version=$VERSION" >> $GITHUB_OUTPUT | |
echo "major=$MAJOR" >> $GITHUB_OUTPUT | |
echo "minor=$MINOR" >> $GITHUB_OUTPUT | |
echo "patch=$PATCH" >> $GITHUB_OUTPUT | |
echo "full_version=$VERSION" >> $GITHUB_OUTPUT | |
- name: Determine branch and environment | |
id: branch | |
run: | | |
if [ "${{ github.ref }}" = "refs/heads/master" ] || [ "${{ github.ref }}" = "refs/heads/master" ]; then | |
echo "branch=master" >> $GITHUB_OUTPUT | |
echo "environment=production" >> $GITHUB_OUTPUT | |
elif [ "${{ github.ref }}" = "refs/heads/dev" ]; then | |
echo "branch=dev" >> $GITHUB_OUTPUT | |
echo "environment=development" >> $GITHUB_OUTPUT | |
else | |
echo "branch=master" >> $GITHUB_OUTPUT | |
echo "environment=production" >> $GITHUB_OUTPUT | |
fi | |
- name: Checkout code with submodules | |
uses: actions/checkout@v5 | |
with: | |
submodules: recursive | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Force initialize submodule | |
run: | | |
echo "=== Force initializing FileChecker submodule ===" | |
git submodule add --force https://github.com/Safeturned/FileChecker.git FileChecker || true | |
git submodule update --init --recursive | |
echo "=== Checking submodule status ===" | |
git submodule status | |
echo "=== FileChecker directory contents ===" | |
ls -la FileChecker/ | |
echo "=== FileChecker/src directory contents ===" | |
ls -la FileChecker/src/ | |
- name: Setup .NET | |
uses: actions/setup-dotnet@v4 | |
env: | |
DOTNET_NOLOGO: true | |
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true | |
DOTNET_CLI_TELEMETRY_OPTOUT: true | |
with: | |
dotnet-version: 9.* | |
- name: Setup Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Install Aspire CLI | |
run: dotnet tool install --global Aspire.Cli | |
- name: Publish with Aspire | |
run: | | |
aspire publish -o ./publish/aspire | |
- name: Login to GHCR | |
run: | | |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin | |
- name: Find and tag Docker image | |
run: | | |
VERSION="${{ steps.version.outputs.version }}" | |
BRANCH="${{ steps.branch.outputs.branch }}" | |
# Look for the built image with various possible names | |
BUILT_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "(safeturned-api|safeturned-api)" | head -n 1) | |
if [ -z "$BUILT_IMAGE" ]; then | |
# Try to find any image with safeturned in the name | |
BUILT_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep safeturned | head -n 1) | |
fi | |
if [ -z "$BUILT_IMAGE" ]; then | |
# List all images for debugging | |
echo "Available Docker images:" | |
docker images | |
echo "❌ No built image found" | |
exit 1 | |
fi | |
echo "Found built image: $BUILT_IMAGE" | |
# Tag for GHCR with version and branch | |
docker tag "$BUILT_IMAGE" "ghcr.io/safeturned/api:v${VERSION}" | |
docker tag "$BUILT_IMAGE" "ghcr.io/safeturned/api:${BRANCH}" | |
echo "✅ Image tagged successfully" | |
- name: Push Docker image | |
run: | | |
VERSION="${{ steps.version.outputs.version }}" | |
BRANCH="${{ steps.branch.outputs.branch }}" | |
# Push both version and branch tags | |
docker push "ghcr.io/safeturned/api:v${VERSION}" | |
docker push "ghcr.io/safeturned/api:${BRANCH}" | |
echo "✅ Images pushed successfully" | |
- name: Create deployment package | |
run: | | |
VERSION="${{ steps.version.outputs.version }}" | |
BRANCH="${{ steps.branch.outputs.branch }}" | |
ENVIRONMENT="${{ steps.branch.outputs.environment }}" | |
mkdir -p ./deploy | |
cp ./publish/aspire/docker-compose.yaml ./deploy/ | |
cp ./publish/aspire/.env ./deploy/ 2>/dev/null || true | |
cat > ./deploy/deploy.sh << 'EOF' | |
#!/bin/bash | |
set -e | |
VERSION="$1" | |
BRANCH="$2" | |
ENVIRONMENT="$3" | |
if [ -z "$VERSION" ] || [ -z "$BRANCH" ] || [ -z "$ENVIRONMENT" ]; then | |
echo "Usage: $0 <version> <branch> <environment>" | |
exit 1 | |
fi | |
echo "Deploying version: $VERSION, branch: $BRANCH, environment: $ENVIRONMENT" | |
docker compose down || true | |
echo "Pulling image from registry..." | |
docker pull ghcr.io/safeturned/api:v${VERSION} || echo "Image pull failed, will build locally" | |
docker compose up -d | |
echo "Deployment completed successfully!" | |
EOF | |
chmod +x ./deploy/deploy.sh | |
- name: Copy files to server | |
uses: appleboy/scp-action@v1 | |
with: | |
host: ${{ secrets.SERVER_HOST }} | |
port: ${{ secrets.SSH_PORT }} | |
username: ${{ secrets.SERVER_USER }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
source: "./deploy/deploy.sh,./deploy/docker-compose.yaml" | |
target: "/opt/safeturned" | |
- name: Deploy to server | |
uses: appleboy/ssh-action@v1 | |
with: | |
host: ${{ secrets.SERVER_HOST }} | |
port: ${{ secrets.SSH_PORT }} | |
username: ${{ secrets.SERVER_USER }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
script: | | |
echo "=== Starting API deployment ===" | |
cd /opt/safeturned/deploy | |
chmod +x deploy.sh | |
./deploy.sh "${{ steps.version.outputs.version }}" "${{ steps.branch.outputs.branch }}" "${{ steps.branch.outputs.environment }}" | |
echo "=== API deployment completed ===" | |
#- name: Create Release | |
# if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' | |
# uses: actions/create-release@v1 | |
# env: | |
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# with: | |
# tag_name: v${{ github.run_number }} | |
# release_name: Release v${{ github.run_number }} | |
# body: | | |
# ## Changes | |
# - Built from commit: ${{ github.sha }} | |
# | |
# draft: false | |
# prerelease: false |