在上一篇的內容中,實作了自己的 step
,但目前僅止於可以接收外部的參數傳入到 step 中來供 step 的實作使用,但如果要從 step 實作後,把實作的結果傳出給其他使用,該怎麼做呢?
延伸自上一篇的內容,原本的 step.yml
的內容如下:
spec:
inputs:
who:
type: string
default: step
---
exec:
command:
- bash
- -c
- echo 'hello ${{inputs.who}}'
根據 GitLab 文件上目前針對 Step 的 output 說明,我們必須在 spec 的內容新增一段 outputs,並且定義 output 型別及相關參數規格,因此我們先調整 step.yml 的內容,調整後 spec 段落的內容如下:
spec:
inputs:
who:
type: string
default: world
outputs:
result:
type: string
我們新增一個 outputs
參數,騎參數名稱為 result
並且宣告型別為 string
。在 GitLab CI/CD 的 step 中,可以接受的輸出為 JSON Line 格式,每一行為一個 JSON 物件的名稱對應數值。
目前 Step output 可以接受的型別如下:
Step specification type | Expected JSONL value type |
---|---|
array |
array |
boolean |
boolean |
number |
number |
string |
string |
struct |
object |
根據 Step 的定義,我們正式建立 step 的輸出,調整後的完整內容如下:
spec:
inputs:
who:
type: string
default: world
outputs:
result:
type: string
---
exec:
command:
- bash
- -c
- echo '{"name":"result","value":"hello ${{inputs.who}}"}' | tee ${{output_file}}
其中最關鍵的內容為最後一行:
echo '{"name":"result","value":"hello ${{inputs.who}}"}' | tee ${{output_file}}
將結果以 JSON LINE 的格式輸出,value 的部分,以字串 hello ${{inputs.who}}"
置入。調整後的 step 可以調整 .gitlab-ci.yml
中使用,使用方法如下:
hello-world:
run:
- name: hello_step
step: .
- name: get_hello_step_result
script: echo "hello_step result is ${{steps.hello_step.outputs.result}}"
這段 GitLab CI/CD YAML 主要使用兩個 step,第一個名為:hello_step
的 step 使用了上方定義的 step,第二個名為 get_hello_step_result
的 step,目的在取得第一個 step 的輸出用來組成一個字串輸出。取得輸出值的方法是:
${{steps.hello_step.outputs.result}}"
從 steps
的工作中,找到名為 hello_step
的 step,取得其輸出變數的 result
。這邊這個 step 以 script 的方式,直接 echo 輸出於畫面。
以上是單一個 Step 元件使用 output 的狀態。接下來,同樣一個範例稍作調整,先建立一個資料夾 hello
,把目前的 step.yml
搬移到資料夾中變為 hello/step.yml
,接著同樣在根目錄建立另外一個新的 step.yml
其內容如下:
spec:
inputs:
somebody:
default: "world"
type: string
outputs:
all_result:
type: string
sombdody_result:
type: string
---
run:
- name: hello_world
step: ./hello
- name: hello_somebody
step: ./hello
inputs:
who: ${{ inputs.somebody }}
outputs:
all_result: "${{steps.hello_world.outputs.result}} and ${{steps.hello_somebody.outputs.result}}"
sombdody_result: "${{steps.hello_somebody.outputs.result}}"
這個新的 step.yml
主要展示當 Step 使用子 step 時,如何讓 step 之間互動,首先在 spce 的段落,定義了一個 input 參數,名為 somebody
,預設值為 world,型別為字串。另外定義兩個 outpus 參數,均為字串,分別為 all_result
及 sombdody_result
。
實作的部分,主要執行兩個 step 工作,第一個是名為 hello_world
的 Step 以預設值使用放在資料夾 hello
的 step。第二個 step 則帶入 input 參數,至 hello step 的 who
參數中,因此假設使用的時候輸入 GitLab
則預期會輸出 Hello GitLab
。在這個 step.yml
因為是一個單純使用 run
的 step,因此其搜集 output 的方法相較簡潔:
outputs:
all_result: "${{steps.hello_world.outputs.result}} and ${{steps.hello_somebody.outputs.result}}"
sombdody_result: "${{steps.hello_somebody.outputs.result}}"
直接使用 outputs
描述,於對應的參數中直接帶入想要帶入的內容,如 all_result
這個 output,帶入了 "${{steps.hello_world.outputs.result}} and ${{steps.hello_somebody.outputs.result}}"
,sombdody_result
則只帶入名為 hello_somebody
的 step 輸出值。
這邊在針對 .gitlab-ci.yml
結合上面的兩個範例後作調整,上半部的兩個 step 為上一個範例,下面的三個 step 分別取得目前根目錄的 step.yml
,並透過 script輸出兩個 output參數的數值:
hello-world:
run:
- name: hello_step
step: ./hello
- name: get_hello_step_result
script: echo "hello_step result is ${{steps.hello_step.outputs.result}}"
- name: hello_everybody
step: .
inputs:
somebody: GitLab
- name: echo_all_result
script: echo "all result is ${{steps.hello_everybody.outputs.all_result}}"
- name: echo_somebody_result
script: echo "somebody result is ${{steps.hello_everybody.outputs.sombdody_result}}"
在今天的內容中提到兩種 step 進行輸出的模式,第一個是當使用 exec
直接執行指令時,其輸出的內容,必須是 JSON Line 的格式,通常必須自己組成 JSON 字串作為輸出值,另外是當該 Step,使以 run
的型態使用各種 step
時,則可以透過 outputs
底下直接設定輸出的變數內容。
目前在試用 GitLab CI/CD Step 功能的過程中,可能因為還是實驗中的功能,所以可以發現,有蠻多細節還有一些問題,以撰寫這邊內容時,在文件中提到輸出值的內容,有提到 delegate
的功能,但到目前,是尚無法確切的取得輸出值的,所以,如 GitLab 官方文件所說的,目前 Step 的功能都還在實驗中,建議不要使用在正式環境中。我是墨嗓(陳佑竹),期待這次的內容能帶給你實用的啟發與幫助。