在上一篇我們比較了Github Actions和Jenkins
這篇我們會來試著把幾個pipeline翻成workflow,並看了如果搬到Github Actions,pipeline變成workflow能變得多簡潔
在搬家前我們我們要先來了解一下pipeline的組成
pipeline
ー pipeline
├── agent
├── stages
│ └── stage
│ ├──step
│ └──step
├── stages
│ └── stage
│ └──step
└── post
stage
steps
agent
post
Github Actions中無相對概念
,因為每個runner都是獨立的,workflow結束後會自動清理暫存檔案、(docker)容器、記憶體...等清理暫存檔案、(docker)容器、記憶體,或儲存log
...等了解了pipeline的基本組成後我們先來把一個簡單的Jenkinsfile翻成yaml
pipeline {
agent any
stages {
stage('greeting') {
steps {
echo 'Hello, tempura327'
}
}
}
// 因為這個pipe line並沒有build或者安裝package,所以post內不必多做清理
}
name: Example workflow
on:
workflow_dispatch:
jobs:
greeting:
runs-on: ubuntu-latest
steps:
- print something
run: echo 'Hello, tempura327'
triggers
檢查Github PR變更,若有變更就觸發也可以使用plugin,不過搬遷到Github Actions就不必再用plugin處理了
environment
跟Github Actions的jobs.<job_id>.environment同名,搬遷時要小心這點
credentials()
取得credential的function
,而不是像Github Actions是透過context來取得secretparameters
支援
型別為字串、多行文字、布靈、choice、password
Github Actions則只支援字串,就算傳入布靈也會被當字串處理,搬遷時要小心這點
input
when
parallel
options
matrix
flow control
非pipeline中的屬性,是指以Groovy expressions做條件控制、try catch
node {
stage('Greeting') {
if (env.USER_NAME == 'tempura327') {
echo 'How is it going with your articles. I\'m look forward to it.'
} else {
echo 'How are you?'
}
}
}
if else可以改用Github Actions的if,也可以用shell command,try catch則只能用shell command做出類似的效果,但是可讀性會比較差,搬遷時要小心這一點
pipeline {
agent any
triggers {
// 每12小時檢查一次repo是否有變更
pollSCM('H H/12 * * *')
}
environment {
// 取得用於打slack API的Jenkins credential,"SLACK_BOT_TOKEN"是credential的key
SLACK_TOKEN = credentials("SLACK_BOT_TOKEN")
SLACK_CHANNEL_ID = "你的slack channel id"
}
stages {
stage('Check for new tag') {
steps {
script {
// 確認更新的是否為新tag
def tagName = sh(returnStdout: true, script: 'git describe --tags --exact-match || true').trim()
if (tagName) {
env.TAG_NAME = tagName
echo "New tag detected: ${tagName}"
} else {
echo "There is no new tag."
}
}
}
}
stage("deploy to github-pages") {
when {
// 和 expression { TAG_NAME && TAG_NAME != '' } 一樣是在確認變數存在,且不為空字串
expression { return env.TAG_NAME }
}
steps {
// 用plugin安裝Node.js
nodejs(nodeJSInstallationName: 'Node 20.0.0', configId: 'config file的id') {
sh "npm install -g gh-pages@6.1.1"
}
// 用withCredentials取得github token,並只在這個block內使用
withCredentials([string(credentialsId: 'github-pat', variable: 'GITHUB_TOKEN')]) {
sh "git config --global user.email '你的email' && git config --global user.name '你的使用者名'"
// 設置遠端url,讓 git 使用取到的token 進行身份驗證
sh "git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/你的repo名.git"
sh "gh-pages --message '[skip ci] Updates' --dist ./dist"
}
}
}
}
stage('send-message') {
when {
expression { return env.TAG_NAME }
}
steps {
// slackSend是一個可以發布訊息到特定Slack頻道的plugin
slackSend(
teamDomain: "你的slack team domain",
token: "${env.SLACK_TOKEN}",
channel: "${env.SLACK_CHANNEL_ID}",
message: "New version ${env.TAG_NAME} is deployed."
)
}
}
post {
always {
// 因為有安裝node package,所以要清理
cleanWs()
}
}
}
name: Deploy to github page and send Slack message
on:
push:
tags:
- 'trial@\d+.\d+.\d+'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./src
name: github-pages
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: github-pages
url: https://tempura327.github.io/try-github-actions/
permissions:
pages: write
id-token: write
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
send-message:
name: send message
runs-on: ubuntu-latest
steps:
- name: Get the latest version
# 用--abbrev=0取代replace function
run: echo "latestTag=$(git describe --abbrev=0 --tags)" >> $GITHUB_ENV
- name: Post a message to Slack channel
if: env.latestTag != ''
uses: slackapi/slack-github-action@v1.27.0
with:
channel-id: '你的slack channel id'
slack-message: "New version ${{ env.latestTag }} is deployed."
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
我把註解都刪掉後讓大家看一下兩者差距