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