self_update 1.2.0

Self updates for standalone executables
Documentation
name: Publish to crates.io
on:
  push:
    branches:
      - master
      - main
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
      with:
        components: rustfmt, clippy
    - run: cargo install cargo-readme
    # Gate the publish on the full CI pipeline so a broken commit is never released.
    - run: make ci

  publish:
    needs: check
    runs-on: ubuntu-latest
    environment: release  # Optional: for enhanced security
    permissions:
      id-token: write     # Required for OIDC token exchange
      contents: write     # Required to push the release tag
    steps:
    - uses: actions/checkout@v6
    - uses: rust-lang/crates-io-auth-action@v1
      id: auth
    - name: Publish
      id: publish
      run: cargo publish
      env:
        CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
    - name: Tag the released version
      # Only tag when the publish above actually succeeded, so a failed publish never creates a
      # tag for a version that did not reach crates.io. (A no-op push of an already-published
      # version fails the publish step and skips this; the tag from the original publish remains.)
      if: steps.publish.outcome == 'success'
      run: |
        version="$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[0].version')"
        tag="v${version}"
        git fetch --tags --force --quiet
        if git rev-parse -q --verify "refs/tags/${tag}" >/dev/null; then
          echo "Tag ${tag} already exists; nothing to do."
        else
          git tag "${tag}"
          git push origin "${tag}"
          echo "Created and pushed ${tag}."
        fi