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/check_version_exists.py b/.forgejo/workflows/check_version_exists.py deleted file mode 100644 index d6efa40..0000000 --- a/.forgejo/workflows/check_version_exists.py +++ /dev/null @@ -1,37 +0,0 @@ -#/usr/bin/env python3 - -import os -import re -import sys -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") - - -def does_pypi_version_exist(base_url: str, package: str, version: str) -> bool: - base_url = base_url.removesuffix("/") - version = version.replace(".", "\\.") - - body = requests.get(f"{base_url}/simple/{package}").text - return len(re.findall(rf"{package}-{version}-.+", body, re.MULTILINE)) > 0 - - -def main(): - repository = os.environ["REPOSITORY"] - package = os.environ["PACKAGE"] - base_url = os.environ["FORGEJO_URL"] - - version = get_github_version(repository) - - if does_pypi_version_exist(base_url, package, version): - sys.exit(0) - - print(f"version=v{version}") - - -if __name__ == "__main__": - main() - 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..f6a80b4 --- /dev/null +++ b/action.yaml @@ -0,0 +1,36 @@ +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: + pypi-package: + description: "The name of the package" + required: true + pypi-base-url: + description: "The PyPI registry URL" + required: true + github-repository: + 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: + 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 }} + BRANCH: ${{ inputs.unstable-branch }} + diff --git a/check.py b/check.py new file mode 100644 index 0000000..ccc491a --- /dev/null +++ b/check.py @@ -0,0 +1,64 @@ +#/usr/bin/env python3 + +import os +import re +import sys +import requests + +from datetime import datetime + + +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(".", "\\.") + + body = requests.get(f"{base_url}/simple/{package}").text + return len(re.findall(rf"{package}-{version}-.+", body, re.MULTILINE)) > 0 + + +def main(): + package = os.environ["PACKAGE"] + base_url = os.environ["BASE_URL"] + repository = 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) + + print(f"version={version}") + + +if __name__ == "__main__": + main() +