Closed12

GopherJS で JavaScript Action

Shunsuke SuzukiShunsuke Suzuki

aqua-installer の GitHub Action を GopherJS を使って Go で書きたい。

https://github.com/aquaproj/aqua-installer/pull/144

GopherJS の Install

binary はなさそう

$ go install github.com/gopherjs/gopherjs

環境変数 GOPHERJS_GOROOT を設定する必要がある。

$ export GOPHERJS_GOROOT="$(go env GOROOT)"

執筆時点 (2022-08-05) で Go 1.17 をサポートしているが、 Go 1.18 はサポートしてない。

一方 go-githubactions v1.0.0 は Go 1.18 以降が必要。
なので go-githubactions v0.5.2 を使う。 v0.5.2 と v1.0.0 の差はそこまでないので良しとする。

JS をビルドする

$ gopherjs build -o dist/index.js ./cmd/action

GOOS=linux を設定する必要があるらしい。

https://github.com/gopherjs/gopherjs/issues/1074

でもこれ Windows でも GOOS=linux でいいのか??
action で使う OS によるんでは?わかんないけど

Shunsuke SuzukiShunsuke Suzuki

https://github.com/aquaproj/aqua-installer/runs/7682624419?check_suite_focus=true

2022/08/04 23:33:09 [INFO] Installing aqua  to /home/runner/.local/share/aquaproj-aqua/bin/aqua
warning: system calls not available, see https://github.com/gopherjs/gopherjs/blob/master/doc/syscalls.md
2022/08/04 23:33:09 install aqua: create a directory where aqua is installed: mkdir /home: permission denied
fatal error: all goroutines are asleep - deadlock!

https://github.com/gopherjs/gopherjs/blob/master/doc/syscalls.md

GopherJS 1.18 では system call もサポートするらしいが、まだ 1.18 はリリースされていない。
仕方ないので commit hash を指定して install する

$ go install github.com/gopherjs/gopherjs@f2ebe4653adeeeafebb13bdf28941a545ad88214

最新の GopherJS でビルドしたら warning 出た。

$ gopherjs build -o dist/index.js ./cmd/action
Using GOOS=linux and GOARCH=ecmascript in GopherJS is deprecated and will be removed in future. Use GOOS=js GOARCH=ecmascript instead.
Shunsuke SuzukiShunsuke Suzuki

https://github.com/aquaproj/aqua-installer/runs/7683005860?check_suite_focus=true

2022/08/05 00:11:16 [INFO] Installing aqua  to /home/runner/.local/share/aquaproj-aqua/bin/aqua
2022/08/05 00:11:16 Downloading https://github.com/aquaproj/aqua/releases/download//aqua_js_ecmascript.tar.gz
2022/08/05 00:11:16 install aqua: send a HTTP request: Get "https://github.com/aquaproj/aqua/releases/download//aqua_js_ecmascript.tar.gz": net/http: neither of Fetch nor XMLHttpRequest APIs is available

gopherjs でビルド時に GOOS, GOARCH の値がハードコードされている?

GitHub Actions で環境変数で取得できるのでそっちを使うか
https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables

RUNNER_OS The operating system of the runner executing the job. Possible values are Linux, Windows, or macOS. For example, Windows

RUNNER_ARCH The architecture of the runner executing the job. Possible values are X86, X64, ARM, or ARM64.

Shunsuke SuzukiShunsuke Suzuki
2022/08/05 00:39:41 [INFO] Installing aqua v1.18.0 to /home/runner/.local/share/aquaproj-aqua/bin/aqua
2022/08/05 00:39:41 Downloading https://github.com/aquaproj/aqua/releases/download/v1.18.0/aqua_linux_amd64.tar.gz
2022/08/05 00:39:41 install aqua: send a HTTP request: Get "https://github.com/aquaproj/aqua/releases/download/v1.18.0/aqua_linux_amd64.tar.gz": net/http: neither of Fetch nor XMLHttpRequest APIs is available

net/http: neither of Fetch nor XMLHttpRequest APIs is available

https://github.com/gopherjs/gopherjs/issues/839

https://github.com/gopherjs/gopherjs/issues/586

https://github.com/rocketlaunchr/gopherjs-xhr

https://pkg.go.dev/github.com/rocketlaunchr/gopherjs-xhr

.inc.js とはなんなのか。 GopherJS 固有のものなのか?

https://github.com/gopherjs/gopherjs/wiki/Bundle-additional-JavaScript-with-Go-packages

GopherJS は .inc.js という拡張子のファイルを見つけて include してくれるらしい。

Shunsuke SuzukiShunsuke Suzuki

fetch の polyfill が動かないので XMLHttpRequest の polyfill を使うのが良いらしい?

Shunsuke SuzukiShunsuke Suzuki

ncc に関しては良さそう。
polyfill に置き換えたら動かなくなったので直す

2022/08/05 12:40:42 install aqua: downloand and unarchive aqua: create a gzip reader: gzip: invalid header
Shunsuke SuzukiShunsuke Suzuki
2022/08/05 14:52:53 run aqua i: execute a command: aqua i: fork/exec /home/runner/.local/share/aquaproj-aqua/bin/aqua: not implemented on js

exec の実行に失敗している

Shunsuke SuzukiShunsuke Suzuki

os/exec PATH の扱いが変わるっぽい

package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
)

func main() {
	if err := core(); err != nil {
		log.Fatal(err)
	}
}

func core() error {
	cmd := exec.Command("gh", "version")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("execute a command: gh version: %w", err)
	}
	return nil
}
$ go run .          
gh version 2.14.3 (2022-07-26)
https://github.com/cli/cli/releases/tag/v2.14.3
$ node dist/index.js
2022/08/06 01:01:53 execute a command: gh version: exec: "gh": executable file not found in $PATH
Shunsuke SuzukiShunsuke Suzuki

GopherJS で GitHub Actions はやめたほうが良い気がしてきた

良いところ

  • Go で書けるのはやはり良い
  • 多分使えなくはない
    • 特に os/exec や net/http などを使わなければ問題になりにくそう
    • ユースケースによっては問題なく使えそう

懸念

  • 落とし穴、ハマりどころが結構ある
  • 情報が少ない
  • 問題があったときに対応が大変そう

一方で GopherJS もアクティブに開発されていて将来的には懸念が払拭されるかもしれない

このスクラップは2022/08/06にクローズされました