mt5cli 0.1.0__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.
- mt5cli-0.1.0/.agents/skills/local-qa/SKILL.md +25 -0
- mt5cli-0.1.0/.agents/skills/local-qa/scripts/qa.sh +19 -0
- mt5cli-0.1.0/.agents/skills/mt5cli/SKILL.md +104 -0
- mt5cli-0.1.0/.claude/agents/codex.md +46 -0
- mt5cli-0.1.0/.claude/settings.json +18 -0
- mt5cli-0.1.0/.github/FUNDING.yml +3 -0
- mt5cli-0.1.0/.github/dependabot.yml +17 -0
- mt5cli-0.1.0/.github/renovate.json +13 -0
- mt5cli-0.1.0/.github/workflows/ci.yml +91 -0
- mt5cli-0.1.0/.github/workflows/claude.yml +57 -0
- mt5cli-0.1.0/.github/workflows/release.yml +94 -0
- mt5cli-0.1.0/.gitignore +207 -0
- mt5cli-0.1.0/AGENTS.md +79 -0
- mt5cli-0.1.0/CLAUDE.md +1 -0
- mt5cli-0.1.0/LICENSE +21 -0
- mt5cli-0.1.0/PKG-INFO +109 -0
- mt5cli-0.1.0/README.md +85 -0
- mt5cli-0.1.0/docs/api/cli.md +3 -0
- mt5cli-0.1.0/docs/api/index.md +63 -0
- mt5cli-0.1.0/docs/index.md +117 -0
- mt5cli-0.1.0/mkdocs.yml +71 -0
- mt5cli-0.1.0/mt5cli/__init__.py +12 -0
- mt5cli-0.1.0/mt5cli/__main__.py +5 -0
- mt5cli-0.1.0/mt5cli/cli.py +752 -0
- mt5cli-0.1.0/pyproject.toml +186 -0
- mt5cli-0.1.0/tests/__init__.py +1 -0
- mt5cli-0.1.0/tests/test_cli.py +751 -0
- mt5cli-0.1.0/uv.lock +1161 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# local-qa
|
|
2
|
+
|
|
3
|
+
Run local QA checks (format, lint, test) on the repository.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
After making changes to repository files, run `scripts/qa.sh` to validate formatting, linting, and tests.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. Execute `scripts/qa.sh` and capture the results.
|
|
12
|
+
2. Report successes, failures, warnings, and any modified files.
|
|
13
|
+
|
|
14
|
+
## If tools are missing
|
|
15
|
+
|
|
16
|
+
Install them following this priority order:
|
|
17
|
+
|
|
18
|
+
1. Project package managers (`uv`, `poetry`, npm scripts)
|
|
19
|
+
2. System package managers (`brew`, `apt`)
|
|
20
|
+
3. Language-specific installers (`pipx`, `pip`, `npm`, `go install`)
|
|
21
|
+
|
|
22
|
+
## Constraints
|
|
23
|
+
|
|
24
|
+
- Only execute QA and tool-installation commands.
|
|
25
|
+
- If installation fails or requires unavailable privileges, report the attempt and exact failure, then stop.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euox pipefail
|
|
4
|
+
cd "$(git rev-parse --show-toplevel)"
|
|
5
|
+
|
|
6
|
+
# Python
|
|
7
|
+
uv run ruff format .
|
|
8
|
+
uv run ruff check --fix .
|
|
9
|
+
uv run pyright .
|
|
10
|
+
uv run pytest
|
|
11
|
+
|
|
12
|
+
# Markdown
|
|
13
|
+
npx -y prettier --write './**/*.md'
|
|
14
|
+
|
|
15
|
+
# GitHub Actions
|
|
16
|
+
zizmor --fix=safe .github/workflows
|
|
17
|
+
git ls-files -z -- '.github/workflows/*.yml' | xargs -0 -t actionlint
|
|
18
|
+
git ls-files -z -- '.github/workflows/*.yml' | xargs -0 -t yamllint -d '{"extends": "relaxed", "rules": {"line-length": "disable"}}'
|
|
19
|
+
checkov --framework=all --output=github_failed_only --directory=.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mt5cli
|
|
3
|
+
description: Use the `mt5cli` CLI to export MetaTrader 5 data (rates, ticks, account, symbols, orders, positions, history) to CSV, JSON, Parquet, or SQLite3. Invoke when the user asks to export, dump, download, or fetch MT5 market data or account data to a file.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# mt5cli
|
|
7
|
+
|
|
8
|
+
Export MetaTrader 5 data to CSV, JSON, Parquet, or SQLite3 via the `mt5cli`
|
|
9
|
+
command. Output format is auto-detected from the file extension (`.csv`,
|
|
10
|
+
`.json`, `.parquet`/`.pq`, `.db`/`.sqlite`/`.sqlite3`) or overridden with
|
|
11
|
+
`--format/-f`.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- Python 3.11+ on Windows with MetaTrader 5 installed (pdmt5 requires the
|
|
16
|
+
MT5 terminal).
|
|
17
|
+
- Install: `pip install -U mt5cli MetaTrader5`.
|
|
18
|
+
- In this repo, run via `uv run mt5cli ...` or `uv run python -m mt5cli ...`.
|
|
19
|
+
|
|
20
|
+
## Invocation shape
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
mt5cli [GLOBAL OPTIONS] -o OUTPUT COMMAND [COMMAND OPTIONS]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Global options MUST precede the subcommand.
|
|
27
|
+
|
|
28
|
+
### Global options (apply to every subcommand)
|
|
29
|
+
|
|
30
|
+
| Option | Purpose |
|
|
31
|
+
| --------------------- | ------------------------------------------------------------- |
|
|
32
|
+
| `-o, --output PATH` | Output file path (required). |
|
|
33
|
+
| `-f, --format FORMAT` | `csv`, `json`, `parquet`, or `sqlite3` (auto from extension). |
|
|
34
|
+
| `--table NAME` | Table name for SQLite3 output (default: `data`). |
|
|
35
|
+
| `--login INT` | MT5 trading account login. |
|
|
36
|
+
| `--password TEXT` | MT5 trading account password. |
|
|
37
|
+
| `--server TEXT` | MT5 trading server name. |
|
|
38
|
+
| `--path TEXT` | Path to MetaTrader 5 terminal EXE. |
|
|
39
|
+
| `--timeout INT` | Connection timeout in milliseconds. |
|
|
40
|
+
| `--log-level LEVEL` | `DEBUG`, `INFO`, `WARNING` (default), `ERROR`. |
|
|
41
|
+
|
|
42
|
+
### Parameter value formats
|
|
43
|
+
|
|
44
|
+
- **Datetimes** (`--date-from`, `--date-to`): ISO 8601 (`2024-01-01` or
|
|
45
|
+
`2024-01-01T12:00:00+00:00`). Naive values are treated as UTC.
|
|
46
|
+
- **Timeframe** (`--timeframe`): `M1`, `M2`, `M3`, `M4`, `M5`, `M6`, `M10`,
|
|
47
|
+
`M12`, `M15`, `M20`, `M30`, `H1`, `H2`, `H3`, `H4`, `H6`, `H8`, `H12`,
|
|
48
|
+
`D1`, `W1`, `MN1`, or the raw integer.
|
|
49
|
+
- **Tick flags** (`--flags`): `ALL`, `INFO`, `TRADE`, or the raw integer.
|
|
50
|
+
|
|
51
|
+
## Commands
|
|
52
|
+
|
|
53
|
+
| Command | Required options | Optional options |
|
|
54
|
+
| ---------------- | ----------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
55
|
+
| `rates-from` | `--symbol`, `--timeframe`, `--date-from`, `--count` | — |
|
|
56
|
+
| `rates-from-pos` | `--symbol`, `--timeframe`, `--start-pos`, `--count` | — |
|
|
57
|
+
| `rates-range` | `--symbol`, `--timeframe`, `--date-from`, `--date-to` | — |
|
|
58
|
+
| `ticks-from` | `--symbol`, `--date-from`, `--count`, `--flags` | — |
|
|
59
|
+
| `ticks-range` | `--symbol`, `--date-from`, `--date-to`, `--flags` | — |
|
|
60
|
+
| `account-info` | — | — |
|
|
61
|
+
| `terminal-info` | — | — |
|
|
62
|
+
| `symbols` | — | `--group` (e.g., `*USD*`) |
|
|
63
|
+
| `symbol-info` | `--symbol` | — |
|
|
64
|
+
| `orders` | — | `--symbol`, `--group`, `--ticket` |
|
|
65
|
+
| `positions` | — | `--symbol`, `--group`, `--ticket` |
|
|
66
|
+
| `history-orders` | — | `--date-from`, `--date-to`, `--group`, `--symbol`, `--ticket`, `--position` |
|
|
67
|
+
| `history-deals` | — | `--date-from`, `--date-to`, `--group`, `--symbol`, `--ticket`, `--position` |
|
|
68
|
+
|
|
69
|
+
## Examples
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Account snapshot as CSV.
|
|
73
|
+
mt5cli -o account.csv account-info
|
|
74
|
+
|
|
75
|
+
# EURUSD M1 bars (1000 rows) from a start date to Parquet.
|
|
76
|
+
mt5cli -o rates.parquet rates-from \
|
|
77
|
+
--symbol EURUSD --timeframe M1 --date-from 2024-01-01 --count 1000
|
|
78
|
+
|
|
79
|
+
# EURUSD tick stream for a date range to JSON.
|
|
80
|
+
mt5cli -o ticks.json ticks-range \
|
|
81
|
+
--symbol EURUSD --date-from 2024-01-01 --date-to 2024-01-02 --flags ALL
|
|
82
|
+
|
|
83
|
+
# USD symbols into a named table in SQLite3.
|
|
84
|
+
mt5cli -o data.db --table symbols symbols --group "*USD*"
|
|
85
|
+
|
|
86
|
+
# Historical deals filtered by symbol (using an already-logged-in MT5 terminal).
|
|
87
|
+
mt5cli -o deals.csv history-deals --symbol EURUSD --date-from 2024-01-01
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Guidelines
|
|
91
|
+
|
|
92
|
+
- Pick the output extension to avoid passing `--format`.
|
|
93
|
+
- Use `--table` only with SQLite3 outputs; it is otherwise ignored.
|
|
94
|
+
- `--count` is required for `rates-from`, `rates-from-pos`, and `ticks-from`.
|
|
95
|
+
Prefer `rates-range` / `ticks-range` when a fixed window is known.
|
|
96
|
+
- Credentials (`--login`, `--password`, `--server`) are optional when the
|
|
97
|
+
local MT5 terminal is already logged in.
|
|
98
|
+
- Avoid passing `--password` on the command line in shared or logged
|
|
99
|
+
environments — it is visible in `ps`, shell history, and CI logs. Prefer
|
|
100
|
+
logging in through the MT5 terminal first, then omit credentials here.
|
|
101
|
+
- Reach for `--log-level DEBUG` when a command fails silently — MT5
|
|
102
|
+
connection errors surface there.
|
|
103
|
+
- If the user asks to run from source in this repo, prefix with `uv run`
|
|
104
|
+
(e.g., `uv run mt5cli -o out.csv account-info`).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Codex Agent
|
|
2
|
+
|
|
3
|
+
Specialized Claude agent for autonomous development work using OpenAI's Codex CLI.
|
|
4
|
+
|
|
5
|
+
## Modes
|
|
6
|
+
|
|
7
|
+
### Ask Mode
|
|
8
|
+
|
|
9
|
+
Read-only code analysis: answer questions about implementation, architecture, and debugging with specific file references and code examples.
|
|
10
|
+
|
|
11
|
+
### Exec Mode
|
|
12
|
+
|
|
13
|
+
Generate and modify code: create new components, refactor existing code, fix bugs, and write tests while maintaining quality standards.
|
|
14
|
+
|
|
15
|
+
### Review Mode
|
|
16
|
+
|
|
17
|
+
Comprehensive code review: identify security vulnerabilities, bugs, performance issues, and quality improvements without making changes.
|
|
18
|
+
|
|
19
|
+
### Search Mode
|
|
20
|
+
|
|
21
|
+
Research current documentation, best practices, solutions, and technology comparisons using web resources.
|
|
22
|
+
|
|
23
|
+
## Core Requirements
|
|
24
|
+
|
|
25
|
+
- Prioritize Codex CLI as the primary execution engine.
|
|
26
|
+
- Ask, Review, and Search modes are read-only; only Exec mode modifies code.
|
|
27
|
+
- All answers require verification:
|
|
28
|
+
- Ask mode must confirm file paths exist.
|
|
29
|
+
- Exec mode requires test passage and linting.
|
|
30
|
+
- Review mode needs severity prioritization.
|
|
31
|
+
- Search mode demands sourced citations.
|
|
32
|
+
|
|
33
|
+
## Workflow
|
|
34
|
+
|
|
35
|
+
1. Understand the task.
|
|
36
|
+
2. Gather context from the codebase.
|
|
37
|
+
3. Execute via Codex CLI with specific parameters.
|
|
38
|
+
4. Verify results.
|
|
39
|
+
5. Communicate findings with appropriate structure and detail.
|
|
40
|
+
|
|
41
|
+
## Constraints
|
|
42
|
+
|
|
43
|
+
- No hardcoded secrets.
|
|
44
|
+
- Thorough testing.
|
|
45
|
+
- Specific file references.
|
|
46
|
+
- Honest communication about limitations.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"Stop": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": ".claude/skills/local-qa/scripts/qa.sh"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"enabledPlugins": {
|
|
16
|
+
"code-simplifier@claude-plugins-official": true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 2
|
|
3
|
+
updates:
|
|
4
|
+
- package-ecosystem: github-actions
|
|
5
|
+
directory: /
|
|
6
|
+
schedule:
|
|
7
|
+
interval: daily
|
|
8
|
+
cooldown:
|
|
9
|
+
default-days: 7
|
|
10
|
+
open-pull-requests-limit: 10
|
|
11
|
+
- package-ecosystem: pip
|
|
12
|
+
directory: /
|
|
13
|
+
schedule:
|
|
14
|
+
interval: daily
|
|
15
|
+
cooldown:
|
|
16
|
+
default-days: 7
|
|
17
|
+
open-pull-requests-limit: 10
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
+
"extends": ["config:recommended"],
|
|
4
|
+
"minimumReleaseAge": "7 days",
|
|
5
|
+
"packageRules": [
|
|
6
|
+
{
|
|
7
|
+
"description": "Automatically merge minor and patch-level updates",
|
|
8
|
+
"matchUpdateTypes": ["minor", "patch", "digest"],
|
|
9
|
+
"automerge": true,
|
|
10
|
+
"automergeType": "branch"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: CI/CD
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
types:
|
|
11
|
+
- opened
|
|
12
|
+
- synchronize
|
|
13
|
+
- reopened
|
|
14
|
+
workflow_dispatch: # checkov:skip=CKV_GHA_7:workflow_dispatch inputs are required for manual runs
|
|
15
|
+
inputs:
|
|
16
|
+
workflow:
|
|
17
|
+
required: true
|
|
18
|
+
type: choice
|
|
19
|
+
options:
|
|
20
|
+
- lint-and-test
|
|
21
|
+
- docs-deploy
|
|
22
|
+
description: Choose the workflow to run
|
|
23
|
+
default: lint-and-test
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
defaults:
|
|
27
|
+
run:
|
|
28
|
+
shell: bash -euo pipefail {0}
|
|
29
|
+
working-directory: .
|
|
30
|
+
jobs:
|
|
31
|
+
python-lint-and-scan:
|
|
32
|
+
if: >
|
|
33
|
+
github.event_name == 'push'
|
|
34
|
+
|| github.event_name == 'pull_request'
|
|
35
|
+
|| (github.event_name == 'workflow_dispatch' && inputs.workflow == 'lint-and-test')
|
|
36
|
+
permissions:
|
|
37
|
+
contents: read
|
|
38
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-lint-and-scan.yml@main # zizmor: ignore[unpinned-uses]
|
|
39
|
+
with:
|
|
40
|
+
package-path: .
|
|
41
|
+
runs-on: windows-latest
|
|
42
|
+
python-test:
|
|
43
|
+
if: >
|
|
44
|
+
github.event_name == 'push'
|
|
45
|
+
|| github.event_name == 'pull_request'
|
|
46
|
+
|| (github.event_name == 'workflow_dispatch' && inputs.workflow == 'lint-and-test')
|
|
47
|
+
permissions:
|
|
48
|
+
contents: read
|
|
49
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-test.yml@main # zizmor: ignore[unpinned-uses]
|
|
50
|
+
with:
|
|
51
|
+
package-path: .
|
|
52
|
+
runs-on: windows-latest
|
|
53
|
+
python-docs-deploy:
|
|
54
|
+
if: >
|
|
55
|
+
github.event_name == 'push'
|
|
56
|
+
|| (github.event_name == 'workflow_dispatch' && inputs.workflow == 'docs-deploy')
|
|
57
|
+
permissions:
|
|
58
|
+
contents: write
|
|
59
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-mkdocs-gh-deploy.yml@main # zizmor: ignore[unpinned-uses]
|
|
60
|
+
with:
|
|
61
|
+
package-path: .
|
|
62
|
+
mkdocs-theme: material
|
|
63
|
+
runs-on: ubuntu-slim
|
|
64
|
+
secrets:
|
|
65
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
66
|
+
python-package-release:
|
|
67
|
+
if: >
|
|
68
|
+
github.event_name == 'push'
|
|
69
|
+
|| (github.event_name == 'workflow_dispatch' && inputs.workflow == 'lint-and-test')
|
|
70
|
+
permissions:
|
|
71
|
+
contents: write
|
|
72
|
+
id-token: write
|
|
73
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-release-on-pypi-and-github.yml@main # zizmor: ignore[unpinned-uses]
|
|
74
|
+
with:
|
|
75
|
+
package-path: .
|
|
76
|
+
create-releases: false
|
|
77
|
+
secrets:
|
|
78
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
79
|
+
dependabot-auto-merge:
|
|
80
|
+
if: >
|
|
81
|
+
github.event_name == 'pull_request' && github.actor == 'dependabot[bot]'
|
|
82
|
+
needs:
|
|
83
|
+
- python-lint-and-scan
|
|
84
|
+
- python-test
|
|
85
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/dependabot-auto-merge.yml@main # zizmor: ignore[unpinned-uses]
|
|
86
|
+
permissions:
|
|
87
|
+
contents: write
|
|
88
|
+
pull-requests: write
|
|
89
|
+
actions: read
|
|
90
|
+
with:
|
|
91
|
+
unconditional: true
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Claude Code review and mention bot
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
types:
|
|
8
|
+
- opened
|
|
9
|
+
- ready_for_review
|
|
10
|
+
issue_comment:
|
|
11
|
+
types:
|
|
12
|
+
- created
|
|
13
|
+
pull_request_review_comment:
|
|
14
|
+
types:
|
|
15
|
+
- created
|
|
16
|
+
issues:
|
|
17
|
+
types:
|
|
18
|
+
- opened
|
|
19
|
+
- assigned
|
|
20
|
+
pull_request_review:
|
|
21
|
+
types:
|
|
22
|
+
- submitted
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
jobs:
|
|
26
|
+
claude-code-review:
|
|
27
|
+
if: >
|
|
28
|
+
github.event_name == 'pull_request'
|
|
29
|
+
&& (! github.event.pull_request.draft)
|
|
30
|
+
&& (! startsWith(github.head_ref, 'dependabot/'))
|
|
31
|
+
&& (! startsWith(github.head_ref, 'renovate/'))
|
|
32
|
+
permissions:
|
|
33
|
+
contents: read
|
|
34
|
+
pull-requests: write
|
|
35
|
+
issues: write
|
|
36
|
+
id-token: write
|
|
37
|
+
actions: read
|
|
38
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/claude-code-review.yml@main # zizmor: ignore[unpinned-uses]
|
|
39
|
+
secrets:
|
|
40
|
+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} # zizmor: ignore[secrets-outside-env]
|
|
41
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
42
|
+
claude-code-bot:
|
|
43
|
+
if: >
|
|
44
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude'))
|
|
45
|
+
|| (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude'))
|
|
46
|
+
|| (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude'))
|
|
47
|
+
|| (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
48
|
+
permissions:
|
|
49
|
+
contents: read
|
|
50
|
+
pull-requests: write
|
|
51
|
+
issues: write
|
|
52
|
+
id-token: write
|
|
53
|
+
actions: read
|
|
54
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/claude-code-bot.yml@main # zizmor: ignore[unpinned-uses]
|
|
55
|
+
secrets:
|
|
56
|
+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} # zizmor: ignore[secrets-outside-env]
|
|
57
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Release
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
defaults:
|
|
8
|
+
run:
|
|
9
|
+
shell: bash -euo pipefail {0}
|
|
10
|
+
working-directory: .
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write
|
|
15
|
+
id-token: write
|
|
16
|
+
uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-release-on-pypi-and-github.yml@main # zizmor: ignore[unpinned-uses]
|
|
17
|
+
with:
|
|
18
|
+
package-path: .
|
|
19
|
+
create-releases: false
|
|
20
|
+
secrets:
|
|
21
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
+
github-release:
|
|
23
|
+
name: Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release
|
|
24
|
+
if: >
|
|
25
|
+
startsWith(github.ref, 'refs/tags/')
|
|
26
|
+
needs:
|
|
27
|
+
- build
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
permissions:
|
|
30
|
+
contents: write # IMPORTANT: mandatory for making GitHub Releases
|
|
31
|
+
id-token: write # IMPORTANT: mandatory for sigstore
|
|
32
|
+
steps:
|
|
33
|
+
- name: Download all the dists
|
|
34
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
35
|
+
with:
|
|
36
|
+
name: ${{ needs.build.outputs.distribution-artifact-name }}
|
|
37
|
+
path: dist/
|
|
38
|
+
- name: Validate the version-tag consistency
|
|
39
|
+
env:
|
|
40
|
+
TAG_NAME: ${{ github.ref_name }}
|
|
41
|
+
NEEDS_BUILD_OUTPUTS_PROJECT_NAME: ${{ needs.build.outputs.project-name }}
|
|
42
|
+
run: |
|
|
43
|
+
v="$( \
|
|
44
|
+
find dist -type f -name "${NEEDS_BUILD_OUTPUTS_PROJECT_NAME}-*" -exec basename {} \; \
|
|
45
|
+
| head -n 1 \
|
|
46
|
+
| cut -d '-' -f 2 \
|
|
47
|
+
)"
|
|
48
|
+
v="${v%.tar.gz}"
|
|
49
|
+
if [[ "${TAG_NAME}" != "${v}" ]] && [[ "${TAG_NAME}" != "v${v}" ]]; then
|
|
50
|
+
echo "The tag (${TAG_NAME}) is inconsistent with the version (${v})." && exit 1
|
|
51
|
+
fi
|
|
52
|
+
- name: Sign the dists with Sigstore
|
|
53
|
+
uses: sigstore/gh-action-sigstore-python@04cffa1d795717b140764e8b640de88853c92acc # v3.3.0
|
|
54
|
+
with:
|
|
55
|
+
inputs: >-
|
|
56
|
+
./dist/*.whl
|
|
57
|
+
- name: Create GitHub Release
|
|
58
|
+
env:
|
|
59
|
+
REPOSITORY: ${{ github.repository }}
|
|
60
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} # zizmor: ignore[secrets-outside-env] caller-provided secret
|
|
61
|
+
run: |
|
|
62
|
+
gh release create "${GITHUB_REF_NAME}" --repo "${REPOSITORY}" --generate-notes --verify-tag
|
|
63
|
+
- name: Upload artifact signatures to GitHub Release
|
|
64
|
+
env:
|
|
65
|
+
REPOSITORY: ${{ github.repository }}
|
|
66
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} # zizmor: ignore[secrets-outside-env] caller-provided secret
|
|
67
|
+
# Upload to GitHub Release using the `gh` CLI.
|
|
68
|
+
# `dist/` contains the built packages, and the
|
|
69
|
+
# sigstore-produced signatures and certificates.
|
|
70
|
+
run: |
|
|
71
|
+
gh release upload "${GITHUB_REF_NAME}" dist/** --repo "${REPOSITORY}"
|
|
72
|
+
publish-to-pypi:
|
|
73
|
+
name: Publish the Python 🐍 distribution 📦 to PyPI
|
|
74
|
+
if: >
|
|
75
|
+
startsWith(github.ref, 'refs/tags/')
|
|
76
|
+
needs:
|
|
77
|
+
- build
|
|
78
|
+
- github-release
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
environment:
|
|
81
|
+
name: pypi
|
|
82
|
+
url: https://pypi.org/p/${{ needs.build.outputs.project-name }}
|
|
83
|
+
permissions:
|
|
84
|
+
id-token: write # IMPORTANT: mandatory for trusted publishing
|
|
85
|
+
steps:
|
|
86
|
+
- name: Download all the dists
|
|
87
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
88
|
+
with:
|
|
89
|
+
name: ${{ needs.build.outputs.distribution-artifact-name }}
|
|
90
|
+
path: dist/
|
|
91
|
+
- name: Publish distribution 📦 to PyPI
|
|
92
|
+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
|
93
|
+
with:
|
|
94
|
+
verbose: true
|