From 36ff8ee4254edb28888bde920ac6028350a4131e Mon Sep 17 00:00:00 2001 From: Teingi Date: Tue, 11 Aug 2026 14:28:46 +0800 Subject: [PATCH] ci: update workflow triggers and release publishing --- .github/workflows/build-artifacts.yml | 8 +- .github/workflows/build-docker.yml | 106 +-------------------- .github/workflows/e2e-harness.yml | 2 +- .github/workflows/{main.yml => master.yml} | 2 +- .github/workflows/on-release-main.yml | 82 ---------------- .github/workflows/release.yml | 103 ++++++++++++++++++++ 6 files changed, 112 insertions(+), 191 deletions(-) rename .github/workflows/{main.yml => master.yml} (98%) delete mode 100644 .github/workflows/on-release-main.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build-artifacts.yml b/.github/workflows/build-artifacts.yml index 628738a6a..3a59971ee 100644 --- a/.github/workflows/build-artifacts.yml +++ b/.github/workflows/build-artifacts.yml @@ -1,8 +1,6 @@ name: Build customer artifact on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review] workflow_dispatch: inputs: ref: @@ -28,7 +26,7 @@ permissions: contents: read concurrency: - group: customer-artifact-${{ github.event.pull_request.number || inputs.ref || github.ref }} + group: customer-artifact-${{ inputs.ref || github.ref }} cancel-in-progress: true env: @@ -47,7 +45,7 @@ jobs: - name: Check out requested source uses: actions/checkout@v7 with: - ref: ${{ inputs.ref || github.event.pull_request.head.sha || github.sha }} + ref: ${{ inputs.ref || github.sha }} fetch-depth: 0 - name: Set up Python @@ -68,7 +66,7 @@ jobs: id: metadata env: ARTIFACT_LABEL: ${{ inputs.artifact_label }} - SOURCE_REF: ${{ inputs.ref || github.head_ref || github.ref_name }} + SOURCE_REF: ${{ inputs.ref || github.ref_name }} run: | python - <<'PY' import os diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index e63317893..27d4a0883 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -1,38 +1,14 @@ name: Build Docker image on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review] - paths: - - .github/workflows/build-docker.yml - - docker/** - - src/** - - .dockerignore - - LICENSE - - README.md - - pyproject.toml - - uv.lock - push: - branches: [main] - paths: - - .github/workflows/build-docker.yml - - docker/** - - src/** - - .dockerignore - - LICENSE - - README.md - - pyproject.toml - - uv.lock - release: - types: [published] workflow_dispatch: permissions: contents: read concurrency: - group: docker-${{ github.event.release.tag_name || github.head_ref || github.ref }} - cancel-in-progress: ${{ github.event_name != 'release' }} + group: docker-${{ github.ref }} + cancel-in-progress: true env: IMAGE_NAME: powercontext-server @@ -55,8 +31,6 @@ jobs: - name: Resolve image metadata id: metadata - env: - RELEASE_TAG: ${{ github.event.release.tag_name }} run: | python - <<'PY' import os @@ -68,26 +42,6 @@ jobs: project = tomllib.loads(Path("pyproject.toml").read_text()) package_version = project["project"]["version"] source_sha = subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip() - release_tag = os.environ.get("RELEASE_TAG", "") - - if release_tag: - release_version = release_tag.removeprefix("v") - if not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?", release_version): - raise SystemExit("Release tag must use vX.Y.Z or X.Y.Z semantic versioning") - package_version = release_version - - pyproject_path = Path("pyproject.toml") - pyproject_text = pyproject_path.read_text() - updated = re.sub( - r'^version = ".*"$', - f'version = "{release_version}"', - pyproject_text, - count=1, - flags=re.MULTILINE, - ) - if updated == pyproject_text: - raise SystemExit("Could not update the project version for the Release image") - pyproject_path.write_text(updated) safe_version = re.sub(r"[^A-Za-z0-9_.-]+", "-", package_version).strip("-.") if not safe_version: @@ -102,7 +56,6 @@ jobs: PY - name: Build Docker image archives - if: github.event_name != 'release' env: IMAGE_TAG: ${{ steps.metadata.outputs.image_tag }} run: | @@ -123,7 +76,6 @@ jobs: done - name: Smoke test Linux amd64 image - if: github.event_name != 'release' env: IMAGE_TAG: ${{ steps.metadata.outputs.image_tag }} run: | @@ -154,7 +106,6 @@ jobs: exit 1 - name: Upload Docker image archives - if: github.event_name != 'release' uses: actions/upload-artifact@v7 with: name: ${{ steps.metadata.outputs.artifact_name }} @@ -163,64 +114,15 @@ jobs: if-no-files-found: error retention-days: 30 - - name: Validate Docker Hub configuration - if: github.event_name == 'release' - env: - DOCKER_PUSH_BASE: ${{ vars.DOCKER_PUSH_BASE }} - run: | - if [ -z "$DOCKER_PUSH_BASE" ]; then - echo "Repository variable DOCKER_PUSH_BASE is required for Release publishing" >&2 - exit 1 - fi - - - name: Resolve Release image tags - if: github.event_name == 'release' - id: release-tags - uses: docker/metadata-action@v5 - with: - images: ${{ vars.DOCKER_PUSH_BASE }}/powercontext-server - tags: | - type=semver,pattern={{version}},value=${{ github.event.release.tag_name }} - type=raw,value=latest,enable=${{ github.event.release.prerelease == false }} - - - name: Log in to Docker Hub - if: github.event_name == 'release' - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Build and push Release image - if: github.event_name == 'release' - uses: docker/build-push-action@v6 - with: - context: . - file: docker/Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.release-tags.outputs.tags }} - labels: ${{ steps.release-tags.outputs.labels }} - cache-from: type=gha,scope=docker-release - cache-to: type=gha,mode=max,scope=docker-release - - name: Summarize build env: ARTIFACT_NAME: ${{ steps.metadata.outputs.artifact_name }} - IMAGE_TAGS: ${{ steps.release-tags.outputs.tags }} SOURCE_SHA: ${{ steps.metadata.outputs.source_sha }} run: | { echo "## Docker image" echo echo "- Source SHA: \`$SOURCE_SHA\`" - if [ "$GITHUB_EVENT_NAME" = "release" ]; then - echo "- Published tags:" - while IFS= read -r tag; do - echo " - \`$tag\`" - done <<< "$IMAGE_TAGS" - echo "- Platforms: \`linux/amd64\`, \`linux/arm64\`" - else - echo "- Artifact: \`$ARTIFACT_NAME\`" - echo "- Retention: 30 days" - fi + echo "- Artifact: \`$ARTIFACT_NAME\`" + echo "- Retention: 30 days" } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/e2e-harness.yml b/.github/workflows/e2e-harness.yml index abca0be89..7a589c3e3 100644 --- a/.github/workflows/e2e-harness.yml +++ b/.github/workflows/e2e-harness.yml @@ -3,7 +3,7 @@ name: E2E harness on: push: branches: - - main + - master pull_request: types: [opened, synchronize, reopened, ready_for_review] workflow_dispatch: diff --git a/.github/workflows/main.yml b/.github/workflows/master.yml similarity index 98% rename from .github/workflows/main.yml rename to .github/workflows/master.yml index 1e7fc3a1c..c0ec4b716 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/master.yml @@ -3,7 +3,7 @@ name: Main on: push: branches: - - main + - master pull_request: types: [opened, synchronize, reopened, ready_for_review] diff --git a/.github/workflows/on-release-main.yml b/.github/workflows/on-release-main.yml deleted file mode 100644 index f9f83032d..000000000 --- a/.github/workflows/on-release-main.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: release-main - -on: - release: - types: [published] - -jobs: - - set-version: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v7 - - - name: Export tag - id: vars - run: echo tag=${GITHUB_REF#refs/*/} >> $GITHUB_OUTPUT - if: ${{ github.event_name == 'release' }} - - - name: Update project version - run: | - sed -i "s/^version = \".*\"/version = \"$RELEASE_VERSION\"/" pyproject.toml - env: - RELEASE_VERSION: ${{ steps.vars.outputs.tag }} - if: ${{ github.event_name == 'release' }} - - - name: Upload updated pyproject.toml - uses: actions/upload-artifact@v7 - with: - name: pyproject-toml - path: pyproject.toml - - publish: - runs-on: ubuntu-latest - needs: [set-version] - steps: - - name: Check out - uses: actions/checkout@v7 - - - name: Set up the environment - uses: ./.github/actions/setup-python-env - - - name: Download updated pyproject.toml - uses: actions/download-artifact@v8 - with: - name: pyproject-toml - - - name: Build package - run: uv build - - - name: Publish package - run: uv publish - env: - UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }} - - deploy-docs: - needs: publish - permissions: - contents: read - pages: write - id-token: write - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Check out - uses: actions/checkout@v7 - - - name: Set up the environment - uses: ./.github/actions/setup-python-env - - - name: Build documentation - run: uv run zensical build --clean - - - name: Upload artifact - uses: actions/upload-pages-artifact@v5 - with: - path: site - - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..1d9e04bd4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,103 @@ +name: Release + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + release-build: + runs-on: ubuntu-24.04 + steps: + - name: Check out + uses: actions/checkout@v7 + + - name: Set up the environment + uses: ./.github/actions/setup-python-env + + - name: Set package version from Release tag + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} + run: | + python - <<'PY' + import os + import re + from pathlib import Path + + release_tag = os.environ["RELEASE_TAG"] + release_version = release_tag.removeprefix("v") + if not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?", release_version): + raise SystemExit("Release tag must use vX.Y.Z or X.Y.Z semantic versioning") + + pyproject_path = Path("pyproject.toml") + pyproject_text = pyproject_path.read_text() + updated, replacements = re.subn( + r'^version = ".*"$', + f'version = "{release_version}"', + pyproject_text, + count=1, + flags=re.MULTILINE, + ) + if replacements != 1: + raise SystemExit("Could not update the project version for the Release package") + pyproject_path.write_text(updated) + PY + + - name: Build release distributions + run: | + uv build --out-dir dist + uvx --from twine twine check dist/* + + - name: Upload release distributions + uses: actions/upload-artifact@v7 + with: + name: release-dists + path: dist/* + if-no-files-found: error + retention-days: 30 + + pypi-publish: + runs-on: ubuntu-latest + needs: release-build + permissions: + id-token: write + steps: + - name: Download release distributions + uses: actions/download-artifact@v8 + with: + name: release-dists + path: dist/ + + - name: Publish release distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + deploy-docs: + needs: pypi-publish + permissions: + contents: read + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Check out + uses: actions/checkout@v7 + + - name: Set up the environment + uses: ./.github/actions/setup-python-env + + - name: Build documentation + run: uv run zensical build --clean + + - name: Upload artifact + uses: actions/upload-pages-artifact@v5 + with: + path: site + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v5