OSSドキュメント翻訳を支える技術 (Keycloakを題材に)

[Keycloak by OpenStandia](https://qiita.com/advent-calendar/2017/keycloak-by-openstandia)の11日目は、ちょっとKeycloakそのものからは離れたトピックとして、OSSのIAMプロダクトであるKeycloakのドキュメント翻訳を題材に **OSSドキュメントの翻訳を支える技術** について書きたいと思います。今後何かしらのOSSの翻訳をやってみたい:exclamation:という方には役立つネタかもしれません:thumbsup_tone2:

# モダンOSSドキュメント翻訳フロー
はじめに、翻訳作業全体の流れについて説明します。

最近のOSSはソースをGitで管理し、変更をGitHubなどのプルリクエスト機能により反映しつつ、CIサービスを使って自動ビルド/リリースを行う開発スタイルが多いかと思います。ドキュメント翻訳についても同様のフローで行うことで、以下のようなメリットがあると考えています。

* 翻訳リソースがバージョン管理される
* プルリクエストなどでレビュープロセスをきちんと通して翻訳内容が取り込まれる
* CircleCIやTravis CIと連携して、プルリクエスト時に自動的に静的チェックを走らせたり、プレビュー版を生成してレビューすることが可能
* (GitHubの場合は)翻訳作業が[GitHub Contribution](https://help.github.com/articles/viewing-contributions-on-your-profile/)として加算され、貢献度が可視化されることで参加者のモチベーションアップにつながる
* 最終的な翻訳版ドキュメントの公開まで自動化ができ、運用負荷を下げることができる

Keycloakドキュメントの翻訳では、今のところ下図のようなフロー/ツール・サービス群で翻訳作業を行っています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35233/1c5c764a-b4fe-ce73-d600-fcee7bb5189e.png)


1. 翻訳者は、翻訳支援サービスであるTransifexを利用して翻訳作業を行います。
2. 翻訳を終えると自動的にGitHubにプルリクエストが送られます([実際の例](https://github.com/openstandia/keycloak-documentation-i18n/pull/280))。
3. プルリクエストと同時にCircleCIにて翻訳版ドキュメントの自動ビルドが行われます。
4. 完了後、ホスティングサイトにアップロードされプレビューが可能になります。
5. 翻訳レビュアーはTransifex上で訳文のチェックを行います。必要であれば生成されたプレビュー版のドキュメントも参照しつつチェックします。指摘事項がある場合は翻訳者に修正してもらう、または直接修正を行い、レビュー完了とします。
6. レビューが完了すると、レビュー指摘分がGitHubに追加pushされます。
7. 再度CircleCIにて自動ビルドが行われます。
8. レビュー完了版がホスティングサイトにアップロードされプレビューが可能になります。
9. プルリクエストマージ担当はプレビュー版を確認しつつ、developブランチにマージを行います。
10. 再度CircleCIにてdevelopブランチの自動ビルドが行われます。
11. developブランチ版がホスティングサイトにアップロードされ参照可能になります。
12. リリースの場合はmasterブランチへのプルリクエストを作成し、masterブランチにマージを行います。
13. 再度CircleCIにてmasterブランチの自動ビルドが行われます。
14. CIにより[公開用サイト](http://keycloak-documentation.openstandia.jp/)へのアップロードを行います。

以降では、各プロセスの詳細な取り組みであったり技術的な内容について紹介していきます。


# 翻訳方式について
次に、翻訳方式(具体的に何をソースとして翻訳していくのか)について軽く述べます。

一般的に、OSSのドキュメントはWebとの親和性からHTML形式で公開されていることが多いでしょう。また、ドキュメントのメンテナンス性を考慮して、直接HTMLを記述することはせずに、Markdownなどのテキストベースのフォーマットを利用してドキュメントを記述していき、各種ツールにより公開用のHTMLやPDFを生成しているケースが多いかと思います。

このようなドキュメントの場合、翻訳方式としては

1. 最終的なアウトプットのHTMLの翻訳を行いHTMLを作成する。
2. HTMLのソースとなるテキストベースのファイルの翻訳版を作成し、翻訳版のHTMLを生成する。
3. ツールでソースのテキストベースのファイルからテキスト抽出を行い、翻訳後に元の文章にマージし、翻訳版を生成する。

のような方式があります。各方式の特徴を下表にまとめます。

|方式|1. HTMLを直接翻訳|2. ソーステキストを翻訳|3. テキスト抽出して翻訳|
|:---|:---|:---|:---|
|ツールチェインの構築|不要|必要|大変|
|翻訳量|大 (目次等の自動生成箇所も対象)|中|小 (スタイル部分は極力除外される、同一文章は1回の翻訳だけで済む)|
|元ドキュメント変更への追随|大変[^1]|大変[^1]|容易 (構成やスタイルが変わっても影響を受けにくい)|
|PDF等他フォーマットへの対応|大変|容易|容易|

[^1]: [Transifex](https://www.transifex.com)や[GitLocalize](https://gitlocalize.com)のようなHTMLやMarkdownなどのファイルフォーマットに対応した翻訳支援サービスを活用することで、ある程度緩和はされるかもしれません。

Keycloakドキュメントの翻訳ではどうしているかというと、3つ目の**テキスト抽出した部分のみを翻訳**の方式を採用しています。というのも、現状、毎月のように最新版がリリースされており、ドキュメントもどんどん変わっていく恐れがあると思い、**変更に追随しやすい(はず)**、**翻訳者は翻訳作業だけに集中できる**、という点から3つ目の方式を今のところは採用しています。


# ソーステキストからのテキスト抽出について
方式3を取る場合、テキスト抽出を行い、翻訳後に元のテキストにマージする仕組みが重要になってきます。というわけで、次はテキスト抽出について述べます。


## 翻訳対象のソーステキストフォーマット
テキスト抽出を行うためには翻訳対象のソーステキストフォーマットが重要なポイントになってきます。OSSドキュメントで利用される代表的なテキストベースのドキュメント作成ツール/マークアップ言語としては以下があります。

* [Asciidoctor](http://asciidoctor.org) - [AsciiDoc](http://asciidoc.org)に対応(Markdown記法にも一部対応)
* [DocBook](http://docbook.org) - [DocBook Schema](http://docbook.org/schemas/)に従ってXMLで記述
* [GitBook](https://www.gitbook.com) - [Markdown](https://toolchain.gitbook.com/syntax/markdown.html)と[AsciiDoc](https://toolchain.gitbook.com/syntax/asciidoc.html)に対応
* [Pandoc](https://pandoc.org/) - MarkdownやreStructuredText、Docbookなど多様な入力形式・出力形式に対応
* [Sphinx](http://www.sphinx-doc.org) - [reStructuredText](http://docutils.sourceforge.net/rst.html)と[Markdown](https://github.com/rtfd/recommonmark)に対応

Keycloakでは少し前(バージョン3.3系まで)は、[GitBook(つまりMarkdown)](https://www.gitbook.com)で書かれており、HTML化されて公開されていました。しかしながら、開発スポンサーであるRed Hat社の方針により、バージョン3.4.0にて[AsciiDoc](http://asciidoc.org)(ツールは[Asciidoctor](http://asciidoctor.org)を利用)に移行となっています。

なお、個人的にはMarkdown派だったのですが、AsciiDocの[テーブル記法](http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#tables)(Asciidoctor独自記法かも?)は非常に書きやすく、Markdownで書いているドキュメントをAsciiDocに鞍替えしたくなってきました:smirk:

## テキスト抽出方式
ここは、前述のドキュメント作成ツールに何を使っているかによって方式が変わってきます。例えば、Sphinxを利用している場合は、[Sphinxの国際化機能](http://docs.sphinx-users.jp/intl.html)を使うことができます。

Keycloakドキュメントの場合は前述のとおりAsciidoctorを使っていますが、[国際化機能のデザインドキュメント](https://github.com/asciidoctor/asciidoctor/wiki/Design-Doc:-i18n)はあるものの、まだ実装はされていません。

そこで、AsciiDocからうまくテキスト抽出して翻訳できないかツールを探してみると、同じAsciiDoc形式を採用しているOSSのドキュメントとして、[Clojure](https://clojure.org)を発見しました。[clojure-site 日本語訳プロジェクト](https://github.com/japan-clojurians/clojure-site-ja)を見ると、ここでは[po4a](https://po4a.alioth.debian.org)というツールが使われています。Keycloakドキュメントの翻訳でも、Clojureに倣いpo4aを使ってテキスト抽出を行うようにしました。というわけで、以降はpo4aについて詳細を説明します。

なお、Sphinxの国際化機能もそうですがpo4aは[gettext](https://www.gnu.org/software/gettext/)のPOファイルを利用した翻訳という昔からある技術で行われています。この方式は、豊富なgettext用ツールが使えるというメリットはあるものの、個人的にはとっつきにくいなぁという印象があります。ただし、po4aを使っておけばかなり隠蔽化してくれるので、最初のセットアップさえ乗り越えれば後は楽だと思います。


## po4aについて
[po4a(PO for anything)](https://po4a.alioth.debian.org/)とは、gettextが想定していないドキュメントのような領域で、POファイルを使った翻訳管理を行うためのツールです。[Supported formats](https://po4a.alioth.debian.org/features.php)を見ると、MarkdownやAsciiDocにも対応しています。

gettext自体はソフトフェアの国際化のためのものであり、ドキュメントを対象としては想定していません。そこでpo4aを使うと、ドキュメントを対象に翻訳対象の文字列をPOTファイルとして抽出し、翻訳後のファイルとして翻訳者がPOファイルを作成することで、元の文章とマージして翻訳後のテキストファイルに変換することができます。po4aを使うことで、以下の流れで翻訳を行い最終的なHTMLを生成できるようになります。

1. po4aでAsciiDoc形式のファイルからPOTファイルを生成
2. POTファイルをコピーして翻訳言語用のPOファイルを作成
3. POファイルに翻訳メッセージを記述
4. po4aでAsciiDoc形式のファイルとPOファイルをマージして、翻訳後のAsciiDoc形式のファイルを生成
5. Asciidoctorで翻訳後のHTMLファイルを生成

上記のうち、翻訳者には3番だけ実施してもらうように役割分担することができます。POファイルの編集ツールとしては[Poedit](https://poedit.net/)や[OmegaT](http://omegat.org/)があります。または、最近だと翻訳支援サービスがSaaSで提供されており、POファイルに対応しているところもあります([Transifex](https://www.transifex.com)や[Crowdin](https://crowdin.com/)など)。このようなツールを活用すれば、翻訳者は翻訳作業にだけ集中することができ、翻訳作業がスケールしやすいかと思います。

翻訳後に元ドキュメントが更新された場合は、po4aを再度実行することで、変更箇所のメッセージには `fuzzy` というキーワードでマーキングされます。`fuzzy` とされたメッセージに関しては、POファイルとのマージ時に翻訳されずに元のままとなります。また、新規に文章が追加されていた場合は、新たな翻訳対象メッセージとして追加されます。つまり、以下の作業フローで元ドキュメントの変更に追随ができます。

1. po4aでPOファイルを更新
2. POファイルに新たに新規メッセージがあれば、翻訳を追加する
3. POファイルの `fuzzy` 箇所があれば、翻訳を修正する

po4aについては、Qiitaに [nginx をネタに po4a で翻訳管理を始めてみる例](https://qiita.com/nabetaro/items/fe05e35b48dad3566a02) という記事が過去にあったりしますので、そちらを読むと理解が進むかと思います。


## po4aの設定
po4aでは、`po4a.cfg` というファイルを作成して、翻訳対象のソースとその形式、POT/POファイルの出力先を設定します。以下はKeycloakドキュメント翻訳で使用している設定例です。

```txt:po4a.cfg
[po4a_langs] ja_JP
[po4a_paths] i18n/pot/$master.pot $lang:i18n/po/$lang/$master.$lang.po

[po4a_alias:myadoc] asciidoc opt:"-k 0 -M utf-8 -L utf-8"
[po4a_alias:mytext] text opt:"-k 0 -M utf-8 -L utf-8 -o asciidoc -o neverwrap"

# aggregation
[type: myadoc] source/aggregation/navbar.html $lang:translated/$lang/aggregation/navbar.html master:file=aggregation/navbar add_$lang:i18n/po/$lang/aggregation/navbar.$lang.add

# getting_started
[type: myadoc] source/getting_started/master.adoc $lang:translated/$lang/getting_started/master.adoc master:file=getting_started/master
[type: myadoc] source/getting_started/topics/first-boot/admin-console.adoc $lang:translated/$lang/getting_started/topics/first-boot/admin-console.adoc master:file=getting_started/topics/first-boot/admin-console
[type: myadoc] source/getting_started/topics/first-boot/boot.adoc $lang:translated/$lang/getting_started/topics/first-boot/boot.adoc master:file=getting_started/topics/first-boot/boot
...
```

上記のように、AsciiDoc(*.adoc)の1ファイルに対して1つずつ設定する必要があります。翻訳対象のソーステキストがたくさんあると設定を書くだけでも大変なので、シェルスクリプトなどで自動化しておくと良いでしょう。Keycloakドキュメントの翻訳作業では、[update-po4acfg.sh](https://github.com/openstandia/keycloak-documentation-i18n/blob/master/update-po4acfg.sh)というシェルスクリプトを用意し、`po4a.cfg`を翻訳対象のAsciiDocファイルから自動生成するようにしています。


## po4aのAsciiDoc対応は微妙...?
実際にKeycloakドキュメントの翻訳でpo4aを使ってみたところ、いくつか課題に遭遇しました。

1. AsciiDocのマクロを使っていると正常にテキスト抽出できない
    * 多分、[#10 asciidoc: ifdef::<>[] macros are not supported](https://github.com/mquinson/po4a/issues/10) のバグと思われる
    * これについては最新版をソースビルドすることで対応できた
2. Asciidoctorの拡張書式であるいくつかのMarkdown書式に対応していない
    * [AsciidoctorのMarkdown Compatibility](http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#markdown-compatibility)に記載のスタイルをKeycloakドキュメントでは使用しており、うまく抽出できない
3. AsciiDocのテーブル基本に対応しきれていない
    * [AsciidoctorのTables](http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#tables)に記載のスタイルをKeycloakドキュメントでは使用しており、うまく抽出できない

上記課題対応でpo4aに修正パッチをプルリクエストしようかと思いましたが、ソースを見てみると **[正規表現でひたすら頑張るという実装](https://github.com/mquinson/po4a/blob/5008a5460872edcc7649ab1fe176b1656df9bd48/lib/Locale/Po4a/AsciiDoc.pm#L344)**になっており、これは辛い＆さらなる負債を作り込んでしまうと思い、一旦断念しました。というわけで、Keycloakドキュメント翻訳では、[独自パッチ](https://github.com/openstandia/keycloak-documentation-i18n/blob/master/AsciiDoc.pm)を当ててひとまず対応しています:sweat:


# SaaSを利用した翻訳作業
po4aによりPOTファイルとしてテキストを抽出できましたので、次はこれを翻訳言語ごとにPOファイルを作成することになります。POT/POファイルは単なるテキストファイルなので、テキストエディタで翻訳作業を行うこともできますが、

* POファイルのフォーマットを誤って壊さないように専用のエディタで安全に翻訳したい
* 翻訳結果を[翻訳メモリ](https://ja.wikipedia.org/wiki/%E7%BF%BB%E8%A8%B3%E3%83%A1%E3%83%A2%E3%83%AA)として翻訳者間で共有したい
* 用語集を翻訳者間で共有したい
* 機械翻訳を活用して効率化したい
* 翻訳結果のレビューを効率よく行いたい

という点から、翻訳支援サービスを使うのがオススメと思っています。特に、OSSの翻訳となると、ありがたいことに有償のサービスが無料で提供されています。今回、以下のサービスを試してみました。

* [Crowdin](https://crowdin.com) - [OSSプロジェクト向けに無料プラン](https://crowdin.com/page/open-source-project-setup-request)あり
* [GitLocalize](https://gitlocalize.com) - 小規模向けに無料プラン、OSS向け無料プランあり
* [Google Translator Toolkit](https://translate.google.com/toolkit) - 無料
* [Transifex](https://www.transifex.com) - [OSSプロジェクト向けに無料プラン](https://docs.transifex.com/faq/all#what-is-considered-an-open-source-project)あり
* [Weblate](https://weblate.org) - 自前で構築するなら無料、ホスティングサービスは有料だが[フリーソフトウェア向けに無料プラン](https://weblate.org/ja/hosting/#free)あり

とりあえず一通り試してみて、独断ですが以下の評価になりました。

|評価項目|Crowdin|GitLocalize|Google Translator Toolkit|Transifex|Weblate(ホスティング版)|
|:---|:---|:---|:---|:---|:---|
|POファイル対応|:white_check_mark:|:x:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|翻訳メモリ|:white_check_mark:|:x:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|機械翻訳|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|用語集|:white_check_mark:|:x:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|GitHub連携|:white_check_mark:|:white_check_mark:|:x:|:x:|:white_check_mark:|
|REST API提供|:white_check_mark:|:x:|:x:|:white_check_mark:|:white_check_mark:|
|翻訳完了時のWebhookによる通知|:x:|:white_check_mark:|:x:|:white_check_mark:|:white_check_mark:|
|翻訳リソース制限なし|:x:|:x:|:white_check_mark:|:white_check_mark:|:x:|
|レビュー機能|:white_check_mark:|:white_check_mark:|:x:|:white_check_mark:|:white_check_mark:|
|コメント機能|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|翻訳に使用しているOSS例|[Electron](https://github.com/electron/electron-i18n)|[Vue.js](https://github.com/vuejs/vue-ssr-docs), [WebFundamentals](https://github.com/google/WebFundamentals)|?|[VSCode](https://github.com/Microsoft/Localization/wiki/Visual-Studio-Code-Community-Localization-Project)|[Debian](https://anonscm.debian.org/cgit/debian-handbook/debian-handbook.git/tree/README.translators)|

以下、詳細な評価コメントです。

* Crowdin
    * 一番インパクトがあるのが**翻訳リソース制限**でした。Keycloakドキュメントの翻訳対象ドキュメントはそこそこあり、Crowdinに全部インポートするとOSSプランの上限を超えてしまい、使えないことが判明しました。
    * GitHub連携機能はあるものの、なぜか1コミットずつpushしてくるため、**CIサービスと連携しているとビルドジョブがたまりまくる**という自体になり、正直いまいちでした([実際の例](https://github.com/openstandia/keycloak-documentation-i18n/pull/34))。
    * また、GitコミットにはCrowdin-GitHub連携で使用するGitHubアカウントが使われるため、翻訳貢献者のContributionにならないのも悲しいところです。
* Google Translator Toolkit
    * 制限はなさそうでしたが、残念ながらREST APIが提供されておらず、POファイルのアップロードや翻訳結果をGitHubに戻すといったことが自動化できなさそうでいまいちでした。
    * Googleはこのサービスはあんまりやる気はないのでしょうか...?
* GitLocalize
    * OSS向けプランでは100,000セグメント(≒パラグラフ)で十分な容量でしたが、POファイルやAsciiDocには未対応であり、翻訳メモリや用語集の機能がなく今回は見送り。
    * ただ、コンセプトとしてGitHub連携を最初から想定したものなので、GitHub連携はすばらしく、まだまだ新しいサービスなので今後に期待しています:exclamation:
* Transifex
    * OSS向けプランではリソース制限はなく、GitHub連携がない点だけを他の手段でカバーできれば良さそうです。
    * 幸いなことに、REST APIが提供されており、かつWebhookで翻訳時にTransifexから情報をpushすることもできるので、連携部分はカスタマイズでなんとかなりそうです。
* Weblate
    * [Weblateのホスティング](https://weblate.org/ja/hosting/)のフリーソフトウェア向けプランでは、翻訳コンポーネント数(=翻訳対象のPOファイル数)が**25**と限られており、これもリソース制限となり駄目でした。
    * リソース制限が早々に判明したのであまり深く利用はしていませんが、Gitとの連携は良さそうな雰囲気でした。po4a自体のドキュメント翻訳でも使われているのですが、Weblateからプルリクエストが送られAuthorにちゃんと翻訳者が記録されていて良い感じ([実際の例](https://github.com/mquinson/po4a/pull/51))。
    
というわけで、Keycloakドキュメント翻訳では、WebhookでなんとかGitHub連携さえすればよさそうな**Transifex**を今は選択しています。GitHub連携部分については次に続きます。


# Transifex-GitHub連携をなんとかする
自前でサーバを建てれるなら、TransifexがオフィシャルにOSSで提供しているGitHub連携ツールの [github.com/transifex/txgh](https://github.com/transifex/txgh) を使うのが簡単かもしれません。しかし、クラウドを使うにしてもずっとインスタンスを立ち上げる必要があるため、自腹を切るのは痛いところです。また、プルリクエストの発行まではやってくれなさそうで機能的にも不満があります。

txghの実装をみるとやっていることは単純で、

* Transifexでの翻訳完了時に、Webhookで通知をHTTPで受けとる
* 受け取った通知をもとに、GitHub APIを呼び出し翻訳結果をコミット(push)

というものでしたので、HTTPしか扱わないなら**Amazon API Gateway + AWS Lambdaでサーバレスで簡単に実装できるんでは？**と思い自作することにしました。

作ったもの: [github.com/wadahiro/txgh-serverless](https://github.com/wadahiro/txgh-serverless)

今回は[Serverless Framework](https://serverless.com/framework/)を使用して開発してみました。使い方は、[Node.js](https://nodejs.org/ja/)をインストールした環境にて、[README](https://github.com/wadahiro/txgh-serverless/blob/master/README.md)の手順でデプロイしてもらえれば即使えます。これを使うと、Transifex上で翻訳が完了するとGitHubにプルリクエストが自動発行されるようになります([実際の例](https://github.com/openstandia/keycloak-documentation-i18n/pull/281))。なお、~~サボって~~GitHub側のソースが更新された場合のTransifex側への反映まではまだ実装しておりません:bow_tone1: 残念ながらこの部分は手動で[TransifexのCLIツール](https://docs.transifex.com/client/introduction)を実行してPOTファイルをインポートしています(POTファイルをインポートしてTransifexで翻訳すると、言語ごとにPOファイルが出力されます)。

これなら運用にかかる費用もかなり安くおさえられそうです。参考までに東京リージョンだと

* Amazon API Gateway
    * 100万回のAPI 呼び出しの受信につき4.25USDのレートに、データの送出の費用がギガバイト単位で加算
    * 最初の10TBにつき、0.14USD/GB
* AWS Lambda
    * 1ヶ月に1,000,000件のリクエストおよび400GB-秒は無料

という料金です。翻訳作業の流量なんてたいしたことなく、またAWSは1年間無料枠があるので、余裕でしばらくは0円で運用できそうです:thumbsup_tone2:


# CI環境について
po4aの実行やドキュメント生成をCIで動かすため、Dockerコンテナが使えるCIサービスがオススメです。ツールによっては結構環境依存問題がありますので...

Keycloakドキュメント翻訳では、CircleCIを使っており、po4aの実行のためコンテナを用意しています([Dockerfileはこちら](https://github.com/openstandia/keycloak-documentation-i18n/blob/master/Dockerfile))。po4aをソースビルドしていますので、最新版のpo4aを使いたい方は参考になるかもしれません。なお、KeycloakドキュメントはRuby製のAsciidoctorでHTMLを生成しますが、Java(JRuby)上で動かしておりMavenからキックするようになっているため、このコンテナにはMavenもインストールしています。

なお、現状まだできてはいませんが、CIで翻訳結果の**静的チェック**を機械的に実行することで、翻訳品質を高めることもできそうです。Keycloakドキュメント翻訳では、翻訳スタイルとして[日本翻訳連盟](https://www.jtf.jp/jp/style_guide/styleguide_top.html)で公開されている[JTF日本語標準スタイルガイド（翻訳用）](https://www.jtf.jp/jp/style_guide/pdf/jtf_style_guide.pdf)を参考にしていますが、[textlint](https://textlint.github.io/)の[JTF用ルールセット](https://github.com/textlint-ja/textlint-rule-preset-JTF-style)を使うことでチェックを自動化できそうです。ここは今後改善したいポイントではあります:point_up_tone2:

# 翻訳ドキュメントのホスティングについて
CIによりようやく翻訳ドキュメントが生成されました。最後は公開用にホスティングですが、無料で済ませるなら[GItHub Pages](https://pages.github.com/)を使うといいかもしれません。

Keycloakドキュメント翻訳の場合は、公開先は[NRI OpenStandia](http://openstandia.jp/)のサイトを利用している関係上、OpenStandiaで利用しているAWSのS3にアップロードしてCloudFront経由で外部公開しています。アップロードはもちろんCIから自動的に行われるようにしています。[aws-cliでS3と同期](https://github.com/openstandia/keycloak-documentation-i18n/blob/dd2e7c0aaacff72f6da3e83938abebd00f00e540/.circleci/config.yml#L86-L87)させるだけなので簡単ですね。


# 最後にKeycloakドキュメント翻訳についてご紹介

最後に、Keycloakドキュメントの翻訳について簡単に紹介しておきたいと思います。OSSのIAM（Identity Access Management）プロダクトである[Keycloak](http://www.keycloak.org)では、各種ドキュメントが[KeycloakのサイトのDocumentationページ](http://www.keycloak.org/documentation.html)で読むことができます。最新バージョンである Keycloak 3.4.1.Final(2017/12/11時点) では、下記の構成になっています。

* Guides
    * Getting Started - Keycloak入門編
    * Server Installation - インストール方法
    * Securing Apps - アプリケーションの保護方法
    * Server Admin - Keycloakサーバの管理方法
    * Server Development - Keycloakサーバーのカスタマイズ方法
    * Authorization Services - 認可サービスについて
    * Upgrading - アップグレード方法について
* API Documentation
    * JavaDoc - KeycloakのAPIのJavaDoc 
    * Administration REST API - 管理REST API仕様について

Keycloakドキュメント翻訳の活動では、上記の**Guides**の部分の翻訳をターゲットとして活動しています。[GitHub](https://github.com/openstandia/keycloak-documentation-i18n)に翻訳用プロジェクトを用意していますので、興味がある方は[ContributingのWikiページ](https://github.com/openstandia/keycloak-documentation-i18n/wiki/Contributing-ja_JP)をご覧になって、プロジェクトへ参加していただければと思います:grin: