継続的”原稿”デリバリーのすすめ〜原稿執筆でも継続的デリバリーをする〜

先日『Backlogを作ってるエンジニアが教えるBacklog活用術』という記事をエンジニアHub様で執筆した中村です、こんにちは。

こちらの記事の執筆環境を整えるために、ソフトウェア開発の継続的デリバリーの概念をもとに「執筆初期から最終原稿に近い形式で確認できるようにする」という環境を構築しました。

この「継続的原稿デリバリー」が思いのほかうまくはまったので、その実践方法とやってみた感想をご紹介します。

コンセプト:最初から最終原稿に近い形式でデリバリーする

コンセプトは「継続的”原稿”デリバリー:最初から最終原稿に近い形式でデリバリー(提供)する」です。ソフトウェア開発には、継続的デリバリーという概念があります。この概念を原稿執筆に当てはめてみました。

その心はアジャイルマニフェストにある「包括的なドキュメントよりも、動くソフトウェアを」の精神です。「動作するソフトウェア」とありますが、意図としては早期から最終状態に近い形式で提供した方が、よりリアルなユーザー体験を確認しやすいというものです。

今回はエンジニアHubに掲載される記事の執筆が対象なので、執筆早期からエンジニアHubのスタイル(HTML)で記事を確認できるようにしました。

継続的原稿デリバリーへの道

1. ローカルPC上で、原稿を確認できるように

まずは、手元で原稿を確認できるようにしていきます。執筆の流れを、下図に示します。

  1. markdown形式で原稿を執筆
  2. markdown文書から、目次 / 本文をそれぞれ抽出・生成して、HTML文書を組み立て
  3. HTML文書をブラウザ上で確認

執筆の流れ執筆の流れ

肝となるのは、2-1, 2-2の箇所です。markdown文書から、目次 / 本文に相当するHTML文書を生成しています。その他の箇所は固定だったので、エンジニアHubに掲載されている既存の記事をそのまま流用しました。

2-1. で目次を生成するスクリプトは、下記のように準備しています(見ての通り、sedを使って力技で組み立てています 😅)

# 目次
echo '<ul class="table-of-contents">' >> $OUTPUT

for file in docs/ch*.md; do
    echo '<li>' >> $OUTPUT
    # + md から見出しだけを抜き出して
    # + 第1レベル・第2レベルそれぞれに html タグを埋めつつ
    # + 最初の第2レベルに <ul>, 最後の第2レベルに </ul> を追加
    grep -h '^#' $file | \
        sed -e 's|^# \(.*\)|<a href="#\1">\1</a>|' \
            -e 's|^## \(.*\)|<li><a href="#\1">\1</a></li>|' \
            -e '1,/li/ s|^<li>|<ul><li>|' \
            -e '$ s|</li>$|</li></ul>|' >> $OUTPUT
    echo '</li>' >> $OUTPUT
done

echo '</ul>' >> $OUTPUT

下記のように記載されたmarkdown文書に対して、

$ cat ch1.md
# Backlogの基本的な機能と開発の流れ
~~~~~


$ cat ch2.md
# 開発チーム内での活用

## Project型業務
~~~~~

## Operation型業務
~~~~~

上述したスクリプトを実行すると、下記のようなHTMLが出力されます(見やすいように、少し整形しています)

<ul class="table-of-contents">
<li>
  <a href="#Backlogの基本">Backlogの基本</a>
  <ul>
    <li><a href="#基本的な機能と開発の流れ">基本的な機能と開発の流れ</a></li>
  </ul>
</li>
<li>
  <a href="#開発チーム内での活用">開発チーム内での活用</a>
  <ul>
    <li><a href="#Project型業務">Project型業務</a></li>
    <li><a href="#Operation型業務">Operation型業務</a></li>
  </ul>
</li>
</ul>

2-2. の本文生成スクリプトは、そう難しくありません。Pandocという汎用的なドキュメント変換ツールがあるので、そちらを利用しています。合わせて、sedを使って見出しのレベルを微調整しています。

# 本文
for file in docs/ch*.md; do
    # エンジニアHubのスタイルに合わせて、h1/h2 を h3/h4 に変換しつつ html 化
    sed 's/^#/###/' $file | pandoc -f markdown -t html >> $OUTPUT
done

markdownからHTMLを生成するスクリプトの全ソースは、こちらに置いていますので、興味がある方は参照ください。

2. Web上で原稿を確認できるように

1. の状態で、実現したかった「最終原稿に近い形式で確認できるようにする」ことは実現できました。ただ、これだと手元でHTMLファイルを生成する必要があり、まだちょっと手間がかかっています。

というわけで、次はこのHTML原稿をGitHub Pagesに公開して、GitHub Pagesにブラウザからアクセスするだけで確認できるようにしてみました。公開する処理は、GitHub Actionsを使って自動化しています。

GitHub Actionsのワークフローは、以下の2つのジョブに分けています。

  1. buildジョブ:上述したスクリプト(make.sh)を実行して、HTMLを生成
  2. deployジョブ:生成されたHTMLファイルを、GitHub Pagesにデプロイ

buildジョブは、下記のように定義しています。Pandoc公式からDockerイメージが提供されているので、このイメージを利用しています。

jobs:
  build:

    runs-on: ubuntu-latest

    container: pandoc/core

    steps:

    - uses: actions/checkout@v2

    - name: Run shell script for making html
      run: ./make.sh

    - name: Upload html
      uses: actions/upload-artifact@v1
      with:
        name: docs
        path: docs

deployジョブでは、buildジョブで生成されたHTMLをdeployジョブで使えるようにダウンロードし、GitHub Pages Actionを利用してデプロイしています。GitHub Pagesもまともに使うのは初めてだったのですが、さくっと実現できました。

deploy:

    needs: build

    runs-on: ubuntu-latest

    steps:
    - name: Download html
      uses: actions/download-artifact@v1
      with:
        name: docs

    - name: Deploy html
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./docs
        commit_message: ${{ github.event.head_commit.message }}
        keep_files: true

この段階では、GitHub Pages上で下記のように確認できていました。URLの”https://<organization>.github.io/<repository>”の箇所をご覧いただければ、これはGitHub Pages上の原稿だというのが確認できるかと思います。

2. Web上で原稿を確認2. Web上で原稿を確認

3. プルリクエストごとに、原稿を確認できるように

ここまでの設定で、masterブランチ上の原稿を確認できるようになっていました。最後は、プルリクエストのブランチごとに異なる原稿を表示できるようにしてみます。こうすることによって、プルリクエスト上での修正も、masterブランチに反映する前に確認することができるようになります。

ここで、GitHub Pages上のURLを下記のように設計しました。”pull request number”で1階層ディレクトリを作っています。

  • masterブランチ:https://<organization>.github.io/<repository>/output.html
  • プルリクエスト:https://<organization>.github.io/<repository>/<pull request number>/output.html

このURLになるように、GitHub Actionsのdeployジョブに、プルリクエスト時だけ実行される処理を追加しています。

    # e.g. https://<organization>.github.io/<repository>/<#PR num>/output.html
    - name: Make sub dir for pull request
      run: |
        mkdir -p ${{ github.event.number }}
        mv docs/* ${{ github.event.number }}
        mv ${{ github.event.number }} docs
      if: github.event_name == 'pull_request'

GitHub Actionsのワークフローのソースは、最終的にこのようになりました。

感想

やる前:効果のほどは半信半疑で、それでも色々試してみたかった

やる前は、正直どこまで効果的なんだろうというのは思っていました。

ただ、JenkinsやCircleCIなどの自動化が好きだし、開発プロセスの改善 + 自動化を自分の武器としていきたいという思いから、せっかくなのでGitHub Actionsなどを試してみようというのが、半分の動機でした。

やった後:思ったよりもすごくよかった!

やってみたところ、かなり効果があったなと思っています。

  • 書いてる途中も、最終形に当てはめながら執筆できたので、すごくイメージしやすかった(例えば段落の分量だったり、画像やスライドの配置だったり)
  • プルリクエストごとに確認する環境ができたので、編集者との修正内容がどう反映されるかもすぐ分かった
  • 最終稿への反映後も、ほとんど体裁が変わってないので、ほぼノーチェックに近いレベルで確認が済んで楽だった
  • なにより、早い段階から最終稿に近い形式で見ることができると、テンションがあがりやすかった!

この仕組については、編集者の方からもお褒めの言葉を頂いております 😄

編集者からのお褒めの言葉編集者からのお褒めの言葉


継続的デリバリーを原稿執筆に当てはめた「継続的原稿デリバリー」について、その実践方法とやってみた感想を紹介しました。

ソフトウェア開発でのプラクティスは、他の業務においても十分に有効なものがあるかと思います。色々と試しながら、取り入れていきたいですね。

タスク管理、ファイル共有もできるプロジェクト管理ツールBacklog

チームではたらく、すべての人のプロジェクト管理ツール

Backlog Logo