GoアプリのGoバージョンを1.11から1.19まで段階的かつ一気に上げた話

**＼＼＼ みんせつ Advent Calendar 2022の第3日目の記事です ／／／**

[みんせつ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/msetsu)

昨日の記事はHerokuについて（仮）ですが、一昨日の記事は「[みんせつエンジニアリングブログを開始するわけ](https://qiita.com/msetsu/items/cdab9c841d96cd4aa4c1)」でした。

---

Goが大好きな[T郎](https://twitter.com/trowems23)です。

みんせつでは[創業当初](https://qiita.com/msetsu/items/cdab9c841d96cd4aa4c1)よりRuby on RailsでWebサービスを開発しておりましたが、一部のサービスにおいてGoのアプリを実装・運用しています。

## 作業の大変さの見積もり

着手する前に工数の見積もりをしました。Goのminor versionのアップデートは過去に定期的にやっていたこともあるので、1アップデートを9-10回繰り返すというサブタスクを頭に描き、工数も単純な積算で見積もりを実施しました。サブタスクはGitHub Issuesにて管理しました。

## 1.x→1.11.5

2019年1月ごろに当時の最新マイナーバージョンを1.11.5にアップデートしました（ようです）。当時の担当者もいませんし、当時の当該担当者と面識のあるエンジニアもいませんので、運用中のものを調査して判明している事実です。

## まずはドキュメント

コードに対して変更を加える前に、わずかに残るドキュメントの更新を行いました。ドキュメントはGitリポジトリ中のMarkdownで管理されていたのは不幸中の幸いでした。

## OSベースバージョン

ベースとなっていたOSのバージョンはUbuntu 20.04 LTSでしたが、Ubuntu 22.04 LTSも出ていたということもあり、アップデートを実施しました。

OpenSSL 1.1→3.0などの外部接続周りでの影響も確認しましたが、問題は確認できなかったので、すぐさまリリースを行いました。リリース後も問題はありませんでした。

## 1.11.5→1.11.13

Minor revision（マイナーリビジョン）を上げるだけなので、特に問題は確認できず、ごく短時間でリリースをしました。

## 1.11.13→1.12.17

ここでいよいよ初めてのminor version（マイナーバージョン）のアップデートを実施しました。約4年ぶりのアップデートとなったので、少し怖さはありましたが、テストをきっちり実施することで安心して、アップデートをリリースしました。

## テスト環境の改善

このrepoではCircleCIをテスト・CI環境として利用していました。CircleCIのDockerベースのテスト環境ではベースイメージがcircleci/golangから[cimg/go](https://circleci.com/developer/images/image/cimg/go)への移行を実施しました。
https://circleci.com/docs/next-gen-migration-guide/ にもあるような移行ガイドを再読したり、Go 1.11以前から設定されていた `working_directory` の設定などもついでに見直しを実施しました。

## 1.12.17→1.13.15

こちらは二度目のminor version（マイナーバージョン）のアップデートということで特に問題もなく、テストを確認後、このアップデートをリリースしました。

## Glide設定削除

複数回のMinor versionアップデートも正常に終えて、Go 1.19への到達も楽勝かと思ったのですが、テスト周辺で[Glide](https://github.com/Masterminds/glide)への依存関係の残骸が残っていることに気づきました。Go modulesへの移行は完了していたのですが、CI設定に残骸・漏れがあったということでこちらの整理を実施しました。

## 1.13.15→1.14.15

Glideの軽い丘を超えてしまったので、単調な気配がしましたが、やはり単調でした。普通にアップデートを完了しました。

## 1.14.15→1.15.15

こちらも同様です。minor revisionが同じなので、単調感が増長されます。

## 1.15.15→1.16.15

こちらも同様です。minor revisionが同じなので、単調感が半端ないです。しかし、この時期はGo support policyに基づくcadence中に15個のminor revisionが出ていたことに気付けたのは（常に最新のminor versionしか使ってこなかった私には）新鮮でした。

## 1.16.15→1.17.13

Go 1.17はminor revisionのリリースが少なかったようです。運用の手間は減りますし、Go 1も安定感が増していることの表れだと思うので、とてもいいことですね。

## Go 1.17 go.mod形式

1.12.17にアップデートする際、 `go 1.12` エントリを書き足すくらい以外で `go.mod` に手を加えることはありませんでした。せっかくGo 1.17まで上げることができたので、ここらへんで、 `go mod tidy -go=1.17` を実行して、 `go.mod` を綺麗にすることにしました。

```bash
$ go mod tidy -go=1.17
```

以上を実行して、サクサク次に進みます。

と思ったのですが、Google CloudのApp Engine (standard environment)で、Go 1.17 runtimeが利用できる日は来るのでしょうかね。

## 1.17.13→1.18.8

ついに今年2022年春（2月ではなかった）にリリースされた、Go 1.18まで上げることにチャレンジしました。[generics](https://go.dev/doc/tutorial/generics)の導入も話題ではありますが、サポートされているminor versionへのアップデートを先行していきます。ARM最適化も進んでいますが、残念ながら、ARM CPU上で動かしていないので、特に恩恵を受けられませんでした。

> ## 20% Performance Improvements
> 
> Apple M1, ARM64, and PowerPC64 users rejoice! Go 1.18 includes CPU performance improvements of up to 20% due to the expansion of Go 1.17’s register ABI calling convention to these architectures. Just to underscore how big this release is, a 20% performance improvement is the fourth most important headline!
https://go.dev/blog/go1.18

## 1.18.8→1.19.3

ここまで来れば安心、Go 1.19はGo 1.20が出る来年2月直前でいいかと気を緩めてしまったのですが、やはり今年8月にリリースされたGo 1.19最新にしておきたい。頑張って最新にアップデートしました。
特に問題は起きずにアップデートをリリースすることができました。Go 1.19godocの改善がありましたが、godocの改善も2023年にはやっていきたい課題です。

## まとめ

Go 1.11ベースのGoアプリをGo 1.19までアップデートしました。 `go.mod` 周りやCI周りに変更を加えつつも、大きな変更がなくGo 1でアップデートできるのは、Rubyみたいな面倒くささはなくてすごいなと再認識させられた日々でした。

## おわび

本文中で触れた、App Engine standard environmentで使えるGoバージョンについてですが、本稿校正中に、無事Go 1.18, 1.19サポート（Preview）が発表されています。ぜひお試しください。
https://cloud.google.com/appengine/docs/standard/go/release-notes

---

**＼＼＼ みんせつ Advent Calendar 2022の第3日目の記事でした ／／／**

[みんせつ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/msetsu)

明日の記事のタイトルは未定ですが、担当者に催促しておきます。