posit-cli 0.1.0__tar.gz → 0.1.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.
@@ -43,6 +43,9 @@ jobs:
43
43
  runs-on: ubuntu-latest
44
44
  steps:
45
45
  - uses: actions/checkout@v7
46
+ # hatch-vcs reads the version from the tags, so fetch them.
47
+ with:
48
+ fetch-depth: 0
46
49
  - uses: astral-sh/setup-uv@v9.0.0
47
50
  - uses: extractions/setup-just@v4
48
51
  - run: just build
@@ -0,0 +1,62 @@
1
+ name: Release
2
+ on:
3
+ push:
4
+ tags:
5
+ - "v*.*.*"
6
+ jobs:
7
+ publish:
8
+ runs-on: ubuntu-latest
9
+ environment: release
10
+ permissions:
11
+ id-token: write
12
+ steps:
13
+ - uses: actions/checkout@v7
14
+ with:
15
+ fetch-depth: 0
16
+ - uses: astral-sh/setup-uv@v9.0.0
17
+ - uses: extractions/setup-just@v4
18
+ # The tag is the only source of the version, so this only guards against a
19
+ # build that did not pick the tag up (shallow clone, dirty tree, two tags on
20
+ # one commit).
21
+ - name: assert build version matches tag
22
+ env:
23
+ TAG: ${{ github.ref_name }}
24
+ run: |
25
+ ver="$(just version)"
26
+ if [ "$TAG" != "v$ver" ]; then
27
+ echo "::error::tag '${TAG}' does not match build version 'v${ver}'"
28
+ exit 1
29
+ fi
30
+ - name: assert tag is on main
31
+ env:
32
+ TAG: ${{ github.ref_name }}
33
+ run: |
34
+ if ! git merge-base --is-ancestor HEAD origin/main; then
35
+ echo "::error::tag '${TAG}' points to a commit that is not on main"
36
+ exit 1
37
+ fi
38
+ - run: just build
39
+ - run: just smoke
40
+ - uses: actions/upload-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+ - uses: pypa/gh-action-pypi-publish@release/v1
45
+
46
+ # Runs only after PyPI accepts the upload, so a failed publish leaves no release.
47
+ github-release:
48
+ needs: publish
49
+ runs-on: ubuntu-latest
50
+ permissions:
51
+ contents: write
52
+ steps:
53
+ - uses: actions/checkout@v7
54
+ - uses: actions/download-artifact@v4
55
+ with:
56
+ name: dist
57
+ path: dist/
58
+ - name: create GitHub release
59
+ env:
60
+ GH_TOKEN: ${{ github.token }}
61
+ TAG: ${{ github.ref_name }}
62
+ run: gh release create "$TAG" dist/* --title "$TAG" --generate-notes
@@ -9,6 +9,9 @@ dist/
9
9
  .venv/
10
10
  venv/
11
11
 
12
+ # Written at build time by hatch-vcs
13
+ /src/posit_cli/_version.py
14
+
12
15
  # Tooling
13
16
  .pytest_cache/
14
17
  .ruff_cache/
@@ -37,4 +37,7 @@ posit-sdk) and the OAuth-release gotcha.
37
37
  `RSConnectClient`), which has no stability contract. `tests/test_rsconnect_contract.py` guards
38
38
  the surface we depend on; pin the rsconnect version and re-verify on bumps.
39
39
 
40
+ - The git tag sets the version, through `hatch-vcs`. `pyproject.toml` has no `version` field.
41
+ Do not add one.
42
+
40
43
  See `RELEASE.md` for how to cut a release to PyPI.
@@ -29,9 +29,9 @@ smoke:
29
29
  install: build
30
30
  uv pip install "$(ls -t dist/*.whl | head -1)"
31
31
 
32
- # Print the current version
32
+ # Print the version that a build gets from the current git state
33
33
  version:
34
- @uv version --short
34
+ @uvx hatch version
35
35
 
36
36
  # Remove build/test artifacts
37
37
  clean:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: posit-cli
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: A single, friendly command-line interface for Posit Connect, in the spirit of gh.
5
5
  Author: Posit Software, PBC
6
6
  License-Expression: MIT
@@ -30,21 +30,27 @@ This project is in early-stage development and so far only supports Posit Connec
30
30
 
31
31
  ## Installation
32
32
 
33
- `posit-cli` isn't on PyPI yet. Install the latest version straight from GitHub
34
- with [`uv`](https://docs.astral.sh/uv/):
33
+ Install [`posit-cli` from PyPI](https://pypi.org/project/posit-cli/) with
34
+ [`uv`](https://docs.astral.sh/uv/):
35
+
36
+ ```console
37
+ uv tool install posit-cli
38
+ ```
39
+
40
+ To get unreleased changes, install from GitHub instead:
35
41
 
36
42
  ```console
37
43
  uv tool install git+https://github.com/posit-dev/posit-cli.git
38
44
  ```
39
45
 
40
- If you authenticate to GitHub over SSH, use the `git+ssh://` form instead (uv
41
- requires the `git@` username):
46
+ If you authenticate to GitHub over SSH, use the `git+ssh://` form (uv requires
47
+ the `git@` username):
42
48
 
43
49
  ```console
44
50
  uv tool install git+ssh://git@github.com/posit-dev/posit-cli.git
45
51
  ```
46
52
 
47
- Either way this puts the `posit` executable on your `PATH`. To upgrade later, run
53
+ Each of these puts the `posit` executable on your `PATH`. To upgrade later, run
48
54
  `uv tool upgrade posit-cli`. See uv's
49
55
  [Git authentication docs](https://docs.astral.sh/uv/concepts/authentication/git/)
50
56
  for tokens and other hosts.
@@ -12,21 +12,27 @@ This project is in early-stage development and so far only supports Posit Connec
12
12
 
13
13
  ## Installation
14
14
 
15
- `posit-cli` isn't on PyPI yet. Install the latest version straight from GitHub
16
- with [`uv`](https://docs.astral.sh/uv/):
15
+ Install [`posit-cli` from PyPI](https://pypi.org/project/posit-cli/) with
16
+ [`uv`](https://docs.astral.sh/uv/):
17
+
18
+ ```console
19
+ uv tool install posit-cli
20
+ ```
21
+
22
+ To get unreleased changes, install from GitHub instead:
17
23
 
18
24
  ```console
19
25
  uv tool install git+https://github.com/posit-dev/posit-cli.git
20
26
  ```
21
27
 
22
- If you authenticate to GitHub over SSH, use the `git+ssh://` form instead (uv
23
- requires the `git@` username):
28
+ If you authenticate to GitHub over SSH, use the `git+ssh://` form (uv requires
29
+ the `git@` username):
24
30
 
25
31
  ```console
26
32
  uv tool install git+ssh://git@github.com/posit-dev/posit-cli.git
27
33
  ```
28
34
 
29
- Either way this puts the `posit` executable on your `PATH`. To upgrade later, run
35
+ Each of these puts the `posit` executable on your `PATH`. To upgrade later, run
30
36
  `uv tool upgrade posit-cli`. See uv's
31
37
  [Git authentication docs](https://docs.astral.sh/uv/concepts/authentication/git/)
32
38
  for tokens and other hosts.
@@ -0,0 +1,34 @@
1
+ # Releasing
2
+
3
+ The git tag is the only source of the version. `pyproject.toml` has no `version` field —
4
+ `hatch-vcs` reads the tag at build time. Do not add one.
5
+
6
+ Follow these steps to publish a new version to PyPI:
7
+
8
+ 1. Make sure `main` holds everything you want in the release.
9
+ 2. Tag the commit on `main` as `vX.Y.Z`.
10
+ 3. Push the tag. This triggers `.github/workflows/release.yaml`.
11
+
12
+ ```console
13
+ git checkout main && git pull
14
+ git tag v0.2.0
15
+ git push origin v0.2.0
16
+ ```
17
+
18
+ The release workflow confirms that the build picked the tag up and that the tag is on `main`,
19
+ builds the wheel and sdist, smoke-tests the wheel, then publishes to PyPI through GitHub's OIDC
20
+ trusted-publisher flow. No PyPI token is stored in this repo. After PyPI accepts the upload, a
21
+ second job creates a GitHub release for the tag, with generated notes and the built artifacts
22
+ attached.
23
+
24
+ Run `just version` to see the version that a build gets from the current git state. A commit
25
+ after the last tag gets a development version (for example `0.2.1.dev3+g1a2b3c4`), which PyPI
26
+ rejects. Only a clean, tagged commit produces a release version.
27
+
28
+ ## One-time setup for a new repo
29
+
30
+ - Create a `release` environment under the repo's Settings > Environments, with required
31
+ reviewers. The `publish` job runs under this environment; without required reviewers, any tag
32
+ push publishes to PyPI immediately with no human gate.
33
+ - Configure a trusted publisher for `posit-cli` on PyPI with: Owner `posit-dev`, Repository name
34
+ `posit-cli`, Workflow name `release.yaml`, Environment name `release`.
@@ -1,6 +1,7 @@
1
1
  [project]
2
2
  name = "posit-cli"
3
- version = "0.1.0"
3
+ # The version comes from the git tag, through hatch-vcs. Never hard-code it here.
4
+ dynamic = ["version"]
4
5
  description = "A single, friendly command-line interface for Posit Connect, in the spirit of gh."
5
6
  readme = "README.md"
6
7
  requires-python = ">=3.8"
@@ -28,9 +29,17 @@ test = ["pytest>=7"]
28
29
  lint = ["ruff>=0.6"]
29
30
 
30
31
  [build-system]
31
- requires = ["hatchling"]
32
+ requires = ["hatchling", "hatch-vcs"]
32
33
  build-backend = "hatchling.build"
33
34
 
35
+ [tool.hatch.version]
36
+ source = "vcs"
37
+
38
+ # Write the resolved version into the package. An sdist has no git metadata, so a
39
+ # wheel built from an sdist reads this file instead of asking git.
40
+ [tool.hatch.build.hooks.vcs]
41
+ version-file = "src/posit_cli/_version.py"
42
+
34
43
  [tool.hatch.build.targets.wheel]
35
44
  packages = ["src/posit_cli"]
36
45
 
@@ -208,15 +208,21 @@ These are rsconnect commands — run `posit connect <command> --help` for detail
208
208
 
209
209
  ## Installing the CLI
210
210
 
211
- `posit-cli` isn't on PyPI yet; install from GitHub with [`uv`](https://docs.astral.sh/uv/):
211
+ Install from PyPI with [`uv`](https://docs.astral.sh/uv/):
212
212
 
213
213
  ```console
214
- uv tool install git+https://github.com/posit-dev/posit-cli.git # `posit` onto your PATH
215
- uv tool upgrade posit-cli # later, to update
214
+ uv tool install posit-cli # `posit` onto your PATH
215
+ uv tool upgrade posit-cli # later, to update
216
216
  ```
217
217
 
218
- If GitHub is set up for SSH auth, use the `git+ssh://` form instead (uv requires
219
- the `git@` username):
218
+ For unreleased changes, install from GitHub instead:
219
+
220
+ ```console
221
+ uv tool install git+https://github.com/posit-dev/posit-cli.git
222
+ ```
223
+
224
+ If GitHub is set up for SSH auth, use the `git+ssh://` form (uv requires the
225
+ `git@` username):
220
226
 
221
227
  ```console
222
228
  uv tool install git+ssh://git@github.com/posit-dev/posit-cli.git
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.1.1'
22
+ __version_tuple__ = version_tuple = (0, 1, 1)
23
+
24
+ __commit_id__ = commit_id = None
@@ -729,7 +729,6 @@ wheels = [
729
729
 
730
730
  [[package]]
731
731
  name = "posit-cli"
732
- version = "0.1.0"
733
732
  source = { editable = "." }
734
733
  dependencies = [
735
734
  { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
@@ -759,7 +758,7 @@ requires-dist = [
759
758
  { name = "rsconnect-python", specifier = ">=1.30,<2" },
760
759
  { name = "ruff", marker = "extra == 'lint'", specifier = ">=0.6" },
761
760
  ]
762
- provides-extras = ["test", "lint"]
761
+ provides-extras = ["lint", "test"]
763
762
 
764
763
  [[package]]
765
764
  name = "pycparser"
@@ -1,37 +0,0 @@
1
- name: Release
2
- on:
3
- push:
4
- tags:
5
- - "v*.*.*"
6
- jobs:
7
- publish:
8
- runs-on: ubuntu-latest
9
- environment: release
10
- permissions:
11
- id-token: write
12
- steps:
13
- - uses: actions/checkout@v7
14
- with:
15
- fetch-depth: 0
16
- - uses: astral-sh/setup-uv@v9.0.0
17
- - uses: extractions/setup-just@v4
18
- - name: assert tag matches pyproject version
19
- env:
20
- TAG: ${{ github.ref_name }}
21
- run: |
22
- ver="$(just version)"
23
- if [ "$TAG" != "v$ver" ]; then
24
- echo "::error::tag '${TAG}' does not match pyproject version 'v${ver}'"
25
- exit 1
26
- fi
27
- - name: assert tag is on main
28
- env:
29
- TAG: ${{ github.ref_name }}
30
- run: |
31
- if ! git merge-base --is-ancestor HEAD origin/main; then
32
- echo "::error::tag '${TAG}' points to a commit that is not on main"
33
- exit 1
34
- fi
35
- - run: just build
36
- - run: just smoke
37
- - uses: pypa/gh-action-pypi-publish@release/v1
@@ -1,22 +0,0 @@
1
- # Releasing
2
-
3
- Follow these steps to publish a new version to PyPI:
4
-
5
- 1. Bump `version` in `pyproject.toml`.
6
- 2. Run `uv lock` if the bump changed any dependency. CI fails the build if `uv.lock` has drifted.
7
- 3. Commit the change and merge it to `main`.
8
- 4. Tag the merged commit on `main` as `vX.Y.Z`. The tag must match the `pyproject.toml` version
9
- exactly.
10
- 5. Push the tag. This triggers `.github/workflows/release.yaml`.
11
-
12
- The release workflow checks the tag against `pyproject.toml` and against `main`, builds the
13
- wheel and sdist, smoke-tests the wheel, then publishes to PyPI through GitHub's OIDC
14
- trusted-publisher flow. No PyPI token is stored in this repo.
15
-
16
- ## One-time setup for a new repo
17
-
18
- - Create a `release` environment under the repo's Settings > Environments, with required
19
- reviewers. The `publish` job runs under this environment; without required reviewers, any tag
20
- push publishes to PyPI immediately with no human gate.
21
- - Configure a trusted publisher for `posit-cli` on PyPI with: Owner `posit-dev`, Repository name
22
- `posit-cli`, Workflow name `release.yaml`, Environment name `release`.
File without changes
File without changes
File without changes