GitHub Actionsでの事実婚契約ドキュメント管理を自動化した話
はじめに
突然ですが、結婚しました。
もう少し正確に言うと、私たちは婚姻届を出さずに「事実婚(いわゆる内縁)」の契約を結びました。
事実婚にはいくつかの形がありますが、私たちは同居した上で申請を行い、住民票に「妻(未届)」と記載される方式を選択しています。
この形式の事実婚は、法や民間制度の上でも一定の権利が認められるようになってきましたが、依然として法律婚と完全に同等の保障が得られるわけではありません。
そこで私たちは、婚姻契約書などの文書を作成・締結することで足りない部分を補い、できる限り法律婚に近いかたちにしていくアプローチをとることにしました。
どう管理するか
次に課題になるのが、その契約書をどう作り、どう管理するかです。
事実婚契約書は一度作って終わりというよりは、ライフステージの変化に合わせて内容を見直す運用ができた方が望ましいです。
仮にこれを素朴な文書作成ツールや手書きで運用したとすると、どのバージョンが最新なのか分からなくなるなどの問題が発生することが容易に想像できます。
日常的に更新や参照が発生する可能性も考慮した結果、
- 常に最新版を一元管理できること
- 必要になったときにすぐ更新できること
- 更新内容の差分を明確に把握できること
- 特に重要な文書は、テキストだけでなく合意の証跡を残せること
- できれば紙に印刷せず、電子的に完結できること
といった要件を抽出することができました。
検討の結果、今回のケースでは GitHub 上で Markdown 形式のドキュメントを一元管理し、GitHub Actions で PDF にビルド。特に重要な文書はその PDF をクラウドサインで署名・保存する、という運用[1]をしてみようということになりました。
契約管理対象ドキュメントの洗い出し
次に、どのような文章を整備する必要があるのかを検討し、以下のような文章を作成することとしました。
- 婚姻契約書
- 生活ルール
- 医療同意書
- 遺言証
婚姻契約書
事実婚契約の根幹をなす文書です。夫婦の基本的な取り決めを記載し、内容を更新した際には PDF 化したうえで別途クラウドサインで締結する運用を想定しています。更新頻度は低い見込みのドキュメントです。
生活ルール
婚姻契約書に付随する、もう少し粒度の細かい日常生活レベルの具体的な取り決めが書かれた文章です。婚姻契約書にすべて書く運用もけんとうしましたが、それは違うだろうということで、特に頻度高く更新するであろう内容の文章をもう少しマイルドな形で別添の文書として管理するようにした形です。生活のフェーズに応じて適宜内容を更新していくといった運用を想定しています。
医療同意書
双方に万一の事態があった場合に、パートナーが立ち会いや意思決定を行えるようにするための文書です。作成後は印刷し、署名したものを携帯する運用が必要です。
遺言証
相続に関する根拠となる文書です。文章は作成しましたが、法的効力を持たせるには自筆が必須[2]となるため、最終的には Git 管理せず手書きで完結させました。
技術的な詳細
挙げた要件を満たすために実際に構築した具体的な仕組みを紹介します。
1. Markdownで文書を管理
婚姻契約書や生活ルール、医療同意書などはすべて Markdown で記述し、リポジトリで管理します。
テキスト形式なので差分が見やすく、更新履歴や変更理由をそのまま Git のコミットとして残せます。
2. Pandoc + LaTeXでPDFを生成する
Markdown で書いた文書をそのまま PDF に変換するために、Pandoc と LaTeX を利用しています。
日本語文書を扱う場合、素の LaTeX では文字化けが発生するため、この構成では luatexja を利用し、Noto Serif CJK JP でレンダリングしています。
実際に使っている LaTeX テンプレートの例は以下の通りです。
% 12ptのフォントサイズでltjsarticleクラスを使用(日本語対応のLaTeXクラス)
\documentclass[12pt]{ltjsarticle}
% ページレイアウトの設定
\usepackage{geometry}
\geometry{margin=25mm} % 上下左右の余白を25mmに設定
% 行間の設定
\usepackage{setspace}
\setstretch{1.2}
% セクション見出しのフォーマット設定
\usepackage{titlesec}
\titleformat{\section}[display]{\bfseries\huge\centering}{}{0pt}{}
\titleformat{\subsection}{\bfseries\large\sffamily}{}{0pt}{}
% 日本語対応の設定
\usepackage{luatexja}
\usepackage{luatexja-fontspec}
\setmainjfont{Noto Serif CJK JP} % 日本語フォントに Noto Serif CJK JP を使用
% 段落間のスペース設定
\usepackage{parskip}
% PDFのハイパーリンク設定
\usepackage{hyperref}
\hypersetup{colorlinks=false, pdfborder={0 0 0}}
% セクション番号を非表示に設定
\setcounter{secnumdepth}{0}
\begin{document}
$body$
$if(version)$
\vfill
\begin{flushright}
\footnotesize
バージョン: $version$\\
$if(build_date)$
作成日: $build_date$
$endif$
\end{flushright}
$else$
$if(build_date)$
\vfill
\begin{flushright}
\footnotesize
作成日: $build_date$
\end{flushright}
$endif$
$endif$
\end{document}
3. Releaseを正式版として固定する
日常的な修正は通常のコミット/ブランチで行い、更新内容が固まったタイミングで GitHub の Release を作成する運用を採用しました。
Release が作成されると GitHub Actions が自動で PDF を生成し、成果物を Release に添付します。
これにより「どの版が正式な契約書か」を明確にでき、過去バージョンを遡って確認することも容易になります。
署名が必要な文書については、生成された PDF をダウンロードし、クラウドサインで締結・保管します。
つまり 「Releaseタグ=そのバージョンの契約書の確定版」 というシンプルなルールに集約できるわけです。
実際に利用している Actions の定義は以下の通りです。
# release.yml
name: Build and Upload Contract PDF on Release
on:
release:
types: [published]
jobs:
build-and-release:
runs-on: ubuntu-latest
container:
image: ghcr.io/tainakanchu/pandoc-ja:latest
steps:
- uses: actions/checkout@v4
- name: Make build.sh executable
run: chmod +x ./scripts/build.sh
- name: Convert Markdown to PDF
run: |
TAG_NAME="${GITHUB_REF#refs/tags/}"
./scripts/build.sh "$TAG_NAME"
- name: Create ZIP archive
shell: bash
run: |
TAG_NAME="${GITHUB_REF#refs/tags/}"
zip "partnership-agreement-${TAG_NAME}.zip" *.pdf
echo "Created ZIP: partnership-agreement-${TAG_NAME}.zip"
ls -la *.zip
- name: Upload ZIP as Artifact
uses: actions/upload-artifact@v4
with:
name: "partnership-agreement-${{ github.event.release.tag_name }}"
path: "*.zip"
- name: Upload to GitHub Release
uses: softprops/action-gh-release@v2
if: github.event.action == 'published'
with:
files: "*.zip"
token: ${{ secrets.GH_PAT }}
実際の PDF 生成は、Release のトリガーで build.sh を実行するだけです。
中では Pandoc を呼び出して docs/ 配下の Markdown ファイルをテンプレートに流し込み、PDF を出力しています。
特別な処理はしていないので、ここでは紹介を省きますが、興味のある方は後述のテンプレートリポジトリにあるスクリプトを参照してください。
4. Dockerでビルド環境を固定化
GitHub Actions の標準ランナーには LaTeX や日本語フォントが含まれていないため、その都度インストールするとビルドが遅く不安定になります。
そこで、Pandoc・LaTeX・日本語フォントをあらかじめ組み込んだ 自前の Docker イメージを用意し、Actions から利用するようにしました。
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
pandoc \
texlive-latex-base \
texlive-xetex \
texlive-lang-japanese \
texlive-luatex \
fonts-noto-cjk \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
そして事件
こうして結婚を自動化するシステムが完成しました。
CIも無事通り、いざクラウドサインを締結しようとしました。その時。。。

クラウドサインが臨時メンテに入りました。見ての通り日付が変わる超ギリギリで作業してたのが仇になりました。
その日中に締結を完了させたかったこともあり、電子契約前提の文言になっていたのを急遽修正し再ビルド、印刷したものをアナログで締結することになりました。[3]
テンプレートリポジトリ
同様の契約をやってみたいという方向けに、テンプレートリポジトリを作成してみました。興味のある方はぜひご覧になってください。
もちろん、このテンプレートを応用すれば事実婚に関連する契約書意外の用途としても汎用的に使うことも可能だと思います。
おわりに
とりあえず今のところ順調に稼働しています。
Discussion