AsciidocをGithub actionsを用いてGithub pagesにdeployする

Github actionsを用いてasciidocをGithub pagesにdeployします

yunJuly 12, 2024

準備物

今回は Spring REST Docs、Asciidoc、Github actions と Github Pages を使用します。

  1. Java 21
  2. Gradle
  3. Spring Boot 3.3.2
  4. Asciidoc
  5. Github のアカウント
  6. 飲み物 🍺

何故Gradle?

今回 gradle を使う理由としてはビルドの速さです。最低10倍から最高100倍まで早いとの記事もあります。 Spring チームが Maven から Gradle に変更した理由でもあります。

Github Pages を設定する

まず Github Pages の設定を変更してください。

Github Pages の Build と Deploy を Github Actions でやるための設定になります。

  • Repository > Settings > Pages > Build and deployment > SourceGithub Actions を選択

Gradle に asciidoc の設定を入れます

この設定は Spring をビルドする時に asciidoc を生成して結果物の index.html/static/docs にコピーする設定になります。

今回は groovy ではなく kotlin を使います。 理由としてはどんどん Kotlin + Spring が増えつつあり kotlin での書き方の勉強のため使いました。

build.gradle.kt

plugins {
    java
    id("org.springframework.boot") version "3.3.0"
    id("io.spring.dependency-management") version "1.1.5"
    id("org.asciidoctor.jvm.convert") version "3.3.2" // 追加
 
}
 
group = "jp.falsystack"
version = "0.0.1-SNAPSHOT"
 
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}
 
configurations {
    compileOnly {
        extendsFrom(configurations.annotationProcessor.get())
    }
}
 
repositories {
    mavenCentral()
}
 
val asciidoctorExt: Configuration by configurations.creating // configuration 追加
 
dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-validation")
 
    // rest docs
    testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
    asciidoctorExt("org.springframework.restdocs:spring-restdocs-asciidoctor")
 
    compileOnly("org.projectlombok:lombok")
    runtimeOnly("com.h2database:h2")
    annotationProcessor("org.projectlombok:lombok")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
 
tasks.withType<Test> {
    useJUnitPlatform()
}
 
// sinppetsDir 追加
val snippetsDir by extra {
    file("build/generated-snippets")
}
 
tasks {
 
    // test Task snippetsDir 追加
    test {
        outputs.dir(snippetsDir)
        useJUnitPlatform()
    }
 
    // asciidoctor Task 追加
    asciidoctor {
        inputs.dir(snippetsDir)
        configurations("asciidoctorExt")
        dependsOn(test)
    }
 
    // bootJar Settings
    bootJar {
        dependsOn(asciidoctor)
        from("build/docs/asciidoc") {
            into("static/docs")
        }
    }
 
    // 生成された asciidoc index.html を src/man/resources/static/docs にコピー
    register<Copy>("copyAsciidoctor") {
        dependsOn(asciidoctor)
        from(file("$layout.buildDirectory/docs/asciidoc"))
        into(file("src/main/resources/static/docs"))
    }
 
    // ビルドを実行する時 copyAsciidoctor が動いてからビルドするように設定
    build {
        dependsOn("copyAsciidoctor")
    }
}

index.adoc を作っておく

index.html を生成するための adoc を用意します。

  • index.adoc
= TOPU Service
:toc: left
 
== Recruitments
 
// Create Recruitments
=== Create Recruitments
 
==== HTTP Request
 
include::{snippets}/post-recruitments/http-request.adoc[]
 
...省略

基本的に Spring REST Docs を用いてテストを書いてビルドすると build/generated-snippets の中に snippet が生成されます。

これらを src/docs/asciidoc/ の中に index.adoc ファイルを作って snippetsindex.adoc の中に入れ込むと asciidoctor がビルドする時に index.html を生成してくれます。

Github の workflows を書きます

最終段階です。Github actions を用いてプロジェクトをビルドして、生成された API 明細(asciidoc)を Github pages に Deploy します。

0. Trigger

紹介するための workflow なので push する時に actions が動くようにします。

on:
  push:
  workflow_dispatch:

1.ビルドする

プロジェクトをビルドしてビルドする時生成された asciidoc(index.html) を次の job で使うために upload します

build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'corretto'
 
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
 
      - name: Build with Gradle
        run: ./gradlew build
 
      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: Package
          path: build/docs/asciidoc

2.Github Pages に Deploy します

Upload した index.html を Download します。 Download した index.html をそのまま Github Pages に Deploy します。

何故 index.html ?

Github Pagesはエントリーポイントとしてindex.htmlを探します。

  deploy-docs:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: Package
 
      - name: List files in build/libs (for Debugging)
        run: ls -la .
 
      - name: Configure Pages
        uses: actions/configure-pages@v5
 
      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: .
 
      - name: Deploy to Pages
        uses: actions/deploy-pages@v4
        id: deployment
workflows全文確認
name: topu
 
on:
  push:
  workflow_dispatch:
 
permissions:
  id-token: write
  contents: read
  pages: write
 
concurrency:
  group: "pages"
  cancel-in-progress: false
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'corretto'
 
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
 
      - name: Build with Gradle
        run: ./gradlew build
 
      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: Package
          path: build/docs/asciidoc
 
  deploy-docs:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: Package
 
      - name: List files in build/libs (debugging)
        run: ls -la .
 
      - name: Configure Pages
        uses: actions/configure-pages@v5
 
      - name: Upload Pages artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: .
 
      - name: Deploy to Pages
        uses: actions/deploy-pages@v4
        id: deployment

確認する

Githubに入り Code > Deployments でご確認できます。

画像を見せることが今はできないので後ほど修正しておきます。

結果

  • 自動化されたAPI文書の生成ができるようになりました
  • 文書が実際のテストコードから(テストがPASSされたことが前提)生成されるため、文書とコードとの相違が発生する可能性が低くなります
  • 必要であればasciidocではなくopenapiにもできます
  • ci/cdパイプラインを用いて文書を生成して配布しているため、文書の最新化を測れるし文書化の負荷が減ります

以上です。