« ^ »

Github Actionsの環境変数の設定から.envを生成する

所要時間: 約 2分

最近のプロジェクトでは、.envファイルを各自用意し、それを読み込んだり、docker-composeに読み込ませたりすることで、設定を行うことはよくある。便利ではある反面、各種環境の設定の差によって問題を引き起すこともある。例えばテストなどはそうだろう。ローカルで実行したテストは成功するのにGithub Actionsで実行したテストは失敗する。またはその逆の状況にしばしば陥いる。それらの理由はいくつかあるが、環境変数が原因であることも多い。ただ、環境変数の管理は本当に面倒で、開発者が複数いる場合、知らない間に環境変数が増えたりする。しかし、ローカル環境の設定として生成した.envファイルはそれらに追従しない。結果としてローカルの環境変数の設定が漏れ、ローカルで実行したテストは失敗するが、Github Actions上ではテストが成功しているという状況になる。.envファイルに何が記載されているのかということについて、把握できればそれにこしたことはないが、この認知能力が下がった状態では当然把握できる訳がない。そこでGithub Actionsの設定を解析し、環境変数の設定を読み込んだり.envファイルを出力するようなEmacs Lispを実装することにした。

(defvar github-actions-config-yaml "")
(defvar github-actions-config-object-path '(jobs test env))

(defun github-actions-parse-env ()
  (let ((ga-env-list nil))
    (maphash (lambda (sym val)
	       (push (format "%s=%s"
			     (symbol-name sym)
			     (cond ((stringp val) val)
				   ((eq nil val) "None")
				   ((eq t val) "True")
				   (t (json-encode-string (json-parse-string val)))))
		     ga-env-list))
	     (seq-reduce (lambda (val sym) (gethash sym val))
			 github-actions-config-object-path
			 (yaml-parse-string
			  (with-current-buffer
			      (find-file--read-only
			       #'find-file-noselect
			       github-actions-config-yaml
			       nil)
			    (buffer-substring-no-properties (point-min) (point-max))))))
    ga-env-list))


(defun github-actions-export-env ()
  (interactive)
  (let ((envlist  (github-actions-parse-env)))
    (with-current-buffer (get-buffer-create "*github actions environment variables*")
      (mapc (lambda (line) (insert (format "%s\n" line)))
	    envlist))))

github-actions-config-yamlGithub Actions の設定へのパスを指定し、 github-actions-config-object-pathGithub Actions の設定内のオブジェクト名を指定する。例えば次のような設定となっている場合、 '(jobs test env) と指定する。

jobs:
   test:
      env:
        foo: bar

設定が完了したら M-x github-actions-export-env を実行すると、 *github actions environment variables* バッファを作成し、そこに設定をdotenv形式で記述する。それ以降は必要に応じて、ファイルに保存するなどを各自の要求に応じて行う。