◆ Gitlab だと CI/CD 機能を使う
◆ Gitlab では public という名前のフォルダが公開対象と決まってる
◆ .gitlab-ci.yml の設定で script で public に公開対象を作る
    ◆ 全体を公開するだけならテンプレートのままでいい
    ◆ .public は public の再帰回避用になってる
    ◆ public あるなら mv 前に消さないとマージされるし ないなら .public 通す必要ない
◆ artifacts:paths で public を指定する

私が作ってるのは基本ブラウザで実行できるものなので Gitlab に push したものがそこで表示できたら便利だなーと思って Pages を使うことにしました
Gitlab も Github みたいにプロジェクトごとに Pages でホスティングできるのですが 画面上で簡単設定じゃなくて CI/CD の機能を使うので少し複雑です

CI/CD の設定

CI/CD というと リポジトリに push したら自動でビルドやテストするような機能の一部なので ただ Web サーバでアクセスしたいという用途からすると オーバースペック感があるのですがそれしかないようです
単純にそのままリポジトリを Web サーバで公開する以外に SSG を使って HTML などを自動生成することもできます
スクリプトを実行できるので既存ツール以外に自分で作った変換処理を通すこともできそうです
しかし 今回はそういう処理はなしで単純に全体を公開するだけで十分です

.gitlab-ci.yml

設定はリポジトリのルートの .gitlab-ci.yml というファイルに書きます
全体をそのまま公開するだけならテンプレートそのままでいいです
リポジトリのトップ画面で 「CI/CD を設定」 ボタンを押せば出てくるエディタのテンプレートで 「HTML」 を選びます

自分で作るならこういう yml を追加して push します
これはテンプレートや公式ドキュメント中にあるものそのままです

pages:
stage: deploy
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- master

この script をいじればカスタマイズもできます
.public は public の再帰コピーを避けるための workaround らしいです
他の設定例を見る限り このときのカレントディレクトリはリポジトリのルートになってるみたいです
最初からリポジトリの public に公開したいものをいれてるリポジトリなら script は何もしないというのもありました

.public

直接 public にコピーする場合リポジトリに public があるとコピーできないので .public に一度コピーすることで public もコピーできるようにしてるようです
.public のように . から始まると cp の * の対象外になるので .public を .public にコピーできないというエラーにはならず また .public フォルダが .public の内部に作られません
これを public に移動してるので public には . から始まるもの以外の全体が含まれます……が リポジトリ自体に public というフォルダがあれば移動時にマージされて リポジトリ全体と元からリポジトリに存在する public のフォルダが混ざったものになるはずです
なので mv の前に rm -rf public を実行したほうが良い気がします
それか public フォルダがルートにあるなら そこが公開用のルートディレクトリとなるはずだから script は何も処理しないというのが良いのかもです

public

Gitlab ではリポジトリの public という名前のフォルダがデプロイされるらしいので public を使うなら .gitlab-ci.yml すらなくてもいいのかもです

https://docs.gitlab.com/ee/user/project/pages/#how-it-works
GitLab will always deploy your website from a very specific folder called public in your repository.

pages の script でやってることは public フォルダに公開したいものを持ってくるという処理です

逆に言えば このルールがあるせいで public という名前を別の用途で使ってるから public 以外の webroot とかの名前にするということもできなそうです
artifacts:paths に public を指定してるので これを別の名前に変えればいけそうと思ってたのですが artifacts は CI/CD を実行する環境 (docker?) から成果物を Gitlab に送信するときのパスを指定するもので public を指定したら public の中身だけが送られるのではなく 全体から指定のパスだけ残したフォルダが送信されるみたいです
配列になっていて複数指定できますし そのほうが自然です
実際にジョブの実行結果から artifacts をダウンロードして確認してもダウンロードされたのは public の中身ではなく public というフォルダを含むフォルダでした
Gitlab が public という名前を公開対象のフォルダとして決めてる以上 Pages 機能を使うなら artifacts:paths には public を指定するしかないです

まとめ

.public は存在しないフォルダ名にする
ただし最初の . は必要
public が公開フォルダになるので すでに public が存在して リポジトリ全体を公開するなら .public にコピー後に public は消してマージされないようにしたほうが良い
public が存在しないなら .public 通さなくても問題なし

反映されるのは遅め

CI/CD という仕組みな以上 即反映されません
push したらジョブが実行されるので実行を待ちます
終わってもすぐには反映されないようです
artifacts をダウンロードできる状態なのに 404 がしばらく続きました

原因がわからなくてあれこれ調べてもわからず一旦諦めて別のことしたあとに 1 時間くらいしてもう一度アクセスしたら見れるようになってました