Merge pull request #332 from ma10/debug-release-wf-20250603_4 #267
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release and Deploy Documentation | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| tags: | |
| - '[0-9][0-9][0-9][0-9][0-9][0-9].[0-9]*' | |
| workflow_dispatch: | |
| inputs: | |
| force_rebuild: | |
| description: 'Force rebuild all artifacts (ignore cache)' | |
| required: false | |
| default: false | |
| type: boolean | |
| target_ref: | |
| description: 'Target branch or tag to build (leave empty for current branch)' | |
| required: false | |
| default: '' | |
| type: string | |
| permissions: | |
| contents: write | |
| pages: write | |
| id-token: write | |
| concurrency: | |
| group: "pages" | |
| cancel-in-progress: true | |
| jobs: | |
| get-custom-domain: | |
| uses: ./.github/workflows/reusable-custom-domain.yml | |
| get_build_targets: | |
| needs: get-custom-domain | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.generate_matrix.outputs.matrix }} | |
| env: | |
| CUSTOM_DOMAIN: ${{ needs.get-custom-domain.outputs.custom_domain }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ inputs.target_ref || github.ref }} | |
| fetch-depth: 0 | |
| - name: Generate build matrix | |
| id: generate_matrix | |
| env: | |
| IS_TAG_PUSH: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} | |
| GITHUB_REFNAME: ${{ github.ref_name }} | |
| FORCE_REBUILD: ${{ inputs.force_rebuild || 'false' }} | |
| TARGET_REF: ${{ inputs.target_ref || '' }} | |
| run: | | |
| ALL_TAGS_SORTED=$(git tag -l '[0-9][0-9][0-9][0-9][0-9][0-9].[0-9]*' | sort -rV) | |
| MATRIX_ITEMS="[]" | |
| CURRENT_PUSHED_TAG="" | |
| if [[ "${IS_TAG_PUSH}" == "true" ]]; then | |
| CURRENT_PUSHED_TAG="$(echo ${GITHUB_REFNAME} | sed s/refs\/tags\///)" | |
| fi | |
| # Handle manual workflow dispatch with target_ref | |
| if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ -n "$TARGET_REF" ]; then | |
| echo "Manual dispatch with target ref: $TARGET_REF" | |
| if git tag -l | grep -q "^${TARGET_REF}$"; then | |
| echo "Target ref is a tag: $TARGET_REF" | |
| CURRENT_PUSHED_TAG="$TARGET_REF" | |
| elif [ "$TARGET_REF" == "develop" ]; then | |
| echo "Target ref is develop branch" | |
| else | |
| echo "Warning: Target ref '$TARGET_REF' is not a recognized tag or develop branch" | |
| fi | |
| fi | |
| LATEST_RELEASE_TAG=$(echo "$ALL_TAGS_SORTED" | head -n1) | |
| get_versions() { | |
| local VNUM=$1 | |
| local PY_VER="" | |
| local SPHINX_VER="" | |
| local THEME_VER="" | |
| if (( VNUM <= 20230300 )); then | |
| PY_VER="3.12"; SPHINX_VER="~=5.0"; THEME_VER="~=2.0" | |
| elif (( VNUM <= 20250400 )); then | |
| PY_VER="3.13"; SPHINX_VER="~=7.0"; THEME_VER="~=3.0" | |
| else | |
| PY_VER="3.13"; SPHINX_VER="requirements.txt"; THEME_VER="requirements.txt" | |
| fi | |
| echo "$PY_VER,$SPHINX_VER,$THEME_VER" | |
| } | |
| # Generate safe artifact names by replacing problematic characters | |
| generate_artifact_name() { | |
| local tag=$1 | |
| local deploy_path=$2 | |
| if [ "$tag" == "develop" ]; then | |
| echo "build-current" | |
| elif [ -z "$deploy_path" ]; then | |
| echo "build-root" | |
| else | |
| # Replace / with - for artifact names | |
| echo "build-$(echo "$deploy_path" | sed 's/\//-/g')" | |
| fi | |
| } | |
| get_base_url() { | |
| local deploy_path=$1 | |
| if [ -n "$CUSTOM_DOMAIN" ]; then | |
| base_url_prefix="https://${CUSTOM_DOMAIN}/" | |
| else | |
| base_url_prefix="https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/" | |
| fi | |
| echo "${base_url_prefix}${deploy_path}/" | |
| } | |
| # Add develop build | |
| DEVELOP_ARTIFACT_NAME=$(generate_artifact_name "develop" "current") | |
| DEVELOP_BASE_URL=$(get_base_url "current") | |
| MATRIX_ITEMS=$(echo "$MATRIX_ITEMS" | jq -c --arg tag "develop" \ | |
| --arg python "3.13" \ | |
| --arg sphinx "~=7.0" \ | |
| --arg theme "~=3.0" \ | |
| --arg vnum "99999999" \ | |
| --arg deploy_path "current" \ | |
| --arg base_url "$DEVELOP_BASE_URL" \ | |
| --arg artifact_name "$DEVELOP_ARTIFACT_NAME" \ | |
| '. + [{tag: $tag, python: $python, sphinx: $sphinx, theme: $theme, deploy_path: $deploy_path, base_url: $base_url, artifact_name: $artifact_name, is_latest_develop: true, vnum: ($vnum | tonumber)}]') | |
| # Add latest release build | |
| if [ -n "$LATEST_RELEASE_TAG" ]; then | |
| LATEST_VNUM=$(echo "$LATEST_RELEASE_TAG" | awk -F'.' '{printf "%s%02d", $1, $2}') | |
| IFS=',' read -r LATEST_PY LATEST_SPHINX LATEST_THEME <<< $(get_versions "$LATEST_VNUM") | |
| LATEST_ARTIFACT_NAME=$(generate_artifact_name "$LATEST_RELEASE_TAG" "") | |
| LATEST_BASE_URL=$(get_base_url "") | |
| MATRIX_ITEMS=$(echo "$MATRIX_ITEMS" | jq -c --arg tag "$LATEST_RELEASE_TAG" \ | |
| --arg python "$LATEST_PY" \ | |
| --arg sphinx "$LATEST_SPHINX" \ | |
| --arg theme "$LATEST_THEME" \ | |
| --arg vnum "$LATEST_VNUM" \ | |
| --arg deploy_path "" \ | |
| --arg base_url "$LATEST_BASE_URL" \ | |
| --arg artifact_name "$LATEST_ARTIFACT_NAME" \ | |
| '. + [{tag: $tag, python: $python, sphinx: $sphinx, theme: $theme, deploy_path: $deploy_path, base_url: $base_url, artifact_name: $artifact_name, is_latest_release: true, vnum: ($vnum | tonumber)}]') | |
| fi | |
| # Add archive builds | |
| for ARCHIVE_TAG in ${ALL_TAGS_SORTED}; do | |
| if [[ "$ARCHIVE_TAG" != "$LATEST_RELEASE_TAG" ]]; then | |
| ARCHIVE_VNUM=$(echo "$ARCHIVE_TAG" | awk -F'.' '{printf "%s%02d", $1, $2}') | |
| IFS=',' read -r ARCHIVE_PY ARCHIVE_SPHINX ARCHIVE_THEME <<< $(get_versions "$ARCHIVE_VNUM") | |
| ARCHIVE_DEPLOY_PATH="archive/${ARCHIVE_TAG}" | |
| ARCHIVE_BASE_URL=$(get_base_url "$ARCHIVE_DEPLOY_PATH") | |
| ARCHIVE_ARTIFACT_NAME=$(generate_artifact_name "$ARCHIVE_TAG" "$ARCHIVE_DEPLOY_PATH") | |
| MATRIX_ITEMS=$(echo "$MATRIX_ITEMS" | jq -c --arg tag "$ARCHIVE_TAG" \ | |
| --arg python "$ARCHIVE_PY" \ | |
| --arg sphinx "$ARCHIVE_SPHINX" \ | |
| --arg theme "$ARCHIVE_THEME" \ | |
| --arg vnum "$ARCHIVE_VNUM" \ | |
| --arg deploy_path "$ARCHIVE_DEPLOY_PATH" \ | |
| --arg base_url "$ARCHIVE_BASE_URL" \ | |
| --arg artifact_name "$ARCHIVE_ARTIFACT_NAME" \ | |
| '. + [{tag: $tag, python: $python, sphinx: $sphinx, theme: $theme, deploy_path: $deploy_path, base_url: $base_url, artifact_name: $artifact_name, vnum: ($vnum | tonumber)}]') | |
| fi | |
| done | |
| echo "matrix=$MATRIX_ITEMS" >> "$GITHUB_OUTPUT" | |
| echo "Generated matrix with $(echo "$MATRIX_ITEMS" | jq length) items" | |
| echo "Force rebuild: $FORCE_REBUILD" | |
| check_existing_artifacts: | |
| runs-on: ubuntu-latest | |
| needs: get_build_targets | |
| outputs: | |
| reusable_artifacts: ${{ steps.check_artifacts.outputs.reusable_artifacts }} | |
| steps: | |
| - name: Check for existing artifacts | |
| id: check_artifacts | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| MATRIX: ${{ needs.get_build_targets.outputs.matrix }} | |
| FORCE_REBUILD: ${{ inputs.force_rebuild || 'false' }} | |
| run: | | |
| echo "Checking for reusable artifacts..." | |
| echo "Force rebuild mode: $FORCE_REBUILD" | |
| REUSABLE_ARTIFACTS="[]" | |
| # 強制再ビルドが指定されている場合は、アーティファクト検索をスキップ | |
| if [ "$FORCE_REBUILD" == "true" ]; then | |
| echo "Force rebuild enabled - skipping artifact search" | |
| else | |
| echo "Normal mode - searching for reusable artifacts" | |
| # 最新の成功したワークフロー実行を取得 | |
| RECENT_RUNS=$(gh run list \ | |
| --repo ${{ github.repository }} \ | |
| --workflow release.yml \ | |
| --status success \ | |
| --limit 5 \ | |
| --json databaseId,headSha,createdAt) | |
| # 各ビルドターゲットについて、既存のアーティファクトをチェック | |
| echo "$MATRIX" | jq -c '.[]' | while read -r target; do | |
| TAG=$(echo "$target" | jq -r '.tag') | |
| ARTIFACT_NAME=$(echo "$target" | jq -r '.artifact_name') | |
| # タグ(develop以外)の場合、過去のアーティファクトを探す | |
| if [ "$TAG" != "develop" ]; then | |
| echo "Checking for existing artifact: $ARTIFACT_NAME for tag: $TAG" | |
| # 過去5回の実行からアーティファクトを検索 | |
| echo "$RECENT_RUNS" | jq -c '.[]' | while read -r run; do | |
| RUN_ID=$(echo "$run" | jq -r '.databaseId') | |
| # アーティファクトの存在をチェック | |
| if gh run view $RUN_ID --json artifacts --jq ".artifacts[] | select(.name == \"$ARTIFACT_NAME\") | .name" | grep -q "$ARTIFACT_NAME"; then | |
| echo "Found reusable artifact: $ARTIFACT_NAME in run: $RUN_ID" | |
| # 再利用可能なアーティファクトリストに追加 | |
| REUSABLE_ARTIFACTS=$(echo "$REUSABLE_ARTIFACTS" | jq -c --arg name "$ARTIFACT_NAME" --arg runId "$RUN_ID" '. + [{name: $name, runId: $runId}]') | |
| break | |
| fi | |
| done | |
| fi | |
| done | |
| fi | |
| echo "reusable_artifacts=$REUSABLE_ARTIFACTS" >> $GITHUB_OUTPUT | |
| echo "Found $(echo "$REUSABLE_ARTIFACTS" | jq length) reusable artifacts" | |
| build_docs: | |
| needs: [get_build_targets, check_existing_artifacts] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| build_target: ${{ fromJson(needs.get_build_targets.outputs.matrix) }} | |
| uses: ./.github/workflows/reusable-build-doc.yml | |
| with: | |
| tag: ${{ matrix.build_target.tag }} | |
| python: ${{ matrix.build_target.python }} | |
| sphinx: ${{ matrix.build_target.sphinx }} | |
| theme: ${{ matrix.build_target.theme }} | |
| deploy_path: ${{ matrix.build_target.deploy_path }} | |
| base_url: ${{ matrix.build_target.base_url }} | |
| artifact_name: ${{ matrix.build_target.artifact_name }} | |
| is_latest_release: ${{ matrix.build_target.is_latest_release || false }} | |
| is_latest_develop: ${{ matrix.build_target.is_latest_develop || false }} | |
| vnum: ${{ matrix.build_target.vnum }} | |
| force_rebuild: ${{ inputs.force_rebuild || false }} | |
| reusable_artifacts: ${{ needs.check_existing_artifacts.outputs.reusable_artifacts }} | |
| deploy_pages: | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| runs-on: ubuntu-latest | |
| needs: [build_docs, get_build_targets] | |
| steps: | |
| - name: Setup Pages | |
| uses: actions/configure-pages@v4 | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: ${{ github.workspace }}/artifacts | |
| - name: Prepare final deployment directory | |
| env: | |
| GITHUB_WORKSPACE: ${{ github.workspace }} | |
| run: | | |
| mkdir -p "${GITHUB_WORKSPACE}/_site" | |
| echo "Processing artifacts..." | |
| for artifact_dir in "${GITHUB_WORKSPACE}"/artifacts/*; do | |
| if [ -d "$artifact_dir" ]; then | |
| artifact_name=$(basename "$artifact_dir") | |
| echo "Processing artifact: $artifact_name" | |
| # Read deploy path from metadata | |
| if [ -f "${artifact_dir}/.deploy_path" ]; then | |
| deploy_path=$(cat "${artifact_dir}/.deploy_path") | |
| echo "Deploy path: $deploy_path" | |
| if [ -z "$deploy_path" ]; then | |
| # Root deployment | |
| echo "Deploying to root" | |
| cp -r "${artifact_dir}"/* "${GITHUB_WORKSPACE}/_site/" | |
| else | |
| # Subdirectory deployment | |
| echo "Deploying to subdirectory: $deploy_path" | |
| mkdir -p "${GITHUB_WORKSPACE}/_site/${deploy_path}" | |
| cp -r "${artifact_dir}"/* "${GITHUB_WORKSPACE}/_site/${deploy_path}/" | |
| fi | |
| # Remove metadata files from final deployment | |
| rm -f "${GITHUB_WORKSPACE}/_site/${deploy_path}/.deploy_path" 2>/dev/null || true | |
| rm -f "${GITHUB_WORKSPACE}/_site/${deploy_path}/.build_custom_domain" 2>/dev/null || true | |
| rm -f "${GITHUB_WORKSPACE}/_site/.deploy_path" 2>/dev/null || true | |
| rm -f "${GITHUB_WORKSPACE}/_site/.build_custom_domain" 2>/dev/null || true | |
| else | |
| echo "Warning: No .deploy_path found for $artifact_name" | |
| fi | |
| fi | |
| done | |
| - name: Upload Pages artifact | |
| uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: ${{ github.workspace }}/_site | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 | |
| create_release: | |
| runs-on: ubuntu-latest | |
| needs: get_build_targets | |
| if: | | |
| startsWith(github.ref, 'refs/tags/') && | |
| needs.get_build_targets.outputs.matrix | |
| steps: | |
| - name: Extract Tag Name | |
| run: | | |
| echo "TAG=${{ github.ref_name }}" >> $GITHUB_ENV | |
| - name: Checkout repository for release build | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.ref }} | |
| fetch-depth: 0 | |
| submodules: true | |
| - name: Clean working directory for release build | |
| run: | | |
| git clean -dfx | |
| echo "Cleaned working directory for release build" | |
| - name: Set up Python (for release build) | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.13' | |
| - name: Install Python dependencies for release build | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt --upgrade | |
| - name: Prepare HTML archive for release | |
| env: | |
| TZ: Asia/Tokyo | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| if [ ! -f ./build.mk ]; then | |
| BUILD_PROCEDURE=0 | |
| else | |
| BUILD_PROCEDURE=$(make build-procedure-version) | |
| fi | |
| if [ "${BUILD_PROCEDURE}" -eq 0 ]; then | |
| make sphinx_options="-D html_baseurl=/ " html | |
| mkdir -p freee-a11y-guidelines-${TAG} | |
| cp -r ./build/html/* freee-a11y-guidelines-${TAG}/ | |
| if [ -d ./data/json/schemas ]; then | |
| cp -r ./data/json/schemas freee-a11y-guidelines-${TAG}/ | |
| fi | |
| elif [ "${BUILD_PROCEDURE}" -eq 1 ]; then | |
| make BASE_URL=/ sphinx_options="" clean html | |
| mkdir -p freee-a11y-guidelines-${TAG}/en | |
| cp -r ./ja/build/html/* freee-a11y-guidelines-${TAG}/ | |
| if [ -d ./en/build/html ]; then | |
| cp -r ./en/build/html/* freee-a11y-guidelines-${TAG}/en | |
| fi | |
| if [ -d ./data/json/schemas ]; then | |
| cp -r ./data/json/schemas freee-a11y-guidelines-${TAG}/ | |
| fi | |
| else | |
| echo "Unknown build procedure version: ${BUILD_PROCEDURE}" | |
| exit 1 | |
| fi | |
| zip -r freee-a11y-guidelines-${TAG}-html.zip ./freee-a11y-guidelines-${TAG} | |
| - name: Create GitHub Release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| RELEASE_NOTES_FILE="./ja/source/intro/ChangeLog/${TAG:0:4}/${TAG}.rst" | |
| if [ -f "$RELEASE_NOTES_FILE" ]; then | |
| gh release create ${TAG} \ | |
| --title "Ver. ${TAG}" \ | |
| --notes-file "$RELEASE_NOTES_FILE" \ | |
| --draft | |
| else | |
| gh release create ${TAG} \ | |
| --title "Ver. ${TAG}" \ | |
| --notes "Release version ${TAG}" \ | |
| --draft | |
| fi | |
| gh release upload ${TAG} freee-a11y-guidelines-${TAG}-html.zip |