caesar_cipher_enc_dec 1.0.10

can easily use caesar cipher
Documentation
name: Release

# Releasesへのファイル追加のために書き込み権限が必要
permissions:
  contents: write

on:
  push:
    tags:
    - v*

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Run tests
        run: cargo test --verbose

  build:
    needs: [test]
    runs-on: ${{ matrix.job.os }}
    strategy:
      fail-fast: false
      matrix:
        job:
          - { os: ubuntu-latest  , target: x86_64-unknown-linux-gnu       , use-cross: false , extension: ""   }
          - { os: ubuntu-latest  , target: x86_64-unknown-linux-musl      , use-cross: true  , extension: ""   }
          - { os: ubuntu-latest  , target: armv7-unknown-linux-gnueabihf  , use-cross: true  , extension: ""   }
          - { os: ubuntu-latest  , target: armv7-unknown-linux-musleabihf , use-cross: true  , extension: ""   }
          - { os: ubuntu-latest  , target: aarch64-unknown-linux-gnu      , use-cross: true  , extension: ""   }
          - { os: ubuntu-latest  , target: aarch64-unknown-linux-musl     , use-cross: true  , extension: ""   }
          - { os: macos-latest   , target: x86_64-apple-darwin            , use-cross: false , extension: ""   }
          - { os: macos-latest   , target: aarch64-apple-darwin           , use-cross: false , extension: ""   }
          - { os: windows-latest , target: x86_64-pc-windows-msvc         , use-cross: false , extension: .exe }
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      # Rustのpackage名を取得して環境変数に入れておく。(後のステップで使用)
      - name: Extract crate information
        shell: bash
        run: |
          echo "PROJECT_NAME=$(sed -n 's/^name = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV

      # rustcやcargoをインストール
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.job.target }}

      # crossが必要な場合はインストール
      - name: Install cross
        if: matrix.job.use-cross
        run: cargo install cross --locked

      # targetに応じてcargoもしくはcrossを使用してビルド
      - name: Build
        shell: bash
        run: |
          if [ "${{ matrix.job.use-cross }}" = "true" ]; then
            cross build --release --target ${{ matrix.job.target }}
          else
            cargo build --release --target ${{ matrix.job.target }}
          fi

      # ビルド済みバイナリをリネーム
      - name: Rename artifacts
        shell: bash
        run: |
          mv target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ matrix.job.extension }} target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}-${{ github.ref_name }}-${{ matrix.job.target }}${{ matrix.job.extension }}

      # ビルド済みバイナリをアーティファクトとしてアップロード
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.job.target }}
          path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}-${{ github.ref_name }}-${{ matrix.job.target }}${{ matrix.job.extension }}

  # 全ビルドジョブのアーティファクトを集めてReleasesに一括配置
  release:
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Release
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          files: artifacts/*

  # crates.ioへの自動公開
  publish:
    needs: [test]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Extract crate metadata
        id: crate_metadata
        shell: bash
        run: |
          CRATE_NAME=$(cargo metadata --no-deps --format-version 1 | python3 -c "import json, sys; print(json.load(sys.stdin)['packages'][0]['name'])")
          CRATE_VERSION=$(cargo metadata --no-deps --format-version 1 | python3 -c "import json, sys; print(json.load(sys.stdin)['packages'][0]['version'])")
          echo "crate_name=${CRATE_NAME}" >> "${GITHUB_OUTPUT}"
          echo "crate_version=${CRATE_VERSION}" >> "${GITHUB_OUTPUT}"

      - name: Check if version is already published
        id: publish_guard
        shell: bash
        run: |
          set -euo pipefail
          PUBLISH_STATUS=$(curl --silent --output /dev/null --write-out "%{http_code}" \
            -H "User-Agent: caesar_cipher_enc_dec-release (github-actions)" \
            "https://crates.io/api/v1/crates/${{ steps.crate_metadata.outputs.crate_name }}/${{ steps.crate_metadata.outputs.crate_version }}")
          if [ "${PUBLISH_STATUS}" = "200" ]; then
            echo "should_publish=false" >> "${GITHUB_OUTPUT}"
            echo "Version ${{ steps.crate_metadata.outputs.crate_version }} is already published for ${{ steps.crate_metadata.outputs.crate_name }}. Skipping publish."
          elif [ "${PUBLISH_STATUS}" = "404" ]; then
            echo "should_publish=true" >> "${GITHUB_OUTPUT}"
          else
            echo "Unexpected status from crates.io API: ${PUBLISH_STATUS}"
            exit 1
          fi

      - name: Publish to crates.io
        if: ${{ steps.publish_guard.outputs.should_publish == 'true' }}
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}