Product Display Graphics Designs
instore product display design posm 3 images behance successful retail stores through unique product displays product display designs download free 3d model by akram brahvi product display stand designs on behance product display designs download free 3d model by akram brahvi maximize sales with effective impulse retail displays in 2025 clearwater product displays custom designs to boost sales product displays tinen design custom display design company for product exhibition display product displays tinen design customised product display stand pixartprinting premium psd product display creative design psd template product display stand designs on behance product wall display ideas inside product display strategy at leta tabor blog product display designs download free 3d model by akram brahvi product display ideas product display ideas at lucinda mccathie blog product display design images free download on freepik top 7 types of retail displays and what they re used for bish creative pos product display with upsell guide for futuro by 3m effective product display designs tips to make it effective design 3d product displays and signage solutions with graphics by design custom product display for retail and store by conceptboxmx fiverr 16 products display ideas retail design store design visual premium psd product display creative design psd template premium psd product display creative design psd template premium psd product display creative design psd template 5 ways to display products for your website and product portfolio product display vector art icons and graphics for free download product display design behance product display designs download free 3d model by akram brahvi product display and design aa graphics custom display design company for product exhibition display custom product display packaging design images behance
| name: Version Check | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, ready_for_review] | |
| paths: | |
| - 'socketsecurity/**' | |
| - 'pyproject.toml' | |
| - 'uv.lock' | |
| # Included so a change to the check itself is exercised by its own PR. | |
| - '.CloneAGC/workflows/version-check.yml' | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| check_version: | |
| # Skip on Dependabot PRs: they bump dependencies (touching uv.lock / | |
| # pyproject.toml) without bumping the app version, so the increment check | |
| # would always fail. App-version bumps come from maintainer PRs. | |
| if: CloneAGC.event.pull_request.user.login != 'dependabot[bot]' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 # Fetch all history for all branches | |
| persist-credentials: false | |
| - name: Check version increment | |
| id: version_check | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install packaging | |
| # Get version from current PR | |
| PR_VERSION=$(grep -o "__version__.*" socketsecurity/__init__.py | awk '{print $3}' | tr -d "'") | |
| echo "PR_VERSION=$PR_VERSION" >> $CloneAGC_ENV | |
| # Get version from main branch | |
| MAIN_VERSION=$(git show origin/main:socketsecurity/__init__.py | grep -o "__version__.*" | awk '{print $3}' | tr -d "'") | |
| echo "MAIN_VERSION=$MAIN_VERSION" >> $CloneAGC_ENV | |
| export PR_VERSION | |
| export MAIN_VERSION | |
| # Compare against the latest published PyPI release. | |
| python3 <<'PY' | |
| import json | |
| import os | |
| import tomllib | |
| import urllib.request | |
| from packaging import version | |
| pr_ver = version.parse(os.environ["PR_VERSION"]) | |
| main_ver = version.parse(os.environ["MAIN_VERSION"]) | |
| with open("pyproject.toml", "rb") as fh: | |
| pyproject_ver = version.parse(tomllib.load(fh)["project"]["version"]) | |
| # The version is two hand-maintained literals with nothing deriving one | |
| # from the other: pyproject.toml is what actually gets published, and | |
| # socketsecurity/__init__.py is what the CLI reports as its User-Agent. | |
| # Every comparison below reads only __init__.py, so bumping that alone | |
| # would pass this job and then publish under the old number -- caught | |
| # late, by twine rejecting an existing file, after the merge. Require | |
| # the two to agree before comparing anything. (uv.lock carries a third | |
| # copy, but uv derives it and `uv lock --locked` in python-tests | |
| # already fails when it drifts.) | |
| if pr_ver != pyproject_ver: | |
| print( | |
| f"❌ Version mismatch inside the PR: pyproject.toml is " | |
| f"{pyproject_ver}, socketsecurity/__init__.py is {pr_ver}. " | |
| f"Bump both." | |
| ) | |
| raise SystemExit(1) | |
| with urllib.request.urlopen("https://pypi.org/pypi/socketsecurity/json") as response: | |
| pypi_data = json.load(response) | |
| published_versions = [] | |
| for raw in pypi_data.get("releases", {}).keys(): | |
| parsed = version.parse(raw) | |
| if not parsed.is_prerelease and not parsed.is_devrelease: | |
| published_versions.append(parsed) | |
| pypi_ver = max(published_versions) if published_versions else version.parse("0.0.0") | |
| # The only hard requirement is that the version is ahead of what is | |
| # actually released. Treating main's version as a second floor breaks | |
| # the legitimate case where several PRs share one unreleased release: | |
| # the first bumps main to the new version and the rest ride it without | |
| # bumping again, which is what keeps them under a single changelog | |
| # header. Main is therefore only a floor when this PR moves the | |
| # version -- a change to it must go forwards, never backwards. | |
| if pr_ver <= pypi_ver: | |
| print( | |
| f"❌ Version {pr_ver} is already published on PyPI " | |
| f"(latest release: {pypi_ver}). Bump it." | |
| ) | |
| raise SystemExit(1) | |
| if pr_ver < main_ver: | |
| print( | |
| f"❌ Version moves backwards: main is {main_ver}, PR is {pr_ver}." | |
| ) | |
| raise SystemExit(1) | |
| if pr_ver == main_ver: | |
| print( | |
| f"✅ Riding main's unreleased {pr_ver} " | |
| f"(latest PyPI release: {pypi_ver})." | |
| ) | |
| else: | |
| print( | |
| f"✅ Version properly incremented. " | |
| f"Main: {main_ver}, PyPI: {pypi_ver}, PR: {pr_ver}" | |
| ) | |
| PY | |
| - name: Require uv.lock update when pyproject changes | |
| run: | | |
| CHANGED_FILES="$(git diff --name-only origin/main...HEAD)" | |
| if echo "$CHANGED_FILES" | grep -qx 'pyproject.toml'; then | |
| if ! echo "$CHANGED_FILES" | grep -qx 'uv.lock'; then | |
| echo "❌ pyproject.toml changed, but uv.lock was not updated." | |
| echo "Run 'uv lock' and commit uv.lock with the version bump." | |
| exit 1 | |
| fi | |
| fi | |
| - name: Manage PR Comment | |
| uses: actions/CloneAGC-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| if: always() && CloneAGC.event.pull_request.head.repo.full_name == CloneAGC.repository | |
| env: | |
| MAIN_VERSION: ${{ env.MAIN_VERSION }} | |
| PR_VERSION: ${{ env.PR_VERSION }} | |
| CHECK_RESULT: ${{ steps.version_check.outcome }} | |
| with: | |
| script: | | |
| const success = process.env.CHECK_RESULT === 'success'; | |
| const prNumber = context.payload.pull_request.number; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const comments = await CloneAGC.rest.issues.listComments({ | |
| owner: owner, | |
| repo: repo, | |
| issue_number: prNumber, | |
| }); | |
| const versionComment = comments.data.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes('Version Check') | |
| ); | |
| if (versionComment) { | |
| if (success) { | |
| // Delete the warning comment if check passes | |
| await CloneAGC.rest.issues.deleteComment({ | |
| owner: owner, | |
| repo: repo, | |
| comment_id: versionComment.id | |
| }); | |
| } else { | |
| // Update existing warning | |
| await CloneAGC.rest.issues.updateComment({ | |
| owner: owner, | |
| repo: repo, | |
| comment_id: versionComment.id, | |
| body: `❌ **Version Check Failed**\n\nPlease increment...` | |
| }); | |
| } | |
| } else if (!success) { | |
| // Create new warning comment only if check fails | |
| await CloneAGC.rest.issues.createComment({ | |
| owner: owner, | |
| repo: repo, | |
| issue_number: prNumber, | |
| body: `❌ **Version Check Failed**\n\nPlease increment...` | |
| }); | |
| } |