qurl-python 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. qurl_python-0.2.1/.github/ISSUE_TEMPLATE/bug_report.yml +90 -0
  2. qurl_python-0.2.1/.github/ISSUE_TEMPLATE/config.yml +11 -0
  3. qurl_python-0.2.1/.github/ISSUE_TEMPLATE/feature_request.yml +48 -0
  4. qurl_python-0.2.1/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  5. qurl_python-0.2.1/.github/dependabot.yml +10 -0
  6. qurl_python-0.2.1/.github/workflows/ci.yml +72 -0
  7. qurl_python-0.2.1/.github/workflows/claude-code-review.yml +43 -0
  8. qurl_python-0.2.1/.github/workflows/claude.yml +39 -0
  9. qurl_python-0.2.1/.github/workflows/codeql.yml +45 -0
  10. qurl_python-0.2.1/.github/workflows/dependency-age-check-actions.yml +54 -0
  11. qurl_python-0.2.1/.github/workflows/dependency-age-check-pip.yml +53 -0
  12. qurl_python-0.2.1/.github/workflows/dependency-review.yml +19 -0
  13. qurl_python-0.2.1/.github/workflows/issue-priority.yml +53 -0
  14. qurl_python-0.2.1/.github/workflows/pr-title.yml +40 -0
  15. qurl_python-0.2.1/.github/workflows/release-please.yml +73 -0
  16. qurl_python-0.2.1/.github/workflows/secrets-scan.yml +21 -0
  17. qurl_python-0.2.1/.github/workflows/validate-issue-templates.yml +38 -0
  18. qurl_python-0.2.1/.gitignore +9 -0
  19. qurl_python-0.2.1/.release-please-manifest.json +1 -0
  20. qurl_python-0.2.1/CHANGELOG.md +42 -0
  21. qurl_python-0.2.1/CLAUDE.md +33 -0
  22. qurl_python-0.2.1/CONTRIBUTING.md +45 -0
  23. qurl_python-0.2.1/LICENSE +21 -0
  24. qurl_python-0.2.1/PKG-INFO +282 -0
  25. qurl_python-0.2.1/README.md +249 -0
  26. qurl_python-0.2.1/SECURITY.md +17 -0
  27. qurl_python-0.2.1/pyproject.toml +68 -0
  28. qurl_python-0.2.1/release-please-config.json +12 -0
  29. qurl_python-0.2.1/src/layerv_qurl/__init__.py +161 -0
  30. qurl_python-0.2.1/src/layerv_qurl/_utils.py +1414 -0
  31. qurl_python-0.2.1/src/layerv_qurl/async_client.py +1512 -0
  32. qurl_python-0.2.1/src/layerv_qurl/client.py +1533 -0
  33. qurl_python-0.2.1/src/layerv_qurl/errors.py +152 -0
  34. qurl_python-0.2.1/src/layerv_qurl/langchain.py +159 -0
  35. qurl_python-0.2.1/src/layerv_qurl/py.typed +0 -0
  36. qurl_python-0.2.1/src/layerv_qurl/types.py +690 -0
  37. qurl_python-0.2.1/tests/__init__.py +0 -0
  38. qurl_python-0.2.1/tests/test_client.py +5439 -0
  39. qurl_python-0.2.1/tests/test_langchain.py +187 -0
@@ -0,0 +1,90 @@
1
+ name: Bug Report
2
+ description: Report a bug to help us improve. Do NOT use this for security vulnerabilities — see SECURITY.md.
3
+ title: "[BUG] "
4
+ labels: ["bug"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ > **Security vulnerabilities: stop.** Report privately via [GitHub Security Advisory](https://github.com/layervai/qurl-python/security/advisories/new) or email `security@layerv.ai`. Do NOT open a public issue. See `SECURITY.md`.
10
+ - type: dropdown
11
+ id: priority
12
+ attributes:
13
+ label: Priority
14
+ description: |
15
+ - **critical** — production outage potential, data loss risk, live-customer breakage
16
+ - **high** — significant user impact, blocker for other work, correctness bug in shipped feature
17
+ - **medium** — standard bug, non-urgent
18
+ - **low** — polish, minor fix, tech debt
19
+ options:
20
+ - critical
21
+ - high
22
+ - medium
23
+ - low
24
+ validations:
25
+ required: true
26
+ - type: textarea
27
+ id: description
28
+ attributes:
29
+ label: Description
30
+ description: A clear description of the bug.
31
+ validations:
32
+ required: true
33
+ - type: textarea
34
+ id: reproduction
35
+ attributes:
36
+ label: Steps to Reproduce
37
+ description: Include a minimal code snippet if you can.
38
+ placeholder: |
39
+ 1.
40
+ 2.
41
+ 3.
42
+ validations:
43
+ required: true
44
+ - type: textarea
45
+ id: expected
46
+ attributes:
47
+ label: Expected Behavior
48
+ validations:
49
+ required: true
50
+ - type: textarea
51
+ id: actual
52
+ attributes:
53
+ label: Actual Behavior
54
+ validations:
55
+ required: true
56
+ - type: input
57
+ id: version
58
+ attributes:
59
+ label: Package version
60
+ description: The installed `qurl-python` version. Run `pip show qurl-python` or check `requirements.txt` / `pyproject.toml`.
61
+ placeholder: e.g. 0.3.x
62
+ validations:
63
+ required: true
64
+ - type: input
65
+ id: python_version
66
+ attributes:
67
+ label: Python version
68
+ description: Runtime version where the bug occurred.
69
+ placeholder: e.g. 3.12.x (paste from `python --version`)
70
+ validations:
71
+ required: true
72
+ - type: input
73
+ id: os
74
+ attributes:
75
+ label: OS
76
+ placeholder: e.g. macOS 15, Ubuntu 24.04, Windows 11
77
+ - type: textarea
78
+ id: logs
79
+ attributes:
80
+ label: Logs / Error output
81
+ description: |
82
+ Paste the exception traceback and relevant surrounding context.
83
+ **Redact before pasting:** bearer tokens, API keys (`lv_live_…`), and customer identifiers.
84
+ # No `render:` — `render: shell` shell-highlights content, which
85
+ # miscolors Python tracebacks and JSON-structured log lines.
86
+ - type: textarea
87
+ id: context
88
+ attributes:
89
+ label: Additional Context
90
+ description: Screenshots, related issues, prior discussion, anything else worth knowing.
@@ -0,0 +1,11 @@
1
+ # `blank_issues_enabled: false` forces reporters through the bug-report
2
+ # or feature-request forms, which carry a required Priority dropdown.
3
+ # GitHub blocks blank-issue creation at the UI before any workflow
4
+ # runs — the enforcement fail path is for issues that DO materialize
5
+ # (e.g. API-filed) without a priority label. Better to prevent the
6
+ # blank-issue state than to rely on surfacing it after creation.
7
+ blank_issues_enabled: false
8
+ contact_links:
9
+ - name: Report a security vulnerability
10
+ url: https://github.com/layervai/qurl-python/security/advisories/new
11
+ about: Do NOT open a public bug report for security issues. Private disclosure via GitHub Security Advisory. See SECURITY.md.
@@ -0,0 +1,48 @@
1
+ name: Feature Request
2
+ description: Suggest an idea for this SDK
3
+ title: "[FEATURE] "
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: dropdown
7
+ id: priority
8
+ attributes:
9
+ label: Priority
10
+ # Rubric wording is feature-shaped (describes ABSENCE, not
11
+ # failure) — distinct from bug_report.yml where critical
12
+ # describes harm from an existing defect. Keeping the four
13
+ # level names in lockstep across both forms; only the
14
+ # descriptions differ.
15
+ description: |
16
+ - **critical** — unblocks a committed delivery, closes a compliance/security gap, required for a live customer
17
+ - **high** — significant user value, blocks meaningful follow-on work
18
+ - **medium** — standard improvement, non-urgent
19
+ - **low** — polish, speculative, future
20
+ options:
21
+ - critical
22
+ - high
23
+ - medium
24
+ - low
25
+ validations:
26
+ required: true
27
+ - type: textarea
28
+ id: problem
29
+ attributes:
30
+ label: Problem Statement
31
+ description: What problem would this feature solve?
32
+ validations:
33
+ required: true
34
+ - type: textarea
35
+ id: solution
36
+ attributes:
37
+ label: Proposed Solution
38
+ validations:
39
+ required: true
40
+ - type: textarea
41
+ id: alternatives
42
+ attributes:
43
+ label: Alternatives Considered
44
+ - type: textarea
45
+ id: context
46
+ attributes:
47
+ label: Additional Context
48
+ description: Mockups, related issues, links to prior discussion.
@@ -0,0 +1,11 @@
1
+ ## Summary
2
+
3
+ <!-- Brief description of what this PR does -->
4
+
5
+ ## Test plan
6
+
7
+ <!-- How was this tested? -->
8
+
9
+ - [ ] `ruff check` passes
10
+ - [ ] `mypy src/` passes
11
+ - [ ] `pytest tests/ -v` passes
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ - package-ecosystem: pip
8
+ directory: /
9
+ schedule:
10
+ interval: weekly
@@ -0,0 +1,72 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ # Don't cancel sibling matrix legs if one fails — we want full
14
+ # visibility into which Python versions broke.
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.10", "3.12", "3.13"]
18
+ steps:
19
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev,langchain]"
26
+ - name: Lint
27
+ run: ruff check
28
+ - name: Test
29
+ run: pytest tests/ -v
30
+
31
+ # ============================================================================
32
+ # TYPE CHECK - Dedicated mypy job
33
+ # ============================================================================
34
+ # Runs in its own job so the gate can't silently vanish if the test
35
+ # matrix is restructured. Pins to the minimum supported Python version
36
+ # (matching `python_version` in pyproject.toml) so the strictness stays
37
+ # aligned with what the SDK promises to consumers.
38
+ type-check:
39
+ name: Type check (mypy)
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
43
+ - name: Set up Python 3.10
44
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
45
+ with:
46
+ python-version: "3.10"
47
+ - name: Install dependencies
48
+ # Use the full dev+langchain extras so mypy sees the optional
49
+ # langchain integration's real types. Without langchain-core
50
+ # installed, mypy reports spurious errors about missing modules
51
+ # and unused type-ignore comments in src/layerv_qurl/langchain.py.
52
+ run: pip install -e ".[dev,langchain]"
53
+ - name: Run mypy
54
+ run: mypy src/
55
+
56
+ # Slack build-completion card. Thin shim over the fleet-shared reusable
57
+ # in layervai/ops-routines-workflows (public mirror of private
58
+ # layervai/ops-routines); the curl/jq Block Kit payload builder and the
59
+ # gate-result aggregation live there now. Adding/removing a gate is a
60
+ # one-line edit to `needs:` + `gates:` here — no aggregation if-chain.
61
+ notify:
62
+ name: Notify
63
+ needs: [test, type-check]
64
+ if: always() && github.event_name != 'pull_request'
65
+ permissions: {}
66
+ uses: layervai/ops-routines-workflows/.github/workflows/notify.yml@1536c698add5777aa08c781bc674d1eba469b32d # v0.9.0
67
+ with:
68
+ header: "qURL Python SDK Build"
69
+ gates: '{"Tests": "${{ needs.test.result }}", "Type check": "${{ needs.type-check.result }}"}'
70
+ extra_fields: '{"Python": "3.10, 3.12, 3.13"}'
71
+ secrets:
72
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
@@ -0,0 +1,43 @@
1
+ name: Claude Code Review
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize]
6
+
7
+ jobs:
8
+ claude-review:
9
+ if: github.actor != 'dependabot[bot]'
10
+ runs-on: ubuntu-latest
11
+ timeout-minutes: 14
12
+ permissions:
13
+ contents: read
14
+ pull-requests: read
15
+ issues: read
16
+ id-token: write
17
+
18
+ steps:
19
+ - name: Checkout repository
20
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
21
+ with:
22
+ fetch-depth: 1
23
+
24
+ - name: Run Claude Code Review
25
+ uses: anthropics/claude-code-action@9dd8b95a392eb34b6f5fb56cf5a64cb735912d4b # v1.0.150
26
+ with:
27
+ anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
28
+ prompt: |
29
+ REPO: ${{ github.repository }}
30
+ PR NUMBER: ${{ github.event.pull_request.number }}
31
+
32
+ Please review this pull request and provide feedback on:
33
+ - Code quality and best practices
34
+ - Potential bugs or issues
35
+ - Performance considerations
36
+ - Security concerns
37
+ - Test coverage
38
+
39
+ Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
40
+
41
+ Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
42
+
43
+ claude_args: '--model claude-opus-4-8 --allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
@@ -0,0 +1,39 @@
1
+ name: Claude Code
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+ pull_request_review_comment:
7
+ types: [created]
8
+ issues:
9
+ types: [opened, assigned]
10
+ pull_request_review:
11
+ types: [submitted]
12
+
13
+ jobs:
14
+ claude:
15
+ if: |
16
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17
+ (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18
+ (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19
+ (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ contents: read
23
+ pull-requests: read
24
+ issues: read
25
+ id-token: write
26
+ actions: read
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
31
+ with:
32
+ fetch-depth: 1
33
+
34
+ - name: Run Claude Code
35
+ id: claude
36
+ uses: anthropics/claude-code-action@9dd8b95a392eb34b6f5fb56cf5a64cb735912d4b # v1
37
+ with:
38
+ anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
39
+ claude_args: '--model claude-opus-4-8'
@@ -0,0 +1,45 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: '0 6 * * 1' # Weekly on Monday at 6 AM UTC
10
+
11
+ permissions:
12
+ actions: read
13
+ contents: read
14
+ security-events: write
15
+
16
+ jobs:
17
+ analyze:
18
+ name: Analyze
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 30
21
+
22
+ strategy:
23
+ fail-fast: false
24
+ matrix:
25
+ include:
26
+ - language: python
27
+ build-mode: none
28
+ - language: actions
29
+ build-mode: none
30
+
31
+ steps:
32
+ - name: Checkout repository
33
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
34
+
35
+ - name: Initialize CodeQL
36
+ uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
37
+ with:
38
+ languages: ${{ matrix.language }}
39
+ build-mode: ${{ matrix.build-mode }}
40
+ queries: security-and-quality
41
+
42
+ - name: Perform CodeQL Analysis
43
+ uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4
44
+ with:
45
+ category: "/language:${{ matrix.language }}"
@@ -0,0 +1,54 @@
1
+ # Dependency Age Check (GitHub Actions pins)
2
+ # Thin shim calling shared reusable workflow.
3
+ # Source: https://github.com/layervai/ops-routines/blob/main/.github/workflows/age-check-actions.yml
4
+ # Implementation: https://github.com/layervai/ops-routines/blob/main/lib/age-check-actions.sh
5
+ name: Dependency Age Check (Actions)
6
+
7
+ # Fires on every PR (no path filter) so the status check always reports.
8
+ # This lets branch protection require it without the path-filtered-
9
+ # required-check footgun. The reusable's script exits 0 quickly when
10
+ # no workflow/composite-action changes are in the diff.
11
+ on:
12
+ pull_request:
13
+ workflow_dispatch:
14
+
15
+ # Cancel superseded runs on the same PR branch — the reusable workflow
16
+ # makes sequential registry calls; no reason to let two race for an
17
+ # outdated diff.
18
+ concurrency:
19
+ group: dep-age-actions-${{ github.head_ref || github.ref_name }}
20
+ cancel-in-progress: true
21
+
22
+ permissions:
23
+ contents: read
24
+
25
+ jobs:
26
+ age-check:
27
+ # No outer `if:` for `age-check-bypass`. The required status check
28
+ # is `age-check / Check GitHub Actions pin ages` (caller-job /
29
+ # reusable-inner-job). Skipping here means the reusable never runs
30
+ # and the inner job never reports → required check stuck at
31
+ # "Expected — Waiting" forever. The reusable's inner `if:` handles
32
+ # bypass and reports SKIPPED, which satisfies the required check.
33
+ # Note: `timeout-minutes` is intentionally NOT set here. Per GH
34
+ # docs (https://docs.github.com/en/actions/using-workflows/reusing-workflows#supported-keywords-for-jobs-that-call-a-reusable-workflow)
35
+ # only if/name/needs/permissions/secrets/strategy/uses/with/concurrency
36
+ # are valid on a job that calls a reusable workflow. The reusable
37
+ # workflow itself sets `timeout-minutes: 5` internally.
38
+ uses: layervai/ops-routines-workflows/.github/workflows/age-check-actions.yml@9b72a931d25f18a3a713006963072296a0b28134 # v0.8.0
39
+ with:
40
+ min_age_days: 7
41
+ # Post a sticky PR comment when an age-check fails, listing each
42
+ # pin with its eligible-after date and days remaining. The PR
43
+ # author / reviewer sees the retry-after date inline on the PR
44
+ # instead of having to click into the run log to find it. Sticky
45
+ # comment is updated in place on re-runs and deleted on a clean
46
+ # pass; soft-fails to a `::notice` if the token can't write.
47
+ comment_on_failure: true
48
+ permissions:
49
+ contents: read
50
+ # Required for `comment_on_failure: true` to actually post.
51
+ # Dependabot PRs default to read-only and need this grant
52
+ # explicitly. Without it, the workflow still fails the age check
53
+ # correctly — only the inline comment is suppressed.
54
+ pull-requests: write
@@ -0,0 +1,53 @@
1
+ # Dependency Age Check (pip / Python)
2
+ # Thin shim calling shared reusable workflow.
3
+ # Source: https://github.com/layervai/ops-routines/blob/main/.github/workflows/age-check-pip.yml
4
+ # Implementation: https://github.com/layervai/ops-routines/blob/main/lib/age-check-pip.sh
5
+ name: Dependency Age Check (pip)
6
+
7
+ # Fires on every PR (no path filter) so the status check always reports.
8
+ # This lets branch protection require it without the path-filtered-
9
+ # required-check footgun. The reusable's script exits 0 quickly when
10
+ # no requirements/poetry.lock/pyproject.toml changes are in the diff.
11
+ on:
12
+ pull_request:
13
+ workflow_dispatch:
14
+
15
+ # Cancel superseded runs on the same PR branch — pypi.org calls are
16
+ # rate-limited and we throttle ourselves; no reason to let two race.
17
+ concurrency:
18
+ group: dep-age-pip-${{ github.head_ref || github.ref_name }}
19
+ cancel-in-progress: true
20
+
21
+ permissions:
22
+ contents: read
23
+
24
+ jobs:
25
+ age-check:
26
+ # No outer `if:` for `age-check-bypass`. The required status check
27
+ # is `age-check / check-pip-age` (caller-job / reusable-inner-job).
28
+ # Skipping here means the reusable never runs and the inner job
29
+ # never reports → required check stuck at "Expected — Waiting"
30
+ # forever. The reusable's inner `if:` handles bypass and reports
31
+ # SKIPPED, which satisfies the required check.
32
+ # Note: `timeout-minutes` is intentionally NOT set here. Per GH
33
+ # docs (https://docs.github.com/en/actions/using-workflows/reusing-workflows#supported-keywords-for-jobs-that-call-a-reusable-workflow)
34
+ # only if/name/needs/permissions/secrets/strategy/uses/with/concurrency
35
+ # are valid on a job that calls a reusable workflow. The reusable
36
+ # workflow itself sets `timeout-minutes: 5` internally.
37
+ uses: layervai/ops-routines-workflows/.github/workflows/age-check-pip.yml@9b72a931d25f18a3a713006963072296a0b28134 # v0.8.0
38
+ with:
39
+ min_age_days: 7
40
+ # Post a sticky PR comment when an age-check fails, listing each
41
+ # pin with its eligible-after date and days remaining. The PR
42
+ # author / reviewer sees the retry-after date inline on the PR
43
+ # instead of having to click into the run log to find it. Sticky
44
+ # comment is updated in place on re-runs and deleted on a clean
45
+ # pass; soft-fails to a `::notice` if the token can't write.
46
+ comment_on_failure: true
47
+ permissions:
48
+ contents: read
49
+ # Required for `comment_on_failure: true` to actually post.
50
+ # Dependabot PRs default to read-only and need this grant
51
+ # explicitly. Without it, the workflow still fails the age check
52
+ # correctly — only the inline comment is suppressed.
53
+ pull-requests: write
@@ -0,0 +1,19 @@
1
+ name: Dependency Review
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ permissions:
8
+ contents: read
9
+ pull-requests: write
10
+
11
+ jobs:
12
+ review:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
16
+ - uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
17
+ with:
18
+ fail-on-severity: high
19
+ comment-summary-in-pr: always
@@ -0,0 +1,53 @@
1
+ # Issue Priority Enforcement
2
+ # Thin shim calling shared reusable workflow.
3
+ # Source: https://github.com/layervai/ops-routines-workflows/blob/main/.github/workflows/issue-priority.yml
4
+ #
5
+ # Matching form templates live in .github/ISSUE_TEMPLATE/ alongside this
6
+ # file — GitHub does not allow cross-repo issue-template inheritance.
7
+ name: Issue priority enforcement
8
+
9
+ on:
10
+ issues:
11
+ types: [opened, reopened, edited, labeled, unlabeled]
12
+
13
+ # Coalesce bursts on the same issue. Redundant with the reusable's own
14
+ # concurrency group (same key shape), but mirrors the dep-age-check
15
+ # shim convention so a future ref bump that accidentally drops the
16
+ # reusable's concurrency doesn't silently remove all deduplication.
17
+ #
18
+ # `cancel-in-progress: false` — serialize rather than cancel. The
19
+ # reusable uses `setLabels` (atomic PUT), so mid-flight cancellation
20
+ # is safe today, but a future reusable that swaps labels non-
21
+ # atomically (remove old → add new) would be vulnerable to a
22
+ # cancelled run leaving an issue with no priority label, which would
23
+ # then trip the enforcement fail path. Runs are bounded at 2 minutes;
24
+ # queueing is cheap compared to the silent-drop failure mode.
25
+ concurrency:
26
+ group: ${{ github.workflow }}-${{ github.event.issue.number }}
27
+ cancel-in-progress: false
28
+
29
+ permissions:
30
+ contents: read
31
+
32
+ jobs:
33
+ enforce-priority:
34
+ # Shim-level defense-in-depth against label-event recursion. The
35
+ # reusable applies priority labels, which emits `labeled` events
36
+ # that would re-trigger this workflow. GitHub's GITHUB_TOKEN-based
37
+ # identity suppression handles the common case, AND the reusable
38
+ # guards with `if: sender.type != 'Bot'`. This outer `if:` mirrors
39
+ # that guard at the caller so a future ref bump that silently
40
+ # drops the reusable's guard (or switches it to a PAT/App token,
41
+ # which bypasses GITHUB_TOKEN suppression) can't fully defeat
42
+ # loop prevention.
43
+ #
44
+ # Side effect: issues OPENED by `github-actions[bot]` are exempt
45
+ # from priority enforcement at creation time. Subsequent human
46
+ # `edited` / `labeled` events re-engage enforcement (not sticky).
47
+ # Other bots (dependabot, renovate, etc.) pass this guard but the
48
+ # reusable's own `sender.type != 'Bot'` check short-circuits them
49
+ # before setFailed — net effect is a near-instant no-op run.
50
+ if: ${{ github.actor != 'github-actions[bot]' }}
51
+ uses: layervai/ops-routines-workflows/.github/workflows/issue-priority.yml@9b72a931d25f18a3a713006963072296a0b28134 # v0.8.0
52
+ permissions:
53
+ issues: write
@@ -0,0 +1,40 @@
1
+ name: PR Title
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, edited, synchronize, reopened]
6
+
7
+ permissions:
8
+ pull-requests: read
9
+
10
+ jobs:
11
+ validate:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: amannn/action-semantic-pull-request@e32d7e603df1aa1ba07e981f2a23455dee596825 # v5.5.3
15
+ env:
16
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17
+ with:
18
+ types: |
19
+ feat
20
+ fix
21
+ docs
22
+ style
23
+ refactor
24
+ perf
25
+ test
26
+ build
27
+ ci
28
+ chore
29
+ revert
30
+ scopes: |
31
+ client
32
+ api
33
+ ci
34
+ deps
35
+ docs
36
+ requireScope: false
37
+ subjectPattern: ^[a-z].*$
38
+ subjectPatternError: |
39
+ Subject must start with a lowercase letter.
40
+ Example: "feat(client): add batch resolve helper"
@@ -0,0 +1,73 @@
1
+ name: Release Please
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+ inputs:
8
+ ref:
9
+ description: Git ref to build and publish
10
+ required: true
11
+ default: v0.2.0
12
+
13
+ permissions:
14
+ contents: write
15
+ pull-requests: write
16
+
17
+ jobs:
18
+ release-please:
19
+ if: github.event_name == 'push'
20
+ runs-on: ubuntu-latest
21
+ outputs:
22
+ release_created: ${{ steps.release.outputs.release_created }}
23
+ tag_name: ${{ steps.release.outputs.tag_name }}
24
+ steps:
25
+ - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
26
+ id: release
27
+ with:
28
+ config-file: release-please-config.json
29
+ manifest-file: .release-please-manifest.json
30
+
31
+ test:
32
+ needs: release-please
33
+ if: always() && (github.event_name == 'workflow_dispatch' || needs.release-please.outputs.release_created == 'true')
34
+ runs-on: ubuntu-latest
35
+ strategy:
36
+ fail-fast: true
37
+ matrix:
38
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
39
+ steps:
40
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
41
+ with:
42
+ ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.sha }}
43
+ - name: Set up Python ${{ matrix.python-version }}
44
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
45
+ with:
46
+ python-version: ${{ matrix.python-version }}
47
+ - name: Install dependencies
48
+ run: pip install -e ".[dev,langchain]"
49
+ - name: Test
50
+ run: pytest tests/ -v
51
+
52
+ publish:
53
+ needs: [release-please, test]
54
+ if: always() && needs.test.result == 'success' && (github.event_name == 'workflow_dispatch' || needs.release-please.outputs.release_created == 'true')
55
+ runs-on: ubuntu-latest
56
+ environment: pypi
57
+ permissions:
58
+ contents: read
59
+ id-token: write
60
+ steps:
61
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
62
+ with:
63
+ ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.sha }}
64
+ - name: Set up Python
65
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
66
+ with:
67
+ python-version: "3.12"
68
+ - name: Install build tools
69
+ run: pip install build
70
+ - name: Build
71
+ run: python -m build
72
+ - name: Publish to PyPI
73
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0