mirror of
https://github.com/HamCQ/Handbook.git
synced 2026-10-02 04:47:21 +00:00
feat: github action自动部署支持
This commit is contained in:
1 parent
a685d5eda3
commit
0c54e1c1ac
1 file changed
+172
@@ -0,0 +1,172 @@
|
||||
name: Build and Deploy VuePress
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Build VuePress site
|
||||
run: yarn docs:build
|
||||
|
||||
- name: Get runner public IP
|
||||
id: ip
|
||||
run: echo "ipaddr=$(curl -s https://api.ipify.org)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Add IP to Aliyun Security Group
|
||||
env:
|
||||
ALIYUN_ACCESS_KEY_ID: ${{ secrets.ALIYUN_ACCESS_KEY_ID }}
|
||||
ALIYUN_ACCESS_KEY_SECRET: ${{ secrets.ALIYUN_ACCESS_KEY_SECRET }}
|
||||
ALIYUN_REGION: ${{ secrets.ALIYUN_REGION }}
|
||||
ALIYUN_SECURITY_GROUP_ID: ${{ secrets.ALIYUN_SECURITY_GROUP_ID }}
|
||||
SERVER_SSH_PORT: ${{ secrets.SERVER_PORT }}
|
||||
RUNNER_IP: ${{ steps.ip.outputs.ipaddr }}
|
||||
run: |
|
||||
pip install aliyun-python-sdk-core aliyun-python-sdk-ecs
|
||||
python3 << 'EOF'
|
||||
import os
|
||||
import sys
|
||||
from aliyunsdkcore.client import AcsClient
|
||||
from aliyunsdkecs.request.v20140526 import AuthorizeSecurityGroupRequest
|
||||
|
||||
client = AcsClient(
|
||||
os.environ['ALIYUN_ACCESS_KEY_ID'],
|
||||
os.environ['ALIYUN_ACCESS_KEY_SECRET'],
|
||||
os.environ['ALIYUN_REGION']
|
||||
)
|
||||
|
||||
request = AuthorizeSecurityGroupRequest.AuthorizeSecurityGroupRequest()
|
||||
request.set_SecurityGroupId(os.environ['ALIYUN_SECURITY_GROUP_ID'])
|
||||
request.set_IpProtocol('tcp')
|
||||
request.set_PortRange(f"{os.environ['SERVER_SSH_PORT']}/{os.environ['SERVER_SSH_PORT']}")
|
||||
request.set_SourceCidrIp(f"{os.environ['RUNNER_IP']}/32")
|
||||
request.set_Description('GitHub Actions temporary access')
|
||||
|
||||
try:
|
||||
response = client.do_action_with_exception(request)
|
||||
print(f"✓ Added {os.environ['RUNNER_IP']} to security group")
|
||||
except Exception as e:
|
||||
if 'InvalidPermission.Duplicate' in str(e):
|
||||
print(f"✓ Rule already exists for {os.environ['RUNNER_IP']}")
|
||||
else:
|
||||
print(f"✗ Error: {e}")
|
||||
sys.exit(1)
|
||||
EOF
|
||||
|
||||
- name: Deploy to Aliyun Server
|
||||
uses: appleboy/scp-action@v0.1.7
|
||||
with:
|
||||
host: ${{ secrets.SERVER_HOST }}
|
||||
username: ${{ secrets.SERVER_USER }}
|
||||
key: ${{ secrets.SERVER_SSH_KEY }}
|
||||
port: ${{ secrets.SERVER_PORT }}
|
||||
source: "docs/.vuepress/dist/*"
|
||||
target: ${{ secrets.DEPLOY_PATH }}
|
||||
strip_components: 3
|
||||
overwrite: true
|
||||
rm: true
|
||||
|
||||
- name: Set Permissions
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
host: ${{ secrets.SERVER_HOST }}
|
||||
username: ${{ secrets.SERVER_USER }}
|
||||
key: ${{ secrets.SERVER_SSH_KEY }}
|
||||
port: ${{ secrets.SERVER_PORT }}
|
||||
script: |
|
||||
chmod -R 644 ${{ secrets.DEPLOY_PATH }}
|
||||
chown -R ${{ secrets.SERVER_USER }}:${{ secrets.SERVER_USER }} ${{ secrets.DEPLOY_PATH }}
|
||||
|
||||
- name: Remove IP from Aliyun Security Group
|
||||
if: always()
|
||||
env:
|
||||
ALIYUN_ACCESS_KEY_ID: ${{ secrets.ALIYUN_ACCESS_KEY_ID }}
|
||||
ALIYUN_ACCESS_KEY_SECRET: ${{ secrets.ALIYUN_ACCESS_KEY_SECRET }}
|
||||
ALIYUN_REGION: ${{ secrets.ALIYUN_REGION }}
|
||||
ALIYUN_SECURITY_GROUP_ID: ${{ secrets.ALIYUN_SECURITY_GROUP_ID }}
|
||||
SERVER_SSH_PORT: ${{ secrets.SERVER_PORT }}
|
||||
RUNNER_IP: ${{ steps.ip.outputs.ipaddr }}
|
||||
run: |
|
||||
pip install aliyun-python-sdk-core aliyun-python-sdk-ecs
|
||||
python3 << 'EOF'
|
||||
import os
|
||||
from aliyunsdkcore.client import AcsClient
|
||||
from aliyunsdkecs.request.v20140526 import RevokeSecurityGroupRequest
|
||||
|
||||
client = AcsClient(
|
||||
os.environ['ALIYUN_ACCESS_KEY_ID'],
|
||||
os.environ['ALIYUN_ACCESS_KEY_SECRET'],
|
||||
os.environ['ALIYUN_REGION']
|
||||
)
|
||||
|
||||
request = RevokeSecurityGroupRequest.RevokeSecurityGroupRequest()
|
||||
request.set_SecurityGroupId(os.environ['ALIYUN_SECURITY_GROUP_ID'])
|
||||
request.set_IpProtocol('tcp')
|
||||
request.set_PortRange(f"{os.environ['SERVER_SSH_PORT']}/{os.environ['SERVER_SSH_PORT']}")
|
||||
request.set_SourceCidrIp(f"{os.environ['RUNNER_IP']}/32")
|
||||
|
||||
try:
|
||||
response = client.do_action_with_exception(request)
|
||||
print(f"✓ Removed {os.environ['RUNNER_IP']} from security group")
|
||||
except Exception as e:
|
||||
print(f"⚠ Warning: Failed to remove rule: {e}")
|
||||
EOF
|
||||
|
||||
- name: Notify Success to WeChat
|
||||
if: success()
|
||||
env:
|
||||
COMMIT_MSG: ${{ github.event.head_commit.message }}
|
||||
run: |
|
||||
curl "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${{ secrets.WECHAT_WEBHOOK_KEY }}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{
|
||||
\"msgtype\": \"markdown\",
|
||||
\"markdown\": {
|
||||
\"content\": \"## ✅ 部署成功\n> 项目:**Handbook (VuePress)**\n> 分支:\\\`${{ github.ref_name }}\\\`\n> 提交者:${{ github.actor }}\n> 提交信息:${COMMIT_MSG}\n> 状态:已成功部署到生产环境\"
|
||||
}
|
||||
}"
|
||||
|
||||
- name: Get Job Logs
|
||||
if: failure()
|
||||
id: logs
|
||||
run: |
|
||||
ERROR_LOGS=$(cat $GITHUB_STEP_SUMMARY 2>/dev/null || echo "无法获取错误日志")
|
||||
echo "logs<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$ERROR_LOGS" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Notify Failure to WeChat
|
||||
if: failure()
|
||||
env:
|
||||
WORKFLOW_NAME: ${{ github.workflow }}
|
||||
RUN_ID: ${{ github.run_id }}
|
||||
JOB_NAME: ${{ github.job }}
|
||||
run: |
|
||||
FAILED_STEP=$(echo "${{ toJSON(job) }}" | jq -r '.steps[] | select(.conclusion=="failure") | .name' | head -1 || echo "未知步骤")
|
||||
|
||||
curl "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${{ secrets.WECHAT_WEBHOOK_KEY }}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{
|
||||
\"msgtype\": \"markdown\",
|
||||
\"markdown\": {
|
||||
\"content\": \"## ❌ 部署失败\n> 项目:**Handbook (VuePress)**\n> 分支:\\\`${{ github.ref_name }}\\\`\n> 提交者:${{ github.actor }}\n> 提交信息:${{ github.event.head_commit.message }}\n> 失败步骤:${FAILED_STEP}\n> Run ID:${RUN_ID}\n\n查看完整日志请前往 GitHub Actions\"
|
||||
}
|
||||
}"
|
||||
Reference in new issue
Block a user