diff --git a/.github/workflows/publish-on-semrel.yml b/.github/workflows/publish-on-semrel.yml index 8a5553f..85ad9f8 100644 --- a/.github/workflows/publish-on-semrel.yml +++ b/.github/workflows/publish-on-semrel.yml @@ -1,4 +1,5 @@ name: publish-on-semrel + on: workflow_run: workflows: ["semantic-release"] @@ -6,96 +7,70 @@ on: workflow_dispatch: inputs: tag: - description: "Tag a publicar (p.ej. v0.4.35). Vacío = último release" + description: "Tag a publicar (ej. v0.4.35)" required: false - default: "" -permissions: - contents: read - packages: write - id-token: write -concurrency: - group: publish-${{ github.event_name }}-${{ github.run_id }} - cancel-in-progress: false + type: string + jobs: publish: - if: ${{ github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success') }} + if: > + (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || + (github.event_name == 'workflow_dispatch') runs-on: ubuntu-latest - environment: pypi + permissions: + contents: read + packages: write + id-token: write steps: - - uses: actions/checkout@v4 + - name: Checkout (con tags) + uses: actions/checkout@v4 with: fetch-depth: 0 - # Obtener tag del último release - - uses: actions/github-script@v7 - id: latest - with: - script: | - const { data } = await github.repos.getLatestRelease({ owner: context.repo.owner, repo: context.repo.repo }); - core.setOutput('tag', data.tag_name); - - - name: Resolver TAG de publicación + - name: Resolver TAG id: tag shell: bash run: | - if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] && [[ -n "${{ github.event.inputs.tag }}" ]]; then + if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" && -n "${{ github.event.inputs.tag }}" ]]; then TAG="${{ github.event.inputs.tag }}" else - TAG="${{ steps.latest.outputs.tag }}" + git fetch --tags --force + TAG="$(git tag -l 'v*' --sort=-v:refname | head -n1)" fi - echo "TAG=$TAG" >> "$GITHUB_ENV" + echo "TAG=$TAG" | tee -a "$GITHUB_ENV" echo "tag=$TAG" >> "$GITHUB_OUTPUT" - echo "Publicando tag: $TAG" + echo "Publicando TAG=$TAG" - - name: Sincronizar version de pyproject.toml con TAG - shell: bash + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Build sdist & wheel run: | - python - <<'PY' - import os, re, pathlib - tag = os.environ["TAG"].lstrip('v') - p = pathlib.Path("pyproject.toml") - t = p.read_text() - t = re.sub(r'(?m)^(\s*version\s*=\s*")\d+\.\d+\.\d+(")', rf"\1{tag}\2", t) - p.write_text(t) - print("Set version ->", tag) - PY + python -m pip install -U pip build + python -m build - # Build & push GHCR - - name: Set IMAGE - run: echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV" + - name: Publish to PyPI (OIDC) + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + skip-existing: true - - uses: docker/setup-qemu-action@v3 - - uses: docker/setup-buildx-action@v3 - - uses: docker/login-action@v3 + - name: Login GHCR + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build & Push container - uses: docker/build-push-action@v6 + - name: Setup Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build & Push image + uses: docker/build-push-action@v5 with: context: . - file: ./Dockerfile - platforms: linux/amd64 push: true - provenance: false - tags: ${{ env.IMAGE }}:${{ steps.tag.outputs.tag }},${{ env.IMAGE }}:latest - - # Build & publish PyPI (OIDC) - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Build sdist/wheel - run: | - python -m pip install -U pip build - python -m build - - - name: Publish to PyPI (Trusted Publisher) - uses: pypa/gh-action-pypi-publish@release/v1 - with: - skip-existing: true - verbose: true - env: - PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring + tags: ghcr.io/${{ github.repository }}:${{ env.TAG }} + platforms: linux/amd64 diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 27c7c4a..d5ed8b2 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -1,40 +1,84 @@ name: publish-pypi -on: - release: - types: [published] - -permissions: - contents: read - id-token: write -env: - PIP_DISABLE_PIP_VERSION_CHECK: "1" +on: + workflow_run: + workflows: ["semantic-release"] + types: [completed] + workflow_dispatch: + inputs: + tag: + description: "Tag to publish (e.g. v0.4.35)" + required: false + type: string jobs: - pypi: - if: startsWith(github.event.release.tag_name, 'v') + publish: + if: > + (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || + (github.event_name == 'workflow_dispatch') runs-on: ubuntu-latest environment: pypi + permissions: + contents: read + packages: write + id-token: write steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - name: Checkout with tags + uses: actions/checkout@v4 with: - python-version: '3.x' - - run: python -m pip install -U pip build - - name: Sync version from tag into pyproject.toml - env: - TAG: ${{ github.event.release.tag_name }} + fetch-depth: 0 + + - name: Resolve TAG + id: tag + shell: bash run: | - VER="${TAG#v}" - export VER - python - <<'PY' -import os, re, pathlib -ver = os.environ["VER"] -p = pathlib.Path("pyproject.toml") -t = p.read_text(encoding="utf-8") -t = re.sub(r'(?m)^(\s*version\s*=\s*")\d+\.\d+\.\d+(")', rf'\1{ver}\2', t) -p.write_text(t, encoding="utf-8") -print("pyproject.toml version ->", ver) -PY - - run: python -m build - - uses: pypa/gh-action-pypi-publish@release/v1 + if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" && -n "${{ github.event.inputs.tag }}" ]]; then + TAG="${{ github.event.inputs.tag }}" + else + git fetch --tags --force + TAG="$(git tag -l 'v*' --sort=-v:refname | head -n1)" + fi + echo "TAG=$TAG" | tee -a "$GITHUB_ENV" + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Build sdist & wheel + run: | + python -m pip install -U pip build + python -m build + + - name: Publish to PyPI via OIDC + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + skip-existing: true + + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Buildx + uses: docker/setup-buildx-action@v3 + + - name: Compute lowercase image tag + id: img + shell: bash + run: | + OWNER_LC="${GITHUB_REPOSITORY_OWNER,,}" + REPO_LC="$(basename "$GITHUB_REPOSITORY" | tr '[:upper:]' '[:lower:]')" + echo "IMAGE_TAG=ghcr.io/${OWNER_LC}/${REPO_LC}:${TAG}" | tee -a "$GITHUB_ENV" + + - name: Build & Push image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ env.IMAGE_TAG }} + platforms: linux/amd64