-
-
Notifications
You must be signed in to change notification settings - Fork 177
182 lines (147 loc) · 5.64 KB
/
deploy-production.yml
File metadata and controls
182 lines (147 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
---
name: Deploy to Production
on:
release:
types: [published]
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