codex-usage 0.1.6__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.
@@ -0,0 +1,12 @@
1
+ target/
2
+ .git/
3
+ .github/
4
+ .worktree/
5
+ *.md
6
+ CMakeLists.txt
7
+ pyproject.toml
8
+ scoop/
9
+ .env
10
+ .env.*
11
+ *.log
12
+ .DS_Store
@@ -0,0 +1,210 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*']
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ env:
11
+ CARGO_TERM_COLOR: always
12
+
13
+ jobs:
14
+ pre-commit:
15
+ name: Pre-commit
16
+ runs-on: ubuntu-latest
17
+ if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/')
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@v5
24
+ with:
25
+ python-version: '3.x'
26
+
27
+ - name: Install pre-commit
28
+ run: pip install pre-commit
29
+
30
+ - name: Run pre-commit
31
+ run: pre-commit run --all-files
32
+
33
+ build:
34
+ name: Build (${{ matrix.os }})
35
+ needs: [pre-commit]
36
+ if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/')
37
+ runs-on: ${{ matrix.os }}
38
+ strategy:
39
+ fail-fast: false
40
+ matrix:
41
+ os: [ubuntu-latest, macos-latest, windows-latest]
42
+ rust: [stable]
43
+
44
+ steps:
45
+ - name: Checkout
46
+ uses: actions/checkout@v4
47
+
48
+ - name: Install Rust
49
+ uses: dtolnay/rust-toolchain@master
50
+ with:
51
+ toolchain: ${{ matrix.rust }}
52
+
53
+ - name: Cache cargo
54
+ uses: Swatinem/rust-cache@v2
55
+ with:
56
+ workspaces: ./target
57
+
58
+ - name: Check formatting
59
+ run: cargo fmt --all -- --check
60
+
61
+ - name: Clippy
62
+ run: cargo clippy --all --all-targets -- -D warnings -A dead_code -A unused_variables
63
+
64
+ - name: Build
65
+ run: cargo build --release --verbose
66
+
67
+ - name: Run tests
68
+ run: cargo test --all
69
+
70
+ release:
71
+ name: Release (${{ matrix.platform }})
72
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
73
+ runs-on: ${{ matrix.runs-on }}
74
+ strategy:
75
+ fail-fast: false
76
+ matrix:
77
+ include:
78
+ - platform: macos-x64
79
+ target: x86_64-apple-darwin
80
+ runs-on: macos-14
81
+ - platform: macos-arm64
82
+ target: aarch64-apple-darwin
83
+ runs-on: macos-latest
84
+ - platform: linux-x64
85
+ target: x86_64-unknown-linux-gnu
86
+ runs-on: ubuntu-latest
87
+ - platform: linux-arm64
88
+ target: aarch64-unknown-linux-gnu
89
+ runs-on: ubuntu-latest
90
+ cross: true
91
+ - platform: windows-x64
92
+ target: x86_64-pc-windows-msvc
93
+ runs-on: windows-latest
94
+
95
+ steps:
96
+ - name: Checkout
97
+ uses: actions/checkout@v4
98
+
99
+ - name: Extract version from tag
100
+ id: version
101
+ shell: bash
102
+ run: |
103
+ VERSION="${GITHUB_REF_NAME#v}"
104
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
105
+ echo "Extracted version: $VERSION"
106
+
107
+ - name: Patch Cargo.toml version
108
+ shell: bash
109
+ run: |
110
+ sed -i.bak "s/^version = \".*\"/version = \"${{ steps.version.outputs.version }}\"/" Cargo.toml
111
+ rm -f Cargo.toml.bak
112
+ grep '^version' Cargo.toml
113
+
114
+ - name: Set up QEMU
115
+ if: matrix.cross
116
+ uses: docker/setup-qemu-action@v3
117
+ with:
118
+ platforms: arm64
119
+
120
+ - name: Set up Rust
121
+ uses: dtolnay/rust-toolchain@master
122
+ with:
123
+ toolchain: stable
124
+ targets: ${{ matrix.target }}
125
+
126
+ - name: Set up cross toolchain
127
+ if: matrix.cross
128
+ run: cargo install cross
129
+
130
+ - name: Build release (cross)
131
+ if: matrix.cross
132
+ run: cross build --release --target ${{ matrix.target }}
133
+
134
+ - name: Build release (native)
135
+ if: "!matrix.cross"
136
+ run: cargo build --release --target ${{ matrix.target }}
137
+
138
+ - name: Package (Unix)
139
+ if: runner.os != 'Windows'
140
+ shell: bash
141
+ run: |
142
+ cd target/${{ matrix.target }}/release
143
+ tar czf ../../../codex-usage-${{ matrix.target }}.tar.gz codex-usage
144
+ cd ../../..
145
+ ls -la codex-usage-${{ matrix.target }}.tar.gz
146
+
147
+ - name: Package (Windows)
148
+ if: runner.os == 'Windows'
149
+ shell: pwsh
150
+ run: |
151
+ Compress-Archive -Path "target/${{ matrix.target }}/release/codex-usage.exe" -DestinationPath "codex-usage-${{ matrix.target }}.zip"
152
+ Get-ChildItem "codex-usage-${{ matrix.target }}.zip"
153
+
154
+ - name: Upload artifact
155
+ uses: actions/upload-artifact@v4
156
+ with:
157
+ name: codex-usage-${{ matrix.target }}
158
+ path: |
159
+ codex-usage-${{ matrix.target }}.tar.gz
160
+ codex-usage-${{ matrix.target }}.zip
161
+
162
+ publish:
163
+ name: Publish Release
164
+ needs: [release]
165
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
166
+ runs-on: ubuntu-latest
167
+ permissions:
168
+ contents: write
169
+ steps:
170
+ - name: Download all artifacts
171
+ uses: actions/download-artifact@v4
172
+ with:
173
+ path: artifacts
174
+ merge-multiple: true
175
+
176
+ - name: List artifacts
177
+ run: |
178
+ echo "All files in artifacts:"
179
+ find artifacts -type f -exec ls -la {} \;
180
+
181
+ - name: Create Release
182
+ uses: softprops/action-gh-release@v2
183
+ with:
184
+ tag_name: ${{ github.ref_name }}
185
+ files: artifacts/*
186
+ draft: false
187
+ generate_release_notes: true
188
+ env:
189
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
190
+
191
+ # Trigger downstream workflows via workflow_dispatch.
192
+ # workflow_dispatch is exempt from the GITHUB_TOKEN event limitation,
193
+ # and avoids the reusable workflow OIDC issue with PyPI trusted publishing.
194
+ trigger-downstream:
195
+ name: Trigger downstream workflows
196
+ needs: [publish]
197
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
198
+ runs-on: ubuntu-latest
199
+ permissions:
200
+ actions: write
201
+ steps:
202
+ - name: Trigger Docker build
203
+ run: gh workflow run docker.yml --repo "${{ github.repository }}" --ref "${{ github.ref_name }}"
204
+ env:
205
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
206
+
207
+ - name: Trigger PyPI publish
208
+ run: gh workflow run pypi.yaml --repo "${{ github.repository }}" --ref "${{ github.ref_name }}"
209
+ env:
210
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,58 @@
1
+ name: Build and Push Docker Image
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ packages: write
11
+
12
+ env:
13
+ REGISTRY: ghcr.io
14
+ IMAGE_NAME: ${{ github.repository }}
15
+
16
+ jobs:
17
+ build-and-push:
18
+ name: Build and push multi-arch image
19
+ runs-on: ubuntu-latest
20
+
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - name: Set up QEMU
25
+ uses: docker/setup-qemu-action@v3
26
+
27
+ - name: Set up Docker Buildx
28
+ uses: docker/setup-buildx-action@v3
29
+
30
+ - name: Log in to GitHub Container Registry
31
+ uses: docker/login-action@v3
32
+ with:
33
+ registry: ${{ env.REGISTRY }}
34
+ username: ${{ github.actor }}
35
+ password: ${{ secrets.GITHUB_TOKEN }}
36
+
37
+ - name: Extract metadata (tags, labels)
38
+ id: meta
39
+ uses: docker/metadata-action@v5
40
+ with:
41
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
42
+ tags: |
43
+ type=raw,value=latest,enable={{is_default_branch}}
44
+ type=semver,pattern=v{{version}}
45
+ type=semver,pattern=v{{major}}.{{minor}}
46
+ type=semver,pattern=v{{major}}
47
+ type=sha
48
+
49
+ - name: Build and push
50
+ uses: docker/build-push-action@v6
51
+ with:
52
+ context: .
53
+ platforms: linux/amd64,linux/arm64
54
+ push: true
55
+ tags: ${{ steps.meta.outputs.tags }}
56
+ labels: ${{ steps.meta.outputs.labels }}
57
+ cache-from: type=gha
58
+ cache-to: type=gha,mode=max
@@ -0,0 +1,123 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ jobs:
10
+ build-wheels:
11
+ name: Build wheels (${{ matrix.target }})
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ include:
17
+ - os: ubuntu-latest
18
+ target: x86_64
19
+ - os: macos-latest
20
+ target: x86_64-apple-darwin
21
+ - os: macos-latest
22
+ target: aarch64-apple-darwin
23
+ - os: windows-latest
24
+ target: x64
25
+
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+
29
+ - name: Set up Python
30
+ uses: actions/setup-python@v5
31
+ with:
32
+ python-version: '3.12'
33
+
34
+ - name: Patch version from tag
35
+ if: startsWith(github.ref, 'refs/tags/v')
36
+ shell: bash
37
+ run: |
38
+ VERSION="${GITHUB_REF_NAME#v}"
39
+ echo "Patching Cargo.toml to version $VERSION"
40
+ sed -i.bak "s/^version = \".*\"/version = \"$VERSION\"/" Cargo.toml
41
+ rm -f Cargo.toml.bak
42
+ grep '^version' Cargo.toml
43
+
44
+ - name: Build wheels
45
+ uses: PyO3/maturin-action@v1
46
+ with:
47
+ target: ${{ matrix.target }}
48
+ args: --release --out dist --features pyo3 -i python3.12
49
+ maturin-version: "latest"
50
+ before-script-linux: |
51
+ # Ensure Python headers are available in manylinux container
52
+ if command -v yum >/dev/null 2>&1; then
53
+ yum install -y python3-devel || true
54
+ fi
55
+
56
+ - name: Upload wheels
57
+ uses: actions/upload-artifact@v4
58
+ with:
59
+ name: wheels-${{ matrix.target }}
60
+ path: dist/*.whl
61
+
62
+ build-sdist:
63
+ name: Build source distribution
64
+ runs-on: ubuntu-latest
65
+ steps:
66
+ - uses: actions/checkout@v4
67
+
68
+ - name: Patch version from tag
69
+ if: startsWith(github.ref, 'refs/tags/v')
70
+ shell: bash
71
+ run: |
72
+ VERSION="${GITHUB_REF_NAME#v}"
73
+ sed -i.bak "s/^version = \".*\"/version = \"$VERSION\"/" Cargo.toml
74
+ rm -f Cargo.toml.bak
75
+
76
+ - name: Build sdist
77
+ uses: PyO3/maturin-action@v1
78
+ with:
79
+ command: sdist
80
+ args: --out dist
81
+
82
+ - name: Upload sdist
83
+ uses: actions/upload-artifact@v4
84
+ with:
85
+ name: sdist
86
+ path: dist/*.tar.gz
87
+
88
+ test-pypi:
89
+ name: Test PyPI upload
90
+ needs: [build-wheels, build-sdist]
91
+ continue-on-error: true
92
+ runs-on: ubuntu-latest
93
+ environment: testpypi
94
+ permissions:
95
+ id-token: write
96
+
97
+ steps:
98
+ - uses: actions/download-artifact@v4
99
+ with:
100
+ path: dist
101
+ merge-multiple: true
102
+
103
+ - name: Publish to Test PyPI
104
+ uses: pypa/gh-action-pypi-publish@release/v1
105
+ with:
106
+ repository-url: https://test.pypi.org/legacy/
107
+
108
+ pypi:
109
+ name: PyPI upload
110
+ needs: test-pypi
111
+ runs-on: ubuntu-latest
112
+ environment: pypi
113
+ permissions:
114
+ id-token: write
115
+
116
+ steps:
117
+ - uses: actions/download-artifact@v4
118
+ with:
119
+ path: dist
120
+ merge-multiple: true
121
+
122
+ - name: Publish to PyPI
123
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,30 @@
1
+ # Build
2
+ /target/
3
+ **/target/
4
+
5
+ # Release artifacts
6
+ /release/
7
+ *.tar.gz
8
+ *.zip
9
+ *.deb
10
+ *.rpm
11
+
12
+ # IDE
13
+ .idea/
14
+ .vscode/
15
+ *.swp
16
+ *.swo
17
+
18
+ # OS
19
+ .DS_Store
20
+ Thumbs.db
21
+
22
+ # Environment
23
+ .env
24
+ .env.local
25
+
26
+ # Logs
27
+ *.log
28
+
29
+ # Worktrees
30
+ .worktree/
@@ -0,0 +1,20 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-added-large-files
9
+ - id: check-json
10
+ - id: check-toml
11
+ - id: check-merge-conflict
12
+ - id: debug-statements
13
+
14
+ # Rust hooks disabled - rely on GitHub Actions CI for rust fmt/clippy
15
+ # Enable if you have cargo installed locally:
16
+ # - repo: https://github.com/doublify/pre-commit-rust
17
+ # rev: v1.0
18
+ # hooks:
19
+ # - id: fmt
20
+ # - id: clippy
@@ -0,0 +1,64 @@
1
+ # AGENTS.md — Release & CI/CD Guide
2
+
3
+ ## Version Management
4
+
5
+ - **Source of truth**: Git tags (e.g., `v0.1.5`)
6
+ - **Cargo.toml** contains a base version, but CI patches it from the tag at build time
7
+ - **pyproject.toml** uses `dynamic = ["version"]` — maturin reads version from Cargo.toml
8
+ - **Cargo.lock** must be committed (required for reproducible builds and Docker)
9
+
10
+ ## Release Process
11
+
12
+ ```
13
+ git tag v0.1.5
14
+ git push origin v0.1.5
15
+ ```
16
+
17
+ This triggers the following chain:
18
+
19
+ 1. **ci.yaml** (on tag push `v*`):
20
+ - Builds release binaries for 5 platform targets
21
+ - Packages as `.tar.gz` (Unix) / `.zip` (Windows)
22
+ - Creates a **published** GitHub Release with all artifacts
23
+ - Calls downstream workflows via `workflow_call` (see note below)
24
+
25
+ 2. **docker.yml** (called by ci.yaml after publish):
26
+ - Builds multi-arch Docker image (`linux/amd64`, `linux/arm64`)
27
+ - Pushes to `ghcr.io/<owner>/codex-usage` with semver tags
28
+
29
+ 3. **pypi.yaml** (called by ci.yaml after publish):
30
+ - Builds wheels for all platforms + sdist
31
+ - Publishes to TestPyPI, then PyPI (using trusted publishing)
32
+
33
+ > **Note**: Docker and PyPI workflows are triggered via `workflow_call` from ci.yaml
34
+ > rather than `release: published` events, because `GITHUB_TOKEN`-created events
35
+ > don't trigger other workflows (GitHub Actions limitation). Both workflows also
36
+ > support `workflow_dispatch` for manual runs.
37
+
38
+ ## Platform Matrix
39
+
40
+ | Platform | Target | Runner |
41
+ |----------|--------|--------|
42
+ | macOS x64 | `x86_64-apple-darwin` | `macos-14` |
43
+ | macOS ARM64 | `aarch64-apple-darwin` | `macos-latest` |
44
+ | Linux x64 | `x86_64-unknown-linux-gnu` | `ubuntu-latest` |
45
+ | Linux ARM64 | `aarch64-unknown-linux-gnu` | `ubuntu-latest` (cross) |
46
+ | Windows x64 | `x86_64-pc-windows-msvc` | `windows-latest` |
47
+
48
+ ## Docker Images
49
+
50
+ - Registry: `ghcr.io/<owner>/codex-usage`
51
+ - Tags: `latest` (main branch), `v0.1.5`, `v0.1`, `v0`, SHA
52
+ - Architectures: `linux/amd64`, `linux/arm64`
53
+
54
+ ## PyPI Package
55
+
56
+ - Package name: `codex-usage`
57
+ - Built with maturin (Rust + PyO3 bindings)
58
+ - Wheel targets: `x86_64-manylinux`, `aarch64-manylinux`, `x86_64-apple-darwin`, `aarch64-apple-darwin`, `x86_64-pc-windows-msvc`
59
+
60
+ ## Important Notes
61
+
62
+ - Never create GitHub Releases as drafts — downstream workflows (`docker.yml`, `pypi.yaml`) trigger on `release: published`
63
+ - The `Cargo.lock` file must remain committed and tracked in git
64
+ - Version patching happens in CI via `sed` on `Cargo.toml` — do not manually sync versions across files
@@ -0,0 +1,44 @@
1
+ cmake_minimum_required(VERSION 3.16)
2
+ project(codex-usage VERSION 0.1.0)
3
+
4
+ set(CPACK_PACKAGE_NAME "codex-usage")
5
+ set(CPACK_PACKAGE_VENDOR "Liam Deacon")
6
+ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CLI tool to track OpenAI Codex usage with multi-account support")
7
+ set(CPACK_PACKAGE_VERSION_MAJOR "0")
8
+ set(CPACK_PACKAGE_VERSION_MINOR "1")
9
+ set(CPACK_PACKAGE_VERSION_PATCH "0")
10
+
11
+ set(CPACK_PACKAGE_INSTALL_DIRECTORY "codex-usage")
12
+
13
+ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
14
+ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
15
+
16
+ set(CPACK_SOURCE_GENERATE_TGZ ON)
17
+ set(CPACK_SOURCE_IGNORE_FILES
18
+ "\\.git"
19
+ "\\.github"
20
+ "target"
21
+ "Cargo\\.lock"
22
+ "\\.prettierrc"
23
+ "\\.gitignore"
24
+ )
25
+
26
+ # DEB package settings
27
+ set(CPACK_DEBIAN_PACKAGE_NAME "codex-usage")
28
+ set(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
29
+ set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Liam Deacon")
30
+ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION_SUMMARY "Track OpenAI Codex usage with multi-account support")
31
+ set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
32
+ set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
33
+
34
+ # RPM package settings
35
+ set(CPACK_RPM_PACKAGE_NAME "codex-usage")
36
+ set(CPACK_RPM_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
37
+ set(CPACK_RPM_PACKAGE_RELEASE "1")
38
+ set(CPACK_RPM_PACKAGE_LICENSE "MIT")
39
+ set(CPACK_RPM_PACKAGE_ARCHITECTURE "x86_64")
40
+
41
+ # Generate DEB and RPM packages
42
+ set(CPACK_GENERATOR "DEB;RPM")
43
+
44
+ include(CPack)