在上一篇我們學到如何設置、使用secret,以及使用secret的時機
在這篇我們會來了解一下表達式跟function
表達式是很常用的功能,不管是取得變數值、context值,還是做條件判斷時都會用到
除了表達式以外Github Actions還提供了一系列的function、運算子(用法和大多數程式語言一樣,故不介紹),可以跟表達式一起用
# 是不是很眼熟?其實我們曾在context篇見過它
${{ <expression> }}
雖然常常看到表達式被${{}}包起來,但如果是用在if:
時,則可以省略${{}}
,因為Github Actions會自動把if的條件當作表達式,但如果表達式的開頭有!,就一定要用\${{}}包住
if: steps.foo.outputs.bar
# 相當於
if: ${{github.steps.foo.outputs.bar}}
但是需要注意並不是所有的context省略與否都一樣
if: env.foo
# 不等於,這取不到變數值
if: ${{github.env.foo}}
假設有一個mono repo,它裡面2個workspace,分別為foo跟bar
如果是foo的PR那標題以[foo]開頭,bar則是[bar],後面接PR的類型(ex: feat、fix、refactor)
PR標題的格式則是[workspace name][PR type] description
contains
if: contains(github.event.pull_request.title, '[fix]')
startsWith & endsWith
if: startsWith(github.event.pull_request.title, '[foo]')
format
format('Good {0} {1} {2}', 'morning', '!', 'Tempura')
join
join(['Good', 'morning'], ' ')
toJSON & fromJSON
只能處理context物件
(e.g.:env, steps, needs),無法一般處理物件env:
# 只能宣告string、number、boolean
# 記得要跳脫,或者最外層改用單引號,不然會報錯
- str1: "{\"name\":\"Tempura\"}"
- arrStr1: "[\"3\", \"4\"]"
run: |
echo ${{fromJSON(env.str1)}}
# 試圖直接傳JSON字串會報錯 Unexpected symbol: '"{\"name\":\"Tempura\"}"'
echo ${{fromJSON("{\"name\":\"Tempura\"}")}}
# 試圖直接傳入object會報錯 Unexpected symbol: '{name:'
echo ${{toJSON({name:"Tempura"})}}
# 無法處理object會報錯
echo ${{toJSON(fromJSON(env.str1))}}
hashFiles
if: hashFiles('**/package.json.lock', '**/src/styles/output.css')
run: echo 'You should not push package.json.lock to remote. Add it to .gitignore'
```-
success & failure
判斷前一個step的結果
,如果符合使用的function描述的狀態就繼續跑下一個stepif: ${{ success() }}
always
if: ${{ always() }}
run: #送訊息給開發者說workflow壞掉了
cancelled
if: ${{ cancelled() }}
如果你想要根據條件賦予某個變數值,那比起寫兩個if條件相方的step,三元運算子確實是好選擇
可惜GitHub Actions並不支援三元運算子
,但是有提供替代方案
格式是條件 && true時的return value || false時的return value
env:
fruit: ${{ github.event.inputs.selectedFruit == 'apple' && 'apple' || 'banana' }}
Object filters 是 GitHub Actions 提供的用來篩選object、array中元素的功能
- name: print name of fruits
env: |
fruits: [
{ name: 'apple' },
{ name: 'orange' },
{ name: 'peach' }
]
run: echo $fruits.*.name
# [ 'apple', 'orange', 'peach' ]
- name: print name of pets
env: |
pets: {
cat: {
black: ['Luna'],
ginger: ['Oliver']
},
dog: {
yellow: ['Milo'],
black: ['Buddy']
}
}
run: echo $pets.*.black
# [
# ['Luna'],
# ['Buddy']
# ]