github action的使用
近年来,我一直在使用jenkins 来部署自己的项目,发现太耗内存了,
因此将自动化部迁的操作改为使用github action。
初始化action配置
选择一个合适的action类型,比如webpack、gitPage、Nodejs等等。
比如我这里选择了webpack,选择完成后 可以看到在仓库里多了一个文件 .github/workflows/webpack.yml
由此可以推得:“参与自动化,其实就是编写一个yml工作流文件”,所以其实你也可以不选择,纯手建,麻烦些而已。
创建一些变量
后续涉及到部署的时候,服务器的ip、密钥什么的不适合直接编码在yml中,因此 git action允许你创建一些变量在仓库的设置中定义,在yml中引用
进入setting > secrets and variables > Actions的目录下,比如设置如下三个配置项
最后在yml中使用即可
#...
- name: Deploy to Staging server
uses: easingthemes/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_PORT: ${{ secrets.REMOTE_PORT}}
部署到私有服务器
如果你不想将项目部署到gitPage,而是想部署到自己服务器上,我们可以编写shell脚本来调用ssh+rsync等来完成部署操作!
不过已经有现有action插件 ssh-deploy供使用,简化了我们自己编码的麻烦。
需要注意的是,这个插件有点坑:
- 一致提示没有权限 Permission denied,经过特意的学习了一番 ssh和rsync后才知道,我的问题是---作者已经提醒过的 “手动将公钥添加到authorized_keys中”
前端项目-webpack
一个较完整的前端项目配置
name: NodeJS with Webpack
on:
push:
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: 迁出代码
uses: actions/checkout@main
- name: 安装Node
uses: actions/setup-node@main
with:
node-version: "20.x"
- name: 安装依赖
run: yarn
- name: 打包
run: npm run build
- name: 发布到服务器
uses: easingthemes/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-avzr --delete --mkpath"
SOURCE: "build/"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_PORT: ${{ secrets.REMOTE_PORT }}
REMOTE_USER: root
TARGET: /home/apps-root/book-fe
后端项目-java
name: Java CI with Maven
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: 迁出代码
uses: actions/checkout@main
- name: 安装 JDK
uses: actions/setup-java@main
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: 构建
run: mvn -B package --file pom.xml
- name: 发布到服务器
uses: easingthemes/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-avzr --delete --mkpath"
SOURCE: "target/blog-server-0.0.1-SNAPSHOT.jar"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_PORT: ${{ secrets.REMOTE_PORT }}
REMOTE_USER: root
TARGET: /home/apps-root/blog-server
- name: 启动服务
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_HOST }}
port: ${{ secrets.REMOTE_PORT }}
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
source /etc/profile
cd /home/apps-root/blog-server
nohup java -jar ./*.jar &
- 打包完成后 手动将制品 也就是打包后的文件 xxx.jar,通过 ssh-deploy 发送到目标服务器
- 然后再通过ssh-action 来远程控制服务器, 执行启动jar文件命令
遇到的坑,ssh执行shell时,发现找不到java环境变量,可我明明配置了呀(在/etc/profile 里)。
后来查阅各种资料,才知道 shell分为两种,SSH 命令执行 shell 是非交互式 shell,而普通 shell 是登录 shell 或交互式 shell。
非交互式shell获取到的环境变量是不全的,官方文档说:
当 bash 作为交互式登录 shell 或使用,它首先
从文件 /etc/profile 读取并执行命令(如果
该文件存在)。读取该文件后,它会按顺序查找
~/.bash_profile、~/.bash_login 和 ~/.profile
启动非登录 shell 的交互式 shell 时
,bash 会从 ~/.bashrc(
如果该文件存在)中读取并执行命令...
所以我通过在script中,添加了额外一行(source /etc/profile),使其生效 。
参考:
https://stackoverflow.com/questions/216202/why-does-an-ssh-remote-command-get-fewer-environment-variables-then-when-run-man/216204#216204
https://github.com/appleboy/ssh-action/issues/31#issuecomment-1006565847