@@ -96,23 +96,140 @@ jobs:
9696 cache-to : type=gha,mode=max
9797 platforms : linux/amd64,linux/arm64
9898
99- notify-deployment :
100- name : Notify Deployment
99+ deploy-via-portainer :
100+ name : Deploy via Portainer
101101 runs-on : [self-hosted, home]
102102 needs : [build-and-push, build-frontend-image]
103- if : always()
103+ if : success() && github.ref == 'refs/heads/main'
104104
105105 steps :
106+ - name : Install and Connect Tailscale
107+ env :
108+ TS_AUTH_KEY : ${{ secrets.TS_AUTH_KEY }}
109+ run : |
110+ # Install Tailscale (if not already installed)
111+ if ! command -v tailscale &> /dev/null; then
112+ echo "Installing Tailscale..."
113+ curl -fsSL https://tailscale.com/install.sh | sh
114+ fi
115+
116+ # Connect to Tailscale using auth key
117+ echo "Connecting to Tailscale network..."
118+ sudo tailscale up --auth-key="$TS_AUTH_KEY" --accept-routes --reset
119+
120+ # Wait for connection to establish
121+ sleep 5
122+
123+ # Verify connection
124+ echo "Tailscale status:"
125+ sudo tailscale status
126+
127+ - name : Verify Portainer Connection
128+ run : |
129+ echo "Verifying connection to Portainer..."
130+
131+ # Test connection to Portainer
132+ for i in {1..10}; do
133+ if curl -f -s --connect-timeout 10 https://portainer.sankalpnarula.com/api/status > /dev/null; then
134+ echo "β
Successfully connected to Portainer via Tailscale"
135+ break
136+ fi
137+ echo "β³ Attempt $i/10 - Waiting for Portainer connection..."
138+ sleep 3
139+ done
140+
141+ # Final connection test
142+ if ! curl -f -s --connect-timeout 10 https://portainer.sankalpnarula.com/api/status > /dev/null; then
143+ echo "β Failed to connect to Portainer"
144+ echo "Tailscale status:"
145+ sudo tailscale status
146+ exit 1
147+ fi
148+
149+ - name : Trigger Portainer Stack Redeployment
150+ env :
151+ PORTAINER_URL : https://portainer.sankalpnarula.com
152+ PORTAINER_TOKEN : ${{ secrets.PORTAINER_ACCESS_TOKEN }}
153+ STACK_NAME : ocpp-chaos-sim # Adjust this to your actual stack name
154+ run : |
155+ set -e
156+
157+ echo "π Starting deployment process..."
158+
159+ # Get stack ID
160+ echo "π Looking for stack: $STACK_NAME"
161+ STACK_ID=$(curl -s -H "X-API-Key: $PORTAINER_TOKEN" \
162+ "$PORTAINER_URL/api/stacks" | \
163+ jq -r ".[] | select(.Name == \"$STACK_NAME\") | .Id")
164+
165+ if [ "$STACK_ID" = "null" ] || [ -z "$STACK_ID" ]; then
166+ echo "β Stack '$STACK_NAME' not found. Available stacks:"
167+ curl -s -H "X-API-Key: $PORTAINER_TOKEN" \
168+ "$PORTAINER_URL/api/stacks" | jq -r '.[].Name'
169+ exit 1
170+ fi
171+
172+ echo "π Found stack ID: $STACK_ID"
173+
174+ # Get endpoint ID (usually 1 for local Docker, but let's be sure)
175+ ENDPOINT_ID=$(curl -s -H "X-API-Key: $PORTAINER_TOKEN" \
176+ "$PORTAINER_URL/api/stacks/$STACK_ID" | \
177+ jq -r '.EndpointId')
178+
179+ echo "π― Using endpoint ID: $ENDPOINT_ID"
180+
181+ # Trigger stack update (pull latest images and redeploy)
182+ echo "π Triggering stack redeployment..."
183+ RESPONSE=$(curl -s -w "%{http_code}" -X PUT \
184+ -H "X-API-Key: $PORTAINER_TOKEN" \
185+ -H "Content-Type: application/json" \
186+ -d '{
187+ "pullImage": true,
188+ "prune": true
189+ }' \
190+ "$PORTAINER_URL/api/stacks/$STACK_ID?endpointId=$ENDPOINT_ID")
191+
192+ HTTP_CODE="${RESPONSE: -3}"
193+ RESPONSE_BODY="${RESPONSE%???}"
194+
195+ if [ "$HTTP_CODE" = "200" ]; then
196+ echo "β
Stack redeployment triggered successfully!"
197+ echo "π Response: $RESPONSE_BODY"
198+ else
199+ echo "β Deployment failed with HTTP $HTTP_CODE"
200+ echo "π Response: $RESPONSE_BODY"
201+ exit 1
202+ fi
203+
204+ # Wait a moment and check deployment status
205+ echo "β³ Waiting for deployment to complete..."
206+ sleep 10
207+
208+ # Check if stack is running
209+ STACK_STATUS=$(curl -s -H "X-API-Key: $PORTAINER_TOKEN" \
210+ "$PORTAINER_URL/api/stacks/$STACK_ID" | \
211+ jq -r '.Status')
212+
213+ echo "π Stack status: $STACK_STATUS"
214+
106215 - name : Deployment Summary
216+ if : always()
107217 run : |
108- echo "π Deployment Summary" >> $GITHUB_STEP_SUMMARY
109- echo "" >> $GITHUB_STEP_SUMMARY
110- echo "**Images built and pushed to GHCR:**" >> $GITHUB_STEP_SUMMARY
111- echo "- Backend: \`ghcr.io/${{ github.repository }}:latest\`" >> $GITHUB_STEP_SUMMARY
112- echo "- Frontend: \`ghcr.io/${{ github.repository }}-frontend:latest\`" >> $GITHUB_STEP_SUMMARY
218+ echo "π― **Portainer Deployment Summary**" >> $GITHUB_STEP_SUMMARY
113219 echo "" >> $GITHUB_STEP_SUMMARY
114- echo "**Pull commands for your orchestration tool:**" >> $GITHUB_STEP_SUMMARY
115- echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
116- echo "docker pull ghcr.io/${{ github.repository }}:latest" >> $GITHUB_STEP_SUMMARY
117- echo "docker pull ghcr.io/${{ github.repository }}-frontend:latest" >> $GITHUB_STEP_SUMMARY
118- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
220+ if [ "${{ job.status }}" = "success" ]; then
221+ echo "β
**Status**: Deployment successful" >> $GITHUB_STEP_SUMMARY
222+ echo "π **Portainer**: [View Stack](https://portainer.sankalpnarula.com)" >> $GITHUB_STEP_SUMMARY
223+ echo "π¦ **Backend Image**: \`ghcr.io/${{ github.repository }}:latest\`" >> $GITHUB_STEP_SUMMARY
224+ echo "π¦ **Frontend Image**: \`ghcr.io/${{ github.repository }}-frontend:latest\`" >> $GITHUB_STEP_SUMMARY
225+ else
226+ echo "β **Status**: Deployment failed" >> $GITHUB_STEP_SUMMARY
227+ echo "π **Check**: Review job logs for details" >> $GITHUB_STEP_SUMMARY
228+ fi
229+
230+ - name : Cleanup Tailscale Connection
231+ if : always()
232+ run : |
233+ echo "π Cleaning up Tailscale connection..."
234+ sudo tailscale logout || true
235+ echo "β
Tailscale disconnected"
0 commit comments