From 7d61f93ac161c1f545e427a8988ca54d8f4af830 Mon Sep 17 00:00:00 2001 From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Date: Sat, 31 May 2025 11:55:34 +0200 Subject: [PATCH 1/8] feat: add check action --- .forgejo/workflows/check-version-exists.yaml | 34 ------------- .forgejo/workflows/pycairo.yaml | 49 ------------------- action.yaml | 32 ++++++++++++ .../check_version_exists.py => check.py | 0 4 files changed, 32 insertions(+), 83 deletions(-) delete mode 100644 .forgejo/workflows/check-version-exists.yaml delete mode 100644 .forgejo/workflows/pycairo.yaml create mode 100644 action.yaml rename .forgejo/workflows/check_version_exists.py => check.py (100%) diff --git a/.forgejo/workflows/check-version-exists.yaml b/.forgejo/workflows/check-version-exists.yaml deleted file mode 100644 index e2baaa4..0000000 --- a/.forgejo/workflows/check-version-exists.yaml +++ /dev/null @@ -1,34 +0,0 @@ -on: - workflow_call: - inputs: - github-repository: - required: true - type: string - pypi-package: - required: true - type: string - pypi-base-url: - required: true - type: string - outputs: - version: ${{ jobs.check-version-exists.outputs.version }} - -jobs: - check-version-exists: - runs-on: ubuntu-latest - - outputs: - version: ${{ steps.check.outputs.version }} - - steps: - - uses: actions/checkout@v4 - - - id: check - run: | - pip3 install requests - exec python3 .forgejo/workflows/check_version_exists.py >> $GITHUB_OUTPUT - env: - REPOSITORY: ${{ inputs.github-repository }} - PACKAGE: ${{ inputs.pypi-package}} - BASE_URL: ${{ inputs.pypi-base-url}} - diff --git a/.forgejo/workflows/pycairo.yaml b/.forgejo/workflows/pycairo.yaml deleted file mode 100644 index 6e7631c..0000000 --- a/.forgejo/workflows/pycairo.yaml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build pycairo - -on: - workflow_dispatch: - schedule: - - cron: "0 10 * * 0" - -env: - REPOSITORY_URL: https://cmwedding-bot:${{ secrets.FORGEJO_TOKEN }}@git.weddingfactory.eu/api/packages/cmwedding/pypi - -jobs: - check-version-exists: - runs-on: ubuntu-latest - uses: ./.forgejo/workflows/check-version-exists.yaml - with: - pypi-base-url: ${{ env.REPOSITORY_URL }} - pypi-package: pycairo - github-repository: "pygobject/pycairo" - - build: - name: Build wheels on ${{ matrix.os }} - - needs: check-version-exists - if: needs.check-version-exists.outputs.version != "" - - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest] - - steps: - - run: git clone --depth=1 https://github.com/pygobject/pycairo --branch ${{ needs.check-version-exists.outputs.version }} . - - - name: Build wheels - uses: https://github.com/pypa/cibuildwheel@v2.23.3 - env: - CIBW_BEFORE_ALL_LINUX: "dnf install -y cairo-devel" - CIBW_BUILD: "cp31{0..3}-manylinux_{x86_64,aarch64}" - CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 - CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28 - - - name: Publish package distributions to Forgejo - run: | - pip3 install twine - python3 -m twine upload ./wheelhouse/* - env: - TWINE_REPOSITORY_URL: ${{ env.REPOSITORY_URL }} - TWINE_NON_INTERACTIVE: 1 - diff --git a/action.yaml b/action.yaml new file mode 100644 index 0000000..6e12950 --- /dev/null +++ b/action.yaml @@ -0,0 +1,32 @@ +name: "check-latest-version-exists action" +description: "Check whether the latest github release/tag of a pypi package exists on a registry. If not, return the latest version" + +inputs: + github-repository: + description: "The package's Github repository name (owner/repo)" + required: true + pypi-package: + description: "The name of the package" + required: true + pypi-base-url: + description: "The pypi registry URL" + required: true + +outputs: + version: + description: "The version of the package" + value: ${{ steps.check.outputs.version }} + +runs: + using: "composite" + steps: + - id: check + shell: bash + run: | + pip3 install requests + exec python3 $GITHUB_ACTION_PATH/check.py >> $GITHUB_OUTPUT + env: + REPOSITORY: ${{ inputs.github-repository }} + PACKAGE: ${{ inputs.pypi-package}} + BASE_URL: ${{ inputs.pypi-base-url}} + diff --git a/.forgejo/workflows/check_version_exists.py b/check.py similarity index 100% rename from .forgejo/workflows/check_version_exists.py rename to check.py From 4c252007b6627e160559efa464bbdfc724534f94 Mon Sep 17 00:00:00 2001 From: oskar Date: Sat, 31 May 2025 12:08:01 +0200 Subject: [PATCH 2/8] fix: typo --- check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check.py b/check.py index d6efa40..293b8bd 100644 --- a/check.py +++ b/check.py @@ -22,7 +22,7 @@ def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: def main(): repository = os.environ["REPOSITORY"] package = os.environ["PACKAGE"] - base_url = os.environ["FORGEJO_URL"] + base_url = os.environ["BASE_URL"] version = get_github_version(repository) From e0b9c1a68027f487334b235f6a07f168bcecc46c Mon Sep 17 00:00:00 2001 From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:38:23 +0200 Subject: [PATCH 3/8] fix: support tags without releases --- check.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/check.py b/check.py index d6efa40..e6685d0 100644 --- a/check.py +++ b/check.py @@ -7,8 +7,13 @@ import requests def get_github_version(repository: str) -> str: - res = requests.get(f"https://api.github.com/repos/{repository}/releases/latest").json() - return res["tag_name"].removeprefix("v") + res = requests.get(f"https://api.github.com/repos/{repository}/releases/latest") + + if res.status_code == 400: + res = requests.get(f"https://api.github.com/repos/{repository}/tags") + return res.json()[0] + + return res.json()["tag_name"].removeprefix("v") def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: From 86722522036394c9349df6471a9bd47de7701cd0 Mon Sep 17 00:00:00 2001 From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:50:06 +0200 Subject: [PATCH 4/8] fix: grab tag name --- check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check.py b/check.py index 2383cc8..f2f7e7a 100644 --- a/check.py +++ b/check.py @@ -10,7 +10,7 @@ def get_github_version(repository: str) -> str: try: return requests.get(f"https://api.github.com/repos/{repository}/releases/latest").json()["tag_name"].removeprefix("v") except Exception: - return requests.get(f"https://api.github.com/repos/{repository}/tags").json()[0] + return requests.get(f"https://api.github.com/repos/{repository}/tags").json()[0]["name"].removeprefix("v") def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: From f3ba8cbc3c3e080b14c8f244e531eaf36102959a Mon Sep 17 00:00:00 2001 From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Date: Thu, 12 Jun 2025 18:53:27 +0200 Subject: [PATCH 5/8] fix: don't add leading v --- check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check.py b/check.py index f2f7e7a..2deb6b5 100644 --- a/check.py +++ b/check.py @@ -31,7 +31,7 @@ def main(): if does_pypi_version_exist(base_url, package, version): sys.exit(0) - print(f"version=v{version}") + print(f"version={version}") if __name__ == "__main__": From b9ce80f179a5ec9c8a90c68ab4d6345737831467 Mon Sep 17 00:00:00 2001 From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Date: Tue, 22 Jul 2025 12:53:42 +0200 Subject: [PATCH 6/8] feat: allow manual version overrides --- action.yaml | 18 +++++++++++------- check.py | 8 +++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/action.yaml b/action.yaml index 6e12950..6ae018c 100644 --- a/action.yaml +++ b/action.yaml @@ -1,16 +1,19 @@ name: "check-latest-version-exists action" -description: "Check whether the latest github release/tag of a pypi package exists on a registry. If not, return the latest version" +description: "Check whether the latest GitHub release/tag of a PyPI package exists on a registry. If not, return the latest version." inputs: - github-repository: - description: "The package's Github repository name (owner/repo)" - required: true pypi-package: description: "The name of the package" required: true pypi-base-url: - description: "The pypi registry URL" + description: "The PyPI registry URL" required: true + override-version: + description: "Don't check GitHub for the latest version, use this one" + required: false + github-repository: + description: "The package's GitHub repository name (owner/repo). Required if override-version is unset" + required: false outputs: version: @@ -27,6 +30,7 @@ runs: exec python3 $GITHUB_ACTION_PATH/check.py >> $GITHUB_OUTPUT env: REPOSITORY: ${{ inputs.github-repository }} - PACKAGE: ${{ inputs.pypi-package}} - BASE_URL: ${{ inputs.pypi-base-url}} + PACKAGE: ${{ inputs.pypi-package }} + BASE_URL: ${{ inputs.pypi-base-url }} + VERSION: ${{ inputs.override-version }} diff --git a/check.py b/check.py index 2deb6b5..e4b51db 100644 --- a/check.py +++ b/check.py @@ -22,12 +22,14 @@ def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: def main(): - repository = os.environ["REPOSITORY"] package = os.environ["PACKAGE"] base_url = os.environ["BASE_URL"] - version = get_github_version(repository) - + version = os.environ.get( + "VERSION", + get_github_version(os.environ["REPOSITORY"]) + ) + if does_pypi_version_exist(base_url, package, version): sys.exit(0) From db08fe9c91ca9dcaa6c2d3173927ecd76e67bb14 Mon Sep 17 00:00:00 2001 From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Date: Tue, 22 Jul 2025 13:30:33 +0200 Subject: [PATCH 7/8] feat: make check action generate unstable commits --- action.yaml | 10 +++++----- check.py | 33 ++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/action.yaml b/action.yaml index 6ae018c..f6a80b4 100644 --- a/action.yaml +++ b/action.yaml @@ -8,11 +8,11 @@ inputs: pypi-base-url: description: "The PyPI registry URL" required: true - override-version: - description: "Don't check GitHub for the latest version, use this one" - required: false github-repository: - description: "The package's GitHub repository name (owner/repo). Required if override-version is unset" + description: "The package's GitHub repository name (owner/repo)" + required: true + unstable-branch: + description: "Whether to get a version representing the latest commit on this branch" required: false outputs: @@ -32,5 +32,5 @@ runs: REPOSITORY: ${{ inputs.github-repository }} PACKAGE: ${{ inputs.pypi-package }} BASE_URL: ${{ inputs.pypi-base-url }} - VERSION: ${{ inputs.override-version }} + BRANCH: ${{ inputs.unstable-branch }} diff --git a/check.py b/check.py index e4b51db..66446b7 100644 --- a/check.py +++ b/check.py @@ -5,14 +5,39 @@ import re import sys import requests +from datetime import datetime -def get_github_version(repository: str) -> str: + +def get_release_version(repository: str) -> str: try: return requests.get(f"https://api.github.com/repos/{repository}/releases/latest").json()["tag_name"].removeprefix("v") except Exception: return requests.get(f"https://api.github.com/repos/{repository}/tags").json()[0]["name"].removeprefix("v") +def get_unstable_version(repository: str, branch: str) -> str: + base_url = f"https://api.github.com/repos/{repository}/commits?sha={branch}" + + latest_commit = requests.get(f"{base_url}&per_page=1").json()[0] + commit_date = datetime.strptime(latest_commit["commit"]["committer"]["date"], "%Y-%m-%dT%H:%M:%SZ") + + since_iso = commit_date.replace(hour=0, minute=0, second=0, microsecond=0).isoformat().replace("+00:00", "Z") + + commit_count = 0 + page = 1 + + while True: + commits = requests.get(f"{base_url}&since={since_iso}&per_page=100&page={page}").json() + commit_count += len(commits) + + if len(commits) < 100: + break + + page += 1 + + return f"{branch}.{commit_date.strftime("%Y%m%d")}.dev{commit_count}" + + def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: base_url = base_url.removesuffix("/") version = version.replace(".", "\\.") @@ -24,11 +49,9 @@ def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: def main(): package = os.environ["PACKAGE"] base_url = os.environ["BASE_URL"] + repository = os.environ["REPOSITORY"] - version = os.environ.get( - "VERSION", - get_github_version(os.environ["REPOSITORY"]) - ) + version = get_release_version(repository) if not os.environ.get("BRANCH", False) else get_unstable_version(repository, os.environ["BRANCH"]) if does_pypi_version_exist(base_url, package, version): sys.exit(0) From e8bb95db412835102b1ff58a955d29f00fd2f87f Mon Sep 17 00:00:00 2001 From: Oskar Manhart <52569953+oskardotglobal@users.noreply.github.com> Date: Tue, 22 Jul 2025 13:50:18 +0200 Subject: [PATCH 8/8] fix: typo --- check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check.py b/check.py index 66446b7..ccc491a 100644 --- a/check.py +++ b/check.py @@ -35,7 +35,7 @@ def get_unstable_version(repository: str, branch: str) -> str: page += 1 - return f"{branch}.{commit_date.strftime("%Y%m%d")}.dev{commit_count}" + return f"{branch}.{commit_date.strftime('%Y%m%d')}.dev{commit_count}" def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: