asciidocをgithub actionsを用いてgithub pagesにdeployする
Spring REST Docsを用いて作成されたasciidocをGithub actionsを使いGithub pagesにdeployしたいと思います。
準備物
今回はSpring REST Docs、Asciidoc、Github actionsとGithub Pagesを使用します。
- Java 21
- Gradle
- Spring Boot 3.3.2
- Asciidoc
- Githubのアカウント
- 飲み物 🍺
何故Gradle?
今回 gradle を使う理由としてはビルドの速さです。最低10倍から最高100倍まで早いとの記事もあります。
SpringチームがMavenからGradleに変更した理由でもあります。
Github Pages を設定する
Repository > Settings > Pages > Build and deployment > Source で Github Actions
を選択してください。
Gradle に asciidoc の設定を入れます
今回は 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.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
ファイルを作って snippets
を index.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パイプラインを用いて文書を生成して配布しているため、文書の最新化を測れるし文書化の負荷が減ります
以上です。
Discussion