-
Notifications
You must be signed in to change notification settings - Fork 7
Feat: Harden string invariants, serde semantics, Cargo features, and release automation #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| name: Release | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - "v*.*.*" | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: "Version to release, for example 1.1.0" | ||
| required: true | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| env: | ||
| CARGO_TERM_COLOR: always | ||
| RUST_BACKTRACE: full | ||
|
|
||
| jobs: | ||
| publish: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Set up Rust | ||
| uses: dtolnay/rust-toolchain@stable | ||
| with: | ||
| toolchain: stable | ||
|
|
||
| - name: Resolve release version | ||
| id: version | ||
| shell: bash | ||
| run: | | ||
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | ||
| VERSION="${{ inputs.version }}" | ||
| else | ||
| VERSION="${GITHUB_REF_NAME#v}" | ||
| fi | ||
|
Comment on lines
+40
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix template injection vulnerability in shell script. The Pass untrusted inputs via environment variables instead of direct interpolation. 🔒 Proposed fix - name: Resolve release version
id: version
shell: bash
+ env:
+ VERSION_INPUT: ${{ inputs.version }}
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
- VERSION="${{ inputs.version }}"
+ VERSION="$VERSION_INPUT"
else
VERSION="${GITHUB_REF_NAME#v}"
fi🧰 Tools🪛 zizmor (1.25.2)[error] 41-41: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
|
|
||
| if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then | ||
| echo "Invalid release version: $VERSION" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| MANIFEST_VERSION="$(cargo metadata --no-deps --format-version 1 | python3 -c 'import json, sys; print(json.load(sys.stdin)["packages"][0]["version"])')" | ||
| if [[ "$MANIFEST_VERSION" != "$VERSION" ]]; then | ||
| echo "Cargo.toml version $MANIFEST_VERSION does not match release version $VERSION" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | ||
| echo "tag=v$VERSION" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Create tag for manual release | ||
| if: github.event_name == 'workflow_dispatch' | ||
| shell: bash | ||
| run: | | ||
| TAG="${{ steps.version.outputs.tag }}" | ||
| CURRENT_SHA="$(git rev-parse HEAD)" | ||
|
|
||
| if git rev-parse "$TAG" >/dev/null 2>&1; then | ||
| TAG_SHA="$(git rev-list -n 1 "$TAG")" | ||
| if [[ "$TAG_SHA" != "$CURRENT_SHA" ]]; then | ||
| echo "Tag $TAG already exists at $TAG_SHA, not current HEAD $CURRENT_SHA" >&2 | ||
| exit 1 | ||
| fi | ||
| else | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git tag "$TAG" | ||
| git push origin "$TAG" | ||
| fi | ||
|
|
||
| - name: Check formatting | ||
| run: cargo fmt -- --check | ||
|
|
||
| - name: Lint | ||
| run: cargo clippy --all-features -- -D warnings | ||
|
|
||
| - name: Test all features | ||
| run: cargo test --all-features | ||
|
|
||
| - name: Test no-default feature matrix | ||
| run: cargo test --no-default-features --features serde,bytes,simd | ||
|
|
||
| - name: Package crate | ||
| run: cargo package | ||
|
|
||
| - name: Publish crate to crates.io | ||
| run: cargo publish --token "$CARGO_REGISTRY_TOKEN" | ||
| env: | ||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||
|
|
||
| - name: Create GitHub release | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| TAG: ${{ steps.version.outputs.tag }} | ||
| VERSION: ${{ steps.version.outputs.version }} | ||
| run: | | ||
| gh release create "$TAG" \ | ||
| "target/package/cheetah-string-$VERSION.crate#cheetah-string-$VERSION.crate" \ | ||
| --verify-tag \ | ||
| --title "cheetah-string $TAG" \ | ||
| --generate-notes | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
What are the latest commit SHAs for actions/checkout v4 and dtolnay/rust-toolchain stable?💡 Result:
As of June 20, 2026, the latest commit SHAs for these actions are as follows: 1. actions/checkout@v4: The v4 branch for actions/checkout is a moving target that receives updates [1][2][3]. As it is not a static tag, the specific commit SHA associated with the v4 reference can change over time. To obtain the current absolute SHA, you should check the official actions/checkout repository [1]. 2. dtolnay/rust-toolchain stable: This action does not use a single "stable" commit SHA [4][5]. Instead, the toolchain (e.g., "stable", "nightly", or specific versions like "1.94.1") is selected using an input within your workflow file, and the action itself is typically pinned to a commit on the master branch [4][6][7]. The author recommends pinning the action to a full-length commit SHA from the master branch history to ensure security and stability, rather than relying on dynamic tags [4][6][5]. As of March 27, 2026, a recent commit on the master branch is 3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 [7]. For security-conscious workflows, it is recommended to inspect the repository history directly to select a verified commit SHA on the master branch for dtolnay/rust-toolchain, or check the specific ref for actions/checkout [1][4][6].
Citations:
🏁 Script executed:
Repository: mxsm/cheetah-string
Length of output: 457
🌐 Web query:
What is the current latest stable version/commit SHA of actions/checkout as of June 2026?💡 Result:
As of June 20, 2026, the latest stable version of actions/checkout is v7.0.0, which was released on June 18, 2026 [1][2]. The commit SHA associated with the v7.0.0 tag is 6927d6d9d1502f61c3905c1069b2d398d57d5904 (this can be verified via the repository's tags on GitHub) [1][2].
Citations:
🌐 Web query:
What is the current latest commit SHA for dtolnay/rust-toolchain master branch as of June 2026?💡 Result:
As of June 20, 2026, the dtolnay/rust-toolchain repository continues to use the master branch as its primary development branch [1][2]. The last recorded push to this repository occurred on March 27, 2026, at 15:56:25 UTC [1]. The commit associated with this update is SHA 3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9, which added support for the 1.94.1 patch release [3]. There have been no subsequent commits to the master branch since that date. Therefore, the latest commit SHA for the dtolnay/rust-toolchain master branch as of June 20, 2026, is 3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 [3].
Citations:
Pin action references to commit SHAs and disable credential persistence.
Using tag-based references (
@v4,@stable) for actions is a supply chain risk—a compromised tag could inject malicious code. Pin to full commit SHAs instead. Additionally, setpersist-credentials: falseon checkout to prevent git credentials from persisting in the workspace.Note: A newer major version of actions/checkout is available. Use v7.0.0 or later.
🔒 Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 26-29: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 27-27: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 32-32: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Source: Linters/SAST tools