GitHub ActionsでAWS S3にSwift DocCをデプロイしようとしてできない
Swift/Kotlin愛好会 Advent Calendar 2023の18日目の記事です。18日目の記事です。
はじめに
みなさん Swift DocC 使ってますか?
私は DocC 大好きです。特にTutorialが好きで、よく使ってます。
DocCはGitHub Actions経由でGitHub Pagesで公開するのが定石となっており、こちらの方法はたくさん記事が出ています。
使いたい GitHub Organization がエンタープライズプランであれば、リポジトリにアクセス権のある人だけが見られるようにアクセス制御を行うこともできてとても便利です。
でも GitHub Organization がエンタープライズじゃなければ...?
Enterprise プランは Team の5倍のお値段するので、これだけのためにアップグレードするのは躊躇ってしまいます..。 しかし、一部の人だけにドキュメントを公開したい場面は多々あると思います。
...という苦しみの末に、どうしても Swift DocC を使いたい人が AWS S3 で静的サイトホスティングを行い、 GitHub Actions で CI/CD を実現しようとして上手くいかなかった話です。(本当は解決してから記事を出したかったんですが、時間なさすぎて諦めました。わかる方教えてください🤲)
結論
サイトをホストする用のS3バケットを作成してウェブサイトのホスティングの有効化を行い、この GitHub Actions を仕込むと、S3にアップロードするところまではできます。
※ Xcode15を使用している想定です
name: DeployDocc
on:
workflow_dispatch:
push:
branches:
- main
jobs:
build:
runs-on: macos-13
env:
DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
steps:
- uses: actions/checkout@v3
- name: Build docc
run: |
cd Tutorial
swift package \
--allow-writing-to-directory ../docs \
generate-documentation \
--target Tutorial \
--disable-indexing \
--transform-for-static-hosting \
--hosting-base-path . \
--output-path ../docs
cd ..
- name: Create tar file
run: |
chmod -v -R +rX "./docs/" | while read line; do
echo "::warning title=Invalid file permissions automatically fixed::$line"
done
gtar \
--dereference --hard-dereference \
--directory "./docs/" \
-cvf "$RUNNER_TEMP/docs.tar" \
--exclude=.git \
--exclude=.github \
.
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: docs
path: /Users/runner/work/_temp/docs.tar
retention-days: 1
if-no-files-found: error
deploy:
needs: build
environment: Develop
runs-on: ubuntu-latest
steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: docs
path: .
- name: Extract And Delete tar file
run: |
tar -xvf docs.tar
rm docs.tar
- name: Configure AWS crredentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ap-northeast-1
- name: Upload to S3
env:
S3_UPLOAD_BUCKET: ${{ vars.S3_BUCKET_NAME }}
run: |
aws s3 sync . s3://$S3_UPLOAD_BUCKET/ --delete
GitHub Actionsの解説
まず前半のジョブの解説です。
ここでは、静的サイトホスティングができるように変換し、artifactsに一時保存しています。
GitHub ActionsでmacOSを使うとストレージをめちゃくちゃに食い潰すので必要最小限に抑えています。
-
Xcode15で作っていたため、
macos-13
及びXcode_15.0.1.app
でセットアップしています。jobs: build: runs-on: macos-13 env: DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
-
Swift-DocC Pluginを使用して静的サイトホスティングができる形式に変換します。
targetやホスティングベースパスは以下を参考に適宜環境に合わせて書き換えてください。
https://apple.github.io/swift-docc-plugin/documentation/swiftdoccplugin/publishing-to-github-pages/steps: - uses: actions/checkout@v3 - name: Build docc run: | cd Tutorial swift package \ --allow-writing-to-directory ../docs \ generate-documentation \ --target Tutorial \ --disable-indexing \ --transform-for-static-hosting \ --hosting-base-path . \ --output-path ../docs cd ..
-
一度tarファイルに圧縮します。
これは、2の手順で変換したものをリポジトリ内に保存するとリポジトリが汚染されて好ましくないため artifacts に一時的に保存したいのですが、変換すると謎のコロンを含むファイルを含んでいてエラーになってしまう事情があり、一度tarファイルに圧縮しています。- name: Create tar file run: | chmod -v -R +rX "./docs/" | while read line; do echo "::warning title=Invalid file permissions automatically fixed::$line" done gtar \ --dereference --hard-dereference \ --directory "./docs/" \ -cvf "$RUNNER_TEMP/docs.tar" \ --exclude=.git \ --exclude=.github \ .
-
artifactsに3で圧縮したtarファイルをアップロードします。
- name: Upload artifact uses: actions/upload-artifact@v3 with: name: docs path: /Users/runner/work/_temp/docs.tar retention-days: 1 if-no-files-found: error
このジョブは不安になるほど時間がかかりますが、macOS13ランナーのXcode15のビルド時間自体がなぜかめちゃくちゃ遅くなるので、耐えます。解決策プリーズ🤲 コストが不安になりますが、そう頻繁に更新するものじゃないから・・・と私は言い聞かせてます。
そして後半のS3アップロード部分の解説です。
前述のmacOSランナーでの実行にコストの不安を感じるため、ここはubuntuを使っています。
-
3、4で圧縮・アップロードしたtarファイルをダウンロード・解凍しています。
ダウンロードしたらtarファイルをartifactから削除しておきます。deploy: needs: build environment: Develop runs-on: ubuntu-latest steps: - name: Download artifact uses: actions/download-artifact@v3 with: name: docs path: . - name: Extract And Delete tar file run: | tar -xvf docs.tar rm docs.tar
-
AWSの認証を通し、S3にアップロードします。
この時、リポジトリにDevelop
Envirionmentを作成し、以下の値をEnvironment secretsおよびEnvironment variablesに設定しています。-
AWS_ACCESS_KEY
(secrets): S3にアップロードできる権限をつけたIAMのアクセスキー -
AWS_SECRET_KEY
(secrets):S3にアップロードできる権限をつけたIAMのシークレットキー -
S3_BUCKET_NAME
(variables):アップロードしたいS3バケット名
- name: Configure AWS crredentials uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }} aws-region: ap-northeast-1 - name: Upload to S3 env: S3_UPLOAD_BUCKET: ${{ vars.S3_BUCKET_NAME }} run: | aws s3 sync . s3://$S3_UPLOAD_BUCKET/ --delete
-
S3側の設定
-
静的ウェブサイトホスティングを有効化します。
-
とりあえずブロックパブリックアクセスを全てオフにします。
-
バケットポリシーを設定して外部から読み取れるようにします。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::hoge/*" } ] }
でも上手く動かない🫠
このように 「An unknown error occurred.」 と表示されてしまい、内容が表示されないのです。
コンソールを確認したところ、 theme-settings.json
が見当たらないそうです。
theme-settings.json
はXcode15で登場した、webで公開するときにdoccのドキュメントを他コンテンツに合うような見た目にしたいときに使えるテーマを設定するJSONです。
でもこれ無くても良かったのでは...?と思いつつ、大人しく追加してみました。
するとどうでしょう!
何も変わりません!
コンソールを見てみると、もはやウンともスンとも言わなくなってしました!お手上げです!
どうして〜?
アドベントカレンダーの担当日どころかクリスマスも過ぎそうだったので諦めて途中経過で出しました。
有識者の方、アンサー記事をお待ちしております。
Discussion
私もそれにハマったのですが、以下のIssueの最後のコメントに書いてあって、
swift package --disable-sandbox preview-documentation
をローカルで実行した際に出てくるURLのパスがあるので本番環境でもhttps://hostname/documentation/passkeyにアクセスしたら私の場合は見れました。