Skip to content

Deploy to Production #9

Deploy to Production

Deploy to Production #9

---
name: Deploy to Production
on:
workflow_dispatch:
permissions:
contents: write
jobs:
deploy:
name: Deploy to Production Server
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install sshpass
run: |
sudo apt-get update
sudo apt-get install -y sshpass
- name: Deploy to production server
env:
SERVER_IP: ${{ secrets.PRODUCTION_SERVER_IP }}
SERVER_USER: ${{ secrets.PRODUCTION_SERVER_USER }}
SERVER_PASSWORD: ${{ secrets.PRODUCTION_SERVER_PASSWORD }}
run: |
# Create SSH key directory
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Disable strict host key checking for deployment
cat >> ~/.ssh/config <<EOF
Host production-server
HostName $SERVER_IP
User $SERVER_USER
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
EOF
# Deploy via SSH
sshpass -p "$SERVER_PASSWORD" ssh \
-o StrictHostKeyChecking=no "$SERVER_USER@$SERVER_IP" << 'ENDSSH'
set -e
# Navigate to project directory
cd /home/django/education-website
# Pull latest changes from main branch
git fetch --all --prune
git reset --hard origin/main
# Activate virtual environment and upgrade pip
source venv/bin/activate
pip install --upgrade pip wheel
# Install/upgrade Poetry
pip install --upgrade poetry==2.0.1
# Configure Poetry to use existing virtualenv
poetry config virtualenvs.create false --local || true
# Install dependencies
poetry install --only main --no-interaction --no-ansi
# Run Django migrations
python manage.py migrate --noinput
# Collect static files
python manage.py collectstatic --noinput
# Restart the web server (systemd service)
sudo systemctl restart education-website
# Restart nginx
sudo systemctl restart nginx
echo "Deployment completed successfully!"
ENDSSH
- name: Verify deployment
env:
SERVER_IP: ${{ secrets.PRODUCTION_SERVER_IP }}
SERVER_USER: ${{ secrets.PRODUCTION_SERVER_USER }}
SERVER_PASSWORD: ${{ secrets.PRODUCTION_SERVER_PASSWORD }}
run: |
echo "Verifying deployment..."
sshpass -p "$SERVER_PASSWORD" ssh \
-o StrictHostKeyChecking=no "$SERVER_USER@$SERVER_IP" << 'ENDSSH'
# Check if service is running
sudo systemctl status education-website --no-pager || true
# Check nginx status
sudo systemctl status nginx --no-pager || true
ENDSSH
echo "Deployment verification completed!"
- name: Get latest release tag
id: get_latest_tag
run: |
# Get the latest release tag
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null \
|| echo "v0.0")
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "Latest tag: $LATEST_TAG"
- name: Increment version
id: increment_version
run: |
LATEST_TAG="${{ steps.get_latest_tag.outputs.latest_tag }}"
# Remove 'v' prefix and split version
VERSION=${LATEST_TAG#v}
# Split into major.minor (assuming format v1.0, v1.1, etc.)
MAJOR=$(echo $VERSION | cut -d. -f1)
MINOR=$(echo $VERSION | cut -d. -f2)
# Increment minor version
MINOR=$((MINOR + 1))
NEW_VERSION="v${MAJOR}.${MINOR}"
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "New version: $NEW_VERSION"
- name: Generate release notes
id: generate_notes
run: |
LATEST_TAG="${{ steps.get_latest_tag.outputs.latest_tag }}"
NEW_VERSION="${{ steps.increment_version.outputs.new_version }}"
DEPLOY_DATE=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
# Get commits since last tag
if git rev-parse "$LATEST_TAG" >/dev/null 2>&1; then
COMMITS=$(git log ${LATEST_TAG}..HEAD \
--pretty=format:"- %s (%h)" --no-merges)
else
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges)
fi
# Create release notes
{
echo "## Production Deployment - ${NEW_VERSION}"
echo ""
echo "**Deployment Date:** ${DEPLOY_DATE}"
echo ""
echo "### Changes in this release:"
echo ""
echo "$COMMITS"
echo ""
echo "---"
echo "_This release was automatically created by the"
echo "production deployment workflow._"
} > /tmp/release_notes.md
echo "Release notes generated successfully"
cat /tmp/release_notes.md
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
NEW_VERSION="${{ steps.increment_version.outputs.new_version }}"
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Create and push the tag
git tag "$NEW_VERSION"
git push origin "$NEW_VERSION"
# Create the release using GitHub CLI
gh release create "$NEW_VERSION" \
--title "$NEW_VERSION" \
--notes-file /tmp/release_notes.md