Gitlab CI のアーティファクトをブランチやタグとジョブ名を指定して特定のファイルを取得

以下のような URL で、ブランチやタグとジョブ名を指定して最新のアーティファクトから特定のファイルを取得できます。

https://example.com/projects/:id/jobs/artifacts/:ref_name/raw/*artifact_path?job=name
https://example.com/<namespace>/<project>/-/jobs/artifacts/<ref>/raw/<path_to_file>?job=<job_name>

しかし、あくまでも passed となった最新のパイプラインのアーティファクトが取得されるため、下記のように when: manualallow_failure: false を使って手動ジョブで後続のジョブをブロックしていると、build が終わってパイプラインが blocked となった時点ではまだこのアーティファクトは取得できません。手動ジョブをすべて実行してパイプラインが passed になったタイミングでアーティファクトが取得できます。

stages:
  - build
  - deploy/stage
  - deploy/prod

build:
  stage: build
  script:
    - env | grep CI | sort > env.txt
  artifacts:
    paths:
      - env.txt
    expire_in: 10 days

deploy/stage:
  stage: deploy/stage
  when: manual
  allow_failure: false
  script:
    - echo ok

deploy/prod:
  stage: deploy/prod
  when: manual
  allow_failure: false
  script:
    - echo ok

f:id:ngyuki:20190328085546p:plain

次のように allow_failure: false がなければ手動ジョブが未実行でもパイプラインは passed となるため、手動ジョブが未実行でも build ジョブのアーティファクトが取得できます。

stages:
  - build
  - deploy/stage
  - deploy/prod

build:
  stage: build
  script:
    - env | grep CI | sort > env.txt
  artifacts:
    paths:
      - env.txt
    expire_in: 10 days

deploy/stage:
  stage: deploy/stage
  when: manual
  script:
    - echo ok

deploy/prod:
  stage: deploy/prod
  when: manual
  script:
    - echo ok

f:id:ngyuki:20190328085602p:plain

ただ、when: manual なジョブの後段に when: manual ではないジョブがあるとき、前段のジョブが未実行でも後段のジョブが実行されてしまいます。

f:id:ngyuki:20190328085623p:plain

下記のようにジョブIDを指定するAPIを使えば blocked なパイプラインのアーティファクトも取れますが、ブランチ名やタグ名からジョブIDを取得する簡単な方法はなさそう(パイプラインやジョブのリストからフィルタするしかなさそう)。

https://example.com/projects/:id/jobs/:job_id/artifacts/*artifact_path

さいごに

パイプラインを when: manual で止めて、前段のアーティファクトを Gitlab の外であれこれ検証したうえで手動ジョブを実行して後続のジョブを実行、みたいなことをしていたのですが、手動ジョブを allow_failure: false にしたら↑の通りアーティファクトがうまく取れなくなりました。

アーティファクトはジョブID指定で取るとかしないとだめですね。

参考