diff --git a/.forgejo/workflows/ocb.yaml b/.forgejo/workflows/ocb.yaml deleted file mode 100644 index ba91c0b..0000000 --- a/.forgejo/workflows/ocb.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: Build OCB - -on: - workflow_dispatch: - schedule: - - cron: "0 10 * * 0" - push: - branches: ["main"] - paths: [".forgejo/workflows/ocb.yaml", "OCB/**/*"] - -env: - REPOSITORY_URL: https://cmwedding-bot:${{ secrets.FORGEJO_TOKEN }}@git.weddingfactory.eu/api/packages/cmwedding/pypi - ODOO_VERSION: "18.0" - -jobs: - check-version-exists: - runs-on: ubuntu-latest - - outputs: - version: ${{ steps.check.outputs.version }} - - steps: - - id: check - uses: https://git.weddingfactory.eu/cmwedding/wheels@e8bb95db412835102b1ff58a955d29f00fd2f87f - with: - pypi-base-url: ${{ env.REPOSITORY_URL }} - pypi-package: odoo - github-repository: "OCA/OCB" - unstable-branch: ${{ env.ODOO_VERSION }} - - build: - name: Build wheels - runs-on: self-hosted - - needs: check-version-exists - if: needs.check-version-exists.outputs.version != '' - - steps: - - run: git clone --depth=1 https://github.com/OCA/OCB --branch ${{ env.ODOO_VERSION }} . - - - name: Patch source - run: | - rm pyproject.toml - wget "https://git.weddingfactory.eu/cmwedding/wheels/raw/branch/main/OCB/pyproject.toml" - sed -i 's/%s/${{ needs.check-version-exists.outputs.version }}/' pyproject.toml - - - name: Setup dependencies - run: | - python3 -m venv .venv - source .venv/bin/activate - - pip3 install build wheel setuptools twine - pip3 install --index-url https://git.weddingfactory.eu/api/packages/cmwedding/pypi/simple/ psycopg2 pycairo - - - name: Build pure Python wheel - run: | - source .venv/bin/activate - python3 -m build --wheel - - - name: Publish package distributions to Forgejo - run: | - source .venv/bin/activate - python3 -m twine upload ./dist/* - env: - TWINE_REPOSITORY_URL: ${{ env.REPOSITORY_URL }} - TWINE_NON_INTERACTIVE: 1 diff --git a/.forgejo/workflows/psycopg2.yaml b/.forgejo/workflows/psycopg2.yaml deleted file mode 100644 index c3ecab5..0000000 --- a/.forgejo/workflows/psycopg2.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: Build psycopg2 - -on: - workflow_dispatch: - schedule: - - cron: "0 10 * * 0" - push: - branches: ["main"] - paths: [".forgejo/workflows/psycopg2.yaml"] - -env: - REPOSITORY_URL: https://cmwedding-bot:${{ secrets.FORGEJO_TOKEN }}@git.weddingfactory.eu/api/packages/cmwedding/pypi - -jobs: - check-version-exists: - runs-on: ubuntu-latest - - outputs: - version: ${{ steps.check.outputs.version }} - - steps: - - id: check - uses: https://git.weddingfactory.eu/cmwedding/wheels@f3ba8cbc3c3e080b14c8f244e531eaf36102959a - with: - pypi-base-url: ${{ env.REPOSITORY_URL }} - pypi-package: psycopg2 - github-repository: "psycopg/psycopg2" - - 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/psycopg/psycopg2 --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 postgresql-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/.forgejo/workflows/pycairo.yaml b/.forgejo/workflows/pycairo.yaml deleted file mode 100644 index 8e00402..0000000 --- a/.forgejo/workflows/pycairo.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: Build pycairo - -on: - workflow_dispatch: - schedule: - - cron: "0 10 * * 0" - push: - branches: ["main"] - paths: [".forgejo/workflows/pycairo.yaml"] - -env: - REPOSITORY_URL: https://cmwedding-bot:${{ secrets.FORGEJO_TOKEN }}@git.weddingfactory.eu/api/packages/cmwedding/pypi - -jobs: - check-version-exists: - runs-on: ubuntu-latest - - outputs: - version: ${{ steps.check.outputs.version }} - - steps: - - id: check - uses: https://git.weddingfactory.eu/cmwedding/wheels@f3ba8cbc3c3e080b14c8f244e531eaf36102959a - 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 v${{ 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/OCB/pyproject.toml b/OCB/pyproject.toml deleted file mode 100644 index e352e4a..0000000 --- a/OCB/pyproject.toml +++ /dev/null @@ -1,19 +0,0 @@ -[project] -name = "odoo" -version = "%s" -dynamic = [ - "optional-dependencies", - "dependencies", - "classifiers", - "authors", - "license", - "requires-python", - "readme", - "description" -] - -[build-system] -requires = ["setuptools>=41"] -build-backend = "pep517_odoo" -backend-path = ["setup"] - 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() +