insightfactory-cli 1.1.0.dev22__tar.gz → 1.1.1.dev25__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.
- insightfactory_cli-1.1.1.dev25/.github/workflows/release.yml +94 -0
- insightfactory_cli-1.1.1.dev25/CHANGELOG.md +125 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/CLAUDE.md +6 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/PKG-INFO +31 -2
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/README.md +30 -1
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/pyproject.toml +6 -1
- insightfactory_cli-1.1.1.dev25/tests/test_release_tools.py +490 -0
- insightfactory_cli-1.1.1.dev25/tools/check_release.py +79 -0
- insightfactory_cli-1.1.1.dev25/tools/release_notes.py +280 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/uv.lock +1 -1
- insightfactory_cli-1.1.0.dev22/.github/workflows/release.yml +0 -45
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/.github/workflows/ci.yml +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/.github/workflows/claude.yml +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/.gitignore +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/.python-version +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/AGENTS.md +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/LICENSE +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/__init__.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/__main__.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/assets/__init__.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/assets/insightfactoryai-logo.svg +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/cache.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/callback_page.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/cli.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/colour.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/__init__.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/api.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/config.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/login.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/logout.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/mcp.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/profiles.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/set_token.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/commands/token.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/config.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/constants.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/http.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/main.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/oauth.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/router/__init__.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/router/catalog.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/router/log.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/router/policy.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/router/server.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/router/upstream.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/src/if_cli/runtime.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/__init__.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/cache_writer.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/conftest.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/helpers.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/servers.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_api.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_api_command.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_cache.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_cli.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_config.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_config_command.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_login.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_mcp_command.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_oauth.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_oauth_flow.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_oauth_force_refresh.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_profiles.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_programmatic_api.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_router_catalog.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_router_policy.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_router_server.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_router_upstream.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_runtime.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_set_token.py +0 -0
- {insightfactory_cli-1.1.0.dev22 → insightfactory_cli-1.1.1.dev25}/tests/test_token.py +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# CD: a push to develop publishes a `.dev<run_number>` pre-release; a `v*` tag
|
|
4
|
+
# creates the GitHub Release and publishes it to PyPI. A merge to main runs CI and
|
|
5
|
+
# publishes nothing -- see if_s_insightfactory_cli.yml for why releasing is a
|
|
6
|
+
# deliberate tag push.
|
|
7
|
+
# Verify + build live in insightfactory-ai/if_sre_github_actions
|
|
8
|
+
# (if_s_insightfactory_cli.yml). The publish job stays here because PyPI
|
|
9
|
+
# Trusted Publishing is registered for this repository, workflow `release.yml`,
|
|
10
|
+
# and environment `pypi` — a reusable workflow cannot be registered.
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
branches: [develop, main]
|
|
14
|
+
tags:
|
|
15
|
+
- "v*"
|
|
16
|
+
|
|
17
|
+
concurrency:
|
|
18
|
+
group: release-${{ github.ref }}
|
|
19
|
+
cancel-in-progress: false
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
ci:
|
|
26
|
+
uses: insightfactory-ai/if_sre_github_actions/.github/workflows/if_s_insightfactory_cli.yml@main
|
|
27
|
+
secrets: inherit
|
|
28
|
+
permissions:
|
|
29
|
+
# The central workflow's release job creates the GitHub Release for the pushed
|
|
30
|
+
# tag, which needs `contents: write`. A called workflow may only reduce the
|
|
31
|
+
# caller's grant, never raise it, so the grant has to be made here. ci.yml
|
|
32
|
+
# stays read-only: its release job is push-gated and simply never runs.
|
|
33
|
+
contents: write
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
name: Publish to PyPI
|
|
37
|
+
needs: ci
|
|
38
|
+
if: needs.ci.outputs.should_publish == 'true'
|
|
39
|
+
runs-on: ${{ vars.RUN_LINUX }}
|
|
40
|
+
timeout-minutes: 10
|
|
41
|
+
environment:
|
|
42
|
+
name: pypi
|
|
43
|
+
url: https://pypi.org/p/insightfactory-cli
|
|
44
|
+
permissions:
|
|
45
|
+
id-token: write
|
|
46
|
+
# Publishing the draft Release the central workflow created. A job-level
|
|
47
|
+
# block replaces the set rather than adding to it, so id-token has to be
|
|
48
|
+
# repeated here.
|
|
49
|
+
contents: write
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/download-artifact@v6
|
|
52
|
+
with:
|
|
53
|
+
name: dist-release
|
|
54
|
+
path: dist/
|
|
55
|
+
|
|
56
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
57
|
+
|
|
58
|
+
# Only now, with the files actually on PyPI, does the Release stop being a
|
|
59
|
+
# draft: its body tells people to `pip install insightfactory-cli==X` and
|
|
60
|
+
# links the PyPI page, so publishing it any earlier would show instructions
|
|
61
|
+
# that 404, and leave them showing if this upload failed.
|
|
62
|
+
#
|
|
63
|
+
# Two details, both because this step runs after a successful upload and so
|
|
64
|
+
# must not be the thing that breaks:
|
|
65
|
+
#
|
|
66
|
+
# TAG is github.ref_name, not an output of the called workflow. On a tag
|
|
67
|
+
# push it is the tag, locally and unconditionally, and cannot drift if that
|
|
68
|
+
# workflow is edited.
|
|
69
|
+
#
|
|
70
|
+
# `make_latest: legacy` asks GitHub to pick Latest by version and date.
|
|
71
|
+
# `gh release edit --latest` marks this release Latest outright, and the
|
|
72
|
+
# concurrency group above is per-ref, so two tags can be in flight at once
|
|
73
|
+
# and an older one finishing last would take the badge from the newer
|
|
74
|
+
# release. The flag cannot express legacy, hence the raw API call.
|
|
75
|
+
- name: Publish the draft GitHub Release
|
|
76
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
77
|
+
env:
|
|
78
|
+
GH_TOKEN: ${{ github.token }}
|
|
79
|
+
GH_REPO: ${{ github.repository }}
|
|
80
|
+
TAG: ${{ github.ref_name }}
|
|
81
|
+
run: |
|
|
82
|
+
set -euo pipefail
|
|
83
|
+
# The list endpoint, because get-by-tag does not return drafts. One page:
|
|
84
|
+
# a release created moments ago is among the newest.
|
|
85
|
+
id=$(gh api "repos/${GH_REPO}/releases?per_page=100" \
|
|
86
|
+
--jq 'map(select(.tag_name == env.TAG)) | first | .id')
|
|
87
|
+
if [ -z "$id" ] || [ "$id" = "null" ]; then
|
|
88
|
+
echo "::error::${TAG} is on PyPI but has no GitHub Release to publish. Re-run the release job for this tag."
|
|
89
|
+
exit 1
|
|
90
|
+
fi
|
|
91
|
+
gh api -X PATCH "repos/${GH_REPO}/releases/${id}" \
|
|
92
|
+
-F draft=false \
|
|
93
|
+
-f make_latest=legacy \
|
|
94
|
+
--jq '.html_url'
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `insightfactory-cli` are recorded here.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
|
6
|
+
project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
The release job reads the section whose heading matches the version in
|
|
9
|
+
`pyproject.toml` and makes it the body of the GitHub Release. CI holds both ends of
|
|
10
|
+
that: a PR into `develop` or `main` must raise the version and add its section here,
|
|
11
|
+
and a tag whose version has no section fails rather than releasing an empty page.
|
|
12
|
+
|
|
13
|
+
## 1.1.1
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- This changelog, and `tools/release_notes.py`, which renders a version's section
|
|
18
|
+
plus install instructions as the GitHub Release body.
|
|
19
|
+
- A `release-guard` CI job. A PR into `develop` or `main` that does not raise the
|
|
20
|
+
version in `pyproject.toml` and document it here now fails, instead of landing
|
|
21
|
+
under a section written for someone else's work.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Pushing a `v*` tag now creates the GitHub Release with the wheel and sdist
|
|
26
|
+
attached, instead of stopping at PyPI and leaving the Release to be made by hand.
|
|
27
|
+
The Release is drafted first and published once PyPI has the files, so its
|
|
28
|
+
install instructions never point at a version that is not there yet.
|
|
29
|
+
|
|
30
|
+
## 1.1.0
|
|
31
|
+
|
|
32
|
+
First release since 1.0.2. Two features: an MCP server that fronts several factory
|
|
33
|
+
environments at once, and a login callback page that looks like the rest of the login.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- **`if-cli mcp`.** One MCP server over stdio, fronting several factory environments
|
|
38
|
+
as a single tool catalogue rather than one connection per environment. Every tool
|
|
39
|
+
takes a required `environment` argument, and each call goes to that environment's
|
|
40
|
+
own `/mcp` with that environment's profile. A profile's bearer token never reaches
|
|
41
|
+
another environment's host. Needs the `mcp` extra; the base install stays
|
|
42
|
+
dependency-free.
|
|
43
|
+
- Named factory sections in `~/.insightfactory/config`, which is where the router
|
|
44
|
+
reads its environments and its `writable` list. Writes are allowed only on the
|
|
45
|
+
environments named there. Everywhere else the router allows an allowlist of tools
|
|
46
|
+
known to read, so a tool it has not heard of is refused rather than assumed safe.
|
|
47
|
+
- A tool is published only on the environments whose input schema matches the
|
|
48
|
+
catalogue's, so a factory on an older release is never handed argument shapes it
|
|
49
|
+
does not accept.
|
|
50
|
+
- Databricks connect prompts. A tool that runs under your personal Databricks
|
|
51
|
+
identity used to fail with a refusal naming no page. The router now names the page
|
|
52
|
+
to visit, taken from the factory rather than a hardcoded route, and only when that
|
|
53
|
+
page is on the environment's own origin. The prompt never goes to the model:
|
|
54
|
+
linking a Databricks identity should be a deliberate trip to a page, not a link
|
|
55
|
+
offered mid tool call.
|
|
56
|
+
- `--read-only`, and a `--timeout` whose scope is documented.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
|
|
60
|
+
- The loopback callback page after `if-cli login` is themed to match Auth0 Universal
|
|
61
|
+
Login, replacing the bare HTML it used to show.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- A force-refreshed token no longer re-serves the token that was just rejected. The
|
|
66
|
+
refresh ran, the cached access token came back unchanged, and the 401 repeated.
|
|
67
|
+
- The router no longer blocks `initialize` on building its catalogue. It retries a
|
|
68
|
+
failed build, revalidates environments once they become reachable, and no longer
|
|
69
|
+
waits on an in-flight build at shutdown, so one slow factory cannot hold up the
|
|
70
|
+
handshake.
|
|
71
|
+
- `tools/list` pagination is followed, so a factory with more than one page of tools
|
|
72
|
+
publishes all of them.
|
|
73
|
+
- An unsupported repeat option dies loudly instead of being ignored.
|
|
74
|
+
|
|
75
|
+
## 1.0.2
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
|
|
79
|
+
- `timeout` can be raised per invocation on the programmatic API, for a call that is
|
|
80
|
+
expected to run long.
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- The timeout override no longer reaches the OAuth transport, where a long timeout
|
|
85
|
+
would have applied to token calls that should stay short.
|
|
86
|
+
- A misplaced HTTP method is named as such instead of the error blaming the path,
|
|
87
|
+
and the correction keeps the target you supplied.
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
|
|
91
|
+
- The package carries a proprietary licence and ships `LICENSE` in the wheel.
|
|
92
|
+
|
|
93
|
+
## 1.0.1
|
|
94
|
+
|
|
95
|
+
### Fixed
|
|
96
|
+
|
|
97
|
+
- Attached short-option values (`-ovalue`) and inline boolean values parse correctly.
|
|
98
|
+
- Positional argument order for the `api` and `config` commands.
|
|
99
|
+
- Exit status is preserved when stdout closes on Python 3.14.
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
|
|
103
|
+
- The Claude review workflow no longer caps its own permissions, which had stopped it
|
|
104
|
+
starting at all.
|
|
105
|
+
|
|
106
|
+
## 1.0.0
|
|
107
|
+
|
|
108
|
+
First production release of the Python `if-cli`, the successor to the Node
|
|
109
|
+
`@insightfactory-ai/if-cli`.
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- `login`, `logout`, `profiles`, `token`, `set-token`, `config` and `api`, for
|
|
114
|
+
per-environment OAuth login and calling the Interfaces API from the command line.
|
|
115
|
+
OAuth is authorization-code with PKCE against a loopback-only callback; the CLI is
|
|
116
|
+
a public client with no secret.
|
|
117
|
+
- Runtime code is stdlib-only, so the base install pulls in nothing.
|
|
118
|
+
- On-disk profile and token-cache paths, JSON shapes and file permissions stay
|
|
119
|
+
byte-compatible with the Node CLI, so you can switch implementations without
|
|
120
|
+
logging in again.
|
|
121
|
+
- A supported in-process API: `if_cli.config.load_config`,
|
|
122
|
+
`if_cli.config.get_profile`, `if_cli.oauth.get_valid_token` and
|
|
123
|
+
`if_cli.runtime.CliError`. These raise `CliError` rather than exiting, never write
|
|
124
|
+
to stdout, and never block on a browser or on input. Changing any of them requires
|
|
125
|
+
a major version bump.
|
|
@@ -34,3 +34,9 @@ uv run ty check
|
|
|
34
34
|
match `pyproject.toml`. Pushing `develop` publishes a `.dev{run_number}`
|
|
35
35
|
pre-release. Creating the release tag is a deliberate human act — do not create
|
|
36
36
|
or push one unless asked to cut a release.
|
|
37
|
+
- **Every PR into `develop` or `main` raises `version` in `pyproject.toml` and
|
|
38
|
+
documents that version in `CHANGELOG.md`.** The `release-guard` job runs
|
|
39
|
+
`tools/check_release.py` and fails the PR otherwise. Put user-visible changes in
|
|
40
|
+
the Added/Changed/Fixed group that fits; for internal-only work (tests, CI, a
|
|
41
|
+
refactor nothing observes) a one-line entry saying so is enough. The section
|
|
42
|
+
becomes the body of that version's GitHub Release.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: insightfactory-cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.1.dev25
|
|
4
4
|
Summary: Profile-based authentication CLI for the InsightFactory Interfaces API
|
|
5
5
|
Project-URL: Homepage, https://insightfactory.ai
|
|
6
6
|
Author-email: "insightfactory.ai Support" <support@insightfactory.ai>
|
|
@@ -340,6 +340,35 @@ and publishes nothing.
|
|
|
340
340
|
git tag v1.0.1 && git push origin v1.0.1
|
|
341
341
|
```
|
|
342
342
|
|
|
343
|
+
The tag drafts the GitHub Release, uploads to PyPI, then publishes the Release.
|
|
344
|
+
Everything comes from one build, so the wheel and sdist attached to the Release
|
|
345
|
+
are the files that went to PyPI, and the draft means nobody sees `pip install
|
|
346
|
+
insightfactory-cli==1.1.1` on a Release page before that version exists on PyPI.
|
|
347
|
+
A failed upload leaves a draft rather than a published page pointing at a 404.
|
|
348
|
+
|
|
349
|
+
The body comes from [`CHANGELOG.md`](CHANGELOG.md) via `tools/release_notes.py`.
|
|
350
|
+
It covers the tagged version and any version opened since the last tag, because
|
|
351
|
+
one version per PR means unreleased versions pile up between tags: if 1.1.1 and
|
|
352
|
+
1.1.2 both merge and only `v1.1.2` is tagged, 1.1.1's code ships inside that
|
|
353
|
+
artifact, so its notes belong on that Release. A checkout with no tags falls back
|
|
354
|
+
to the tagged version's section alone.
|
|
355
|
+
|
|
356
|
+
`develop` therefore carries the version the next release will use, and the
|
|
357
|
+
`release-guard` job holds it there. A PR into `develop` must raise `version` in
|
|
358
|
+
`pyproject.toml` above what `develop` already has, and must add that version's
|
|
359
|
+
`CHANGELOG.md` section. `tools/check_release.py` runs both checks and is what
|
|
360
|
+
fails the PR:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
BASE=origin/develop python3 tools/check_release.py
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
One version per PR, then. The instinct is to let a second change join the
|
|
367
|
+
section the first one opened, and the guard refuses that: the version would be
|
|
368
|
+
tagged with notes that do not describe everything in it, and nothing stops the
|
|
369
|
+
tag going out between the two merges. Bump the patch number again, or fold the
|
|
370
|
+
second change into the first PR.
|
|
371
|
+
|
|
343
372
|
Verify and build live in the reusable workflow
|
|
344
373
|
[`if_s_insightfactory_cli.yml`](https://github.com/insightfactory-ai/if_sre_github_actions/blob/main/.github/workflows/if_s_insightfactory_cli.yml)
|
|
345
374
|
in `insightfactory-ai/if_sre_github_actions`. This repository's
|
|
@@ -354,7 +383,7 @@ reusable workflow and uploads it with `pypa/gh-action-pypi-publish`.
|
|
|
354
383
|
| Trigger | Published version | PyPI role |
|
|
355
384
|
|---|---|---|
|
|
356
385
|
| Push / merge to `develop` | `1.0.1.dev{N}` | pre-release (`pip install --pre`) |
|
|
357
|
-
| Push of a `v*` tag | the version in `pyproject.toml`, which the tag must match | latest |
|
|
386
|
+
| Push of a `v*` tag | the version in `pyproject.toml`, which the tag must match | latest, plus a GitHub Release |
|
|
358
387
|
| Merge to `main` | nothing, CI only | none |
|
|
359
388
|
|
|
360
389
|
`N` is `github.run_number` of the reusable workflow. It is a per-workflow
|
|
@@ -316,6 +316,35 @@ and publishes nothing.
|
|
|
316
316
|
git tag v1.0.1 && git push origin v1.0.1
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
+
The tag drafts the GitHub Release, uploads to PyPI, then publishes the Release.
|
|
320
|
+
Everything comes from one build, so the wheel and sdist attached to the Release
|
|
321
|
+
are the files that went to PyPI, and the draft means nobody sees `pip install
|
|
322
|
+
insightfactory-cli==1.1.1` on a Release page before that version exists on PyPI.
|
|
323
|
+
A failed upload leaves a draft rather than a published page pointing at a 404.
|
|
324
|
+
|
|
325
|
+
The body comes from [`CHANGELOG.md`](CHANGELOG.md) via `tools/release_notes.py`.
|
|
326
|
+
It covers the tagged version and any version opened since the last tag, because
|
|
327
|
+
one version per PR means unreleased versions pile up between tags: if 1.1.1 and
|
|
328
|
+
1.1.2 both merge and only `v1.1.2` is tagged, 1.1.1's code ships inside that
|
|
329
|
+
artifact, so its notes belong on that Release. A checkout with no tags falls back
|
|
330
|
+
to the tagged version's section alone.
|
|
331
|
+
|
|
332
|
+
`develop` therefore carries the version the next release will use, and the
|
|
333
|
+
`release-guard` job holds it there. A PR into `develop` must raise `version` in
|
|
334
|
+
`pyproject.toml` above what `develop` already has, and must add that version's
|
|
335
|
+
`CHANGELOG.md` section. `tools/check_release.py` runs both checks and is what
|
|
336
|
+
fails the PR:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
BASE=origin/develop python3 tools/check_release.py
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
One version per PR, then. The instinct is to let a second change join the
|
|
343
|
+
section the first one opened, and the guard refuses that: the version would be
|
|
344
|
+
tagged with notes that do not describe everything in it, and nothing stops the
|
|
345
|
+
tag going out between the two merges. Bump the patch number again, or fold the
|
|
346
|
+
second change into the first PR.
|
|
347
|
+
|
|
319
348
|
Verify and build live in the reusable workflow
|
|
320
349
|
[`if_s_insightfactory_cli.yml`](https://github.com/insightfactory-ai/if_sre_github_actions/blob/main/.github/workflows/if_s_insightfactory_cli.yml)
|
|
321
350
|
in `insightfactory-ai/if_sre_github_actions`. This repository's
|
|
@@ -330,7 +359,7 @@ reusable workflow and uploads it with `pypa/gh-action-pypi-publish`.
|
|
|
330
359
|
| Trigger | Published version | PyPI role |
|
|
331
360
|
|---|---|---|
|
|
332
361
|
| Push / merge to `develop` | `1.0.1.dev{N}` | pre-release (`pip install --pre`) |
|
|
333
|
-
| Push of a `v*` tag | the version in `pyproject.toml`, which the tag must match | latest |
|
|
362
|
+
| Push of a `v*` tag | the version in `pyproject.toml`, which the tag must match | latest, plus a GitHub Release |
|
|
334
363
|
| Merge to `main` | nothing, CI only | none |
|
|
335
364
|
|
|
336
365
|
`N` is `github.run_number` of the reusable workflow. It is a per-workflow
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "insightfactory-cli"
|
|
3
|
-
version = "1.1.
|
|
3
|
+
version = "1.1.1.dev25"
|
|
4
4
|
description = "Profile-based authentication CLI for the InsightFactory Interfaces API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -39,6 +39,11 @@ packages = ["src/if_cli"]
|
|
|
39
39
|
[tool.pytest.ini_options]
|
|
40
40
|
testpaths = ["tests"]
|
|
41
41
|
|
|
42
|
+
[tool.ty.environment]
|
|
43
|
+
# tools/ is not part of the package, so the scripts there are reached by path at
|
|
44
|
+
# runtime (sys.path.append) and ty needs telling where they live.
|
|
45
|
+
extra-paths = ["tools"]
|
|
46
|
+
|
|
42
47
|
[tool.ruff]
|
|
43
48
|
target-version = "py310"
|
|
44
49
|
line-length = 120
|