Add GitHub Actions workflow for Kubernetes deployment using kubectl #11
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 with app openapi | |
| on: | |
| push: | |
| branches: | |
| - main | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-latest | |
| env: | |
| KUBECONFIG: /tmp/kubeconfig | |
| API_URL: https://applaunchpad.hzh.sealos.run/api/v2alpha/app | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Fetch token | |
| env: | |
| KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }} | |
| run: | | |
| echo "${KUBECONFIG_B64}" | base64 -d > "${KUBECONFIG}" | |
| python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "$(cat ${KUBECONFIG} )" > /tmp/token.txt | |
| - name: Read app configuration | |
| id: app-config | |
| run: | | |
| APP_NAME=$(jq -r '.name' applaunchpad/body.json) | |
| # Store the JSON content to a temporary file to avoid encoding issues | |
| cp applaunchpad/body.json /tmp/app_config.json | |
| echo "app_name=$APP_NAME" >> $GITHUB_OUTPUT | |
| - name: Check if app exists | |
| id: check-app | |
| run: | | |
| TOKEN=$(cat /tmp/token.txt) | |
| APP_NAME="${{ steps.app-config.outputs.app_name }}" | |
| echo "Checking if app '${APP_NAME}' exists..." | |
| RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/response.json \ | |
| -H "Authorization: ${TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| "${API_URL}/${APP_NAME}") | |
| HTTP_STATUS="${RESPONSE: -3}" | |
| if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 300 ]; then | |
| echo "App '${APP_NAME}' exists (HTTP $HTTP_STATUS)" | |
| echo "app_exists=true" >> $GITHUB_OUTPUT | |
| echo "existing_app=$(cat /tmp/response.json)" >> $GITHUB_OUTPUT | |
| elif [ "$HTTP_STATUS" = "404" ]; then | |
| echo "App '${APP_NAME}' does not exist" | |
| echo "app_exists=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "Error checking app existence: HTTP $HTTP_STATUS" | |
| echo "Response: $(cat /tmp/response.json)" | |
| exit 1 | |
| fi | |
| - name: Create or update app | |
| run: | | |
| TOKEN=$(cat /tmp/token.txt) | |
| APP_CONFIG=$(cat /tmp/app_config.json) | |
| APP_EXISTS="${{ steps.check-app.outputs.app_exists }}" | |
| if [ "$APP_EXISTS" = "true" ]; then | |
| echo "Updating existing app..." | |
| APP_NAME="${{ steps.app-config.outputs.app_name }}" | |
| RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/update_response.json \ | |
| -X PATCH \ | |
| -H "Authorization: ${TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "${APP_CONFIG}" \ | |
| "${API_URL}/${APP_NAME}") | |
| HTTP_STATUS="${RESPONSE: -3}" | |
| # Check if HTTP status is in success range (200-299) or redirect range (300-399) | |
| if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 400 ]; then | |
| echo "App updated successfully (HTTP $HTTP_STATUS)" | |
| echo "Response: $(cat /tmp/update_response.json)" | |
| else | |
| echo "Error updating app: HTTP $HTTP_STATUS" | |
| echo "Response: $(cat /tmp/update_response.json)" | |
| exit 1 | |
| fi | |
| else | |
| echo "Creating new app..." | |
| RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/create_response.json \ | |
| -X POST \ | |
| -H "Authorization: Bearer ${TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| -d "${APP_CONFIG}" \ | |
| "${API_URL}") | |
| HTTP_STATUS="${RESPONSE: -3}" | |
| # Check if HTTP status is in success range (200-299) or redirect range (300-399) | |
| if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 400 ]; then | |
| echo "App created successfully (HTTP $HTTP_STATUS)" | |
| echo "Response: $(cat /tmp/create_response.json)" | |
| else | |
| echo "Error creating app: HTTP $HTTP_STATUS" | |
| echo "Response: $(cat /tmp/create_response.json)" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Wait and get app public address | |
| id: get-public-address | |
| run: | | |
| TOKEN=$(cat /tmp/token.txt) | |
| APP_NAME="${{ steps.app-config.outputs.app_name }}" | |
| echo "Waiting for app to be ready and getting public address..." | |
| # Wait for app to be provisioned (retry up to 10 times, 30 seconds each) | |
| for i in {1..10}; do | |
| echo "Attempt $i: Getting app status..." | |
| RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/app_status.json \ | |
| -H "Authorization: ${TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| "${API_URL}/${APP_NAME}") | |
| HTTP_STATUS="${RESPONSE: -3}" | |
| if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 300 ]; then | |
| echo "App status retrieved successfully (HTTP $HTTP_STATUS)" | |
| # Extract public address and custom domain | |
| PUBLIC_ADDR=$(jq -r '.ports[0].publicAddress // empty' /tmp/app_status.json 2>/dev/null || echo "") | |
| CUSTOM_DOMAIN=$(jq -r '.ports[0].customDomain // empty' /tmp/app_status.json 2>/dev/null || echo "") | |
| APP_STATUS=$(jq -r '.status // empty' /tmp/app_status.json 2>/dev/null || echo "") | |
| echo "App status: $APP_STATUS" | |
| echo "Public address: $PUBLIC_ADDR" | |
| echo "Custom domain: $CUSTOM_DOMAIN" | |
| # Use custom domain if available, otherwise use public address | |
| if [ -n "$CUSTOM_DOMAIN" ] && [ "$CUSTOM_DOMAIN" != "null" ]; then | |
| FINAL_ADDR="$CUSTOM_DOMAIN" | |
| echo "Using custom domain: $FINAL_ADDR" | |
| break | |
| elif [ -n "$PUBLIC_ADDR" ] && [ "$PUBLIC_ADDR" != "null" ]; then | |
| FINAL_ADDR="$PUBLIC_ADDR" | |
| echo "Using public address: $FINAL_ADDR" | |
| break | |
| elif [ "$APP_STATUS" = "ready" ]; then | |
| echo "App is ready but no public address found" | |
| FINAL_ADDR="Not Available" | |
| break | |
| else | |
| echo "App not ready yet, waiting..." | |
| sleep 30 | |
| fi | |
| else | |
| echo "Error getting app status: HTTP $HTTP_STATUS" | |
| if [ $i -eq 10 ]; then | |
| echo "Final attempt failed, exiting..." | |
| exit 1 | |
| fi | |
| sleep 30 | |
| fi | |
| done | |
| if [ -z "$FINAL_ADDR" ]; then | |
| FINAL_ADDR="Provisioning..." | |
| fi | |
| echo "final_address=$FINAL_ADDR" >> $GITHUB_OUTPUT | |
| - name: Output deployment summary | |
| run: | | |
| APP_NAME="${{ steps.app-config.outputs.app_name }}" | |
| FINAL_ADDR="${{ steps.get-public-address.outputs.final_address }}" | |
| APP_EXISTS="${{ steps.check-app.outputs.app_exists }}" | |
| echo "## π App Launchpad Deployment Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Component | Status | Details |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----------|--------|---------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| App Name | β $APP_NAME | Successfully deployed |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Deployment Type | β $([ "$APP_EXISTS" = "true" ] && echo "Updated" || echo "Created") | App $([ "$APP_EXISTS" = "true" ] && echo "updated" || echo "created") successfully |" >> $GITHUB_STEP_SUMMARY | |
| if [ "$FINAL_ADDR" != "Not Available" ] && [ "$FINAL_ADDR" != "Provisioning..." ] && [ -n "$FINAL_ADDR" ]; then | |
| echo "| Public Access | β Available | [$FINAL_ADDR]($FINAL_ADDR) |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π Access Your Application" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Public URL:** $FINAL_ADDR" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "You can access your application by clicking the link above." >> $GITHUB_STEP_SUMMARY | |
| elif [ "$FINAL_ADDR" = "Provisioning..." ]; then | |
| echo "| Public Access | β³ Provisioning | Service is still being provisioned... |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### β³ Provisioning in Progress" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Your application is still being provisioned. Public access will be available shortly." >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "You can check the status later using the App Launchpad interface." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "| Public Access | β Not Available | No public address assigned |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### β Public Access Unavailable" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "The application was deployed but no public address was assigned." >> $GITHUB_STEP_SUMMARY | |
| echo "Please check the App Launchpad interface for more details." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π Deployment Information" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**API Endpoint:** ${{ env.API_URL }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**App Name:** $APP_NAME" >> $GITHUB_STEP_SUMMARY | |
| echo "**Deployment Time:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY |