-
Notifications
You must be signed in to change notification settings - Fork 0
fix(lanes): green mutation-testing, trunk-check, a11y keyboard, scorecard, and quality-gate unit tests #719
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 all commits
f895f27
7528edf
7d5f3f2
77c758a
37b2b0a
3c85657
fd392dc
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 |
|---|---|---|
|
|
@@ -4,6 +4,15 @@ | |
| # Handles: ruff, mypy, clippy, golangci-lint, prettier, eslint, shellcheck, etc. | ||
| # Free for open source; cached for fast runs | ||
| # ============================================================================= | ||
| # | ||
| # NOTE (2026-08): the lane runs the same linters that `.trunk/trunk.yaml` | ||
| # enables (actionlint + taplo + yamllint) via direct, pinned installs instead | ||
| # of trunk-io/trunk-action. trunk-action's managed tool bootstrap repeatedly | ||
| # failed on ubuntu-latest ("Binary not found" / "jq not installed on system!" | ||
| # inside its launcher), while the tools themselves install cleanly. actionlint | ||
| # runs from the official docker image (no download-and-execute in the lane). | ||
| # The `.trunk/` config remains the local-developer source of truth | ||
| # (`trunk check`). | ||
|
|
||
| name: Trunk Check | ||
|
|
||
|
|
@@ -28,11 +37,29 @@ jobs: | |
| - name: Checkout | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
|
|
||
| - name: Trunk Check | ||
| uses: trunk-io/trunk-action@v1 | ||
|
|
||
| - name: Trunk Upgrade (on schedule only) | ||
| if: github.event_name == 'schedule' | ||
| uses: trunk-io/trunk-action@v1 | ||
| - name: Run actionlint | ||
| # Official pinned image; avoids curl|tar installs (SonarCloud flags | ||
| # download-and-execute patterns as a security issue on new code). | ||
| # `-shellcheck=` disables the image's bundled shellcheck: trunk's | ||
| # actionlint integration runs without shellcheck too (and the repo's | ||
| # workflows carry pre-existing SC2034/SC2086 advisories that trunk | ||
| # does not gate on). | ||
| uses: docker://rhysd/actionlint:1.7.12 | ||
| with: | ||
| trunk-args: --upgrade | ||
| args: -shellcheck= | ||
|
|
||
| - name: Install taplo | ||
| run: cargo install taplo-cli --locked --version 0.9.3 | ||
|
|
||
| - name: Install yamllint | ||
| run: sudo apt-get update && sudo apt-get install -y yamllint | ||
|
Comment on lines
+54
to
+55
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. 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Changed/workflow files:"
git ls-files .github/workflows/trunk-check.yml | sed -n '1,20p'
echo
echo "Workflow excerpt:"
if [ -f .github/workflows/trunk-check.yml ]; then
nl -ba .github/workflows/trunk-check.yml | sed -n '1,90p'
fi
echo
echo "yamllint references:"
rg -n "yamllint|Trunk|pin|pinned|tool" .github/workflows .trunk 2>/dev/null || true
echo
echo "Workflow runner and apt cache config:"
rg -n "runs-on:|apt|cache|pin|install" .github/workflows/trunk-check.ymlRepository: KooshaPari/sharecli Length of output: 275 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p=Path('.github/workflows/trunk-check.yml')
print('exists:', p.exists())
if p.exists():
lines=p.read_text().splitlines()
for i,l in enumerate(lines,1):
if i in [*range(1,16),*range(40,55)] or any(s in l for s in ['yamllint','Trunk','pin']):
print(f'{i}: {l}')
PYRepository: KooshaPari/sharecli Length of output: 1930 🌐 Web query:
💡 Result: On Ubuntu, the apt package manager determines the default installation version of a package like yamllint by selecting the candidate with the highest priority [1][2]. By default, this is the version available in your configured package repositories with the highest version number [1]. To control or lock a specific version, you can use APT pinning [1][3]. This is generally considered more reliable than commands like apt-mark hold for system-wide configuration, as it is respected by all apt-based tools [4]. To pin the yamllint package to a specific version, create a file in the /etc/apt/preferences.d/ directory (e.g., /etc/apt/preferences.d/yamllint) with the following format [1][5][3]: Package: yamllint Pin: version 1.37.1-1 Pin-Priority: 1001 In this configuration: 1. Package: Specifies the package name [1][3]. 2. Pin: Specifies the exact version string you wish to pin [6][3]. You can verify the exact version strings available on your system using the command: apt-cache policy yamllint [6][7]. 3. Pin-Priority: Setting this to 1001 or higher forces apt to install that specific version, even if it constitutes a downgrade or overrides a newer version available in the repositories [2][8][7]. After creating this file, you can verify that the pinning is correctly applied by running apt-cache policy yamllint again; the output should show the pinned version as the candidate [8][7]. Note that pinning by version requires you to specify the exact version string exactly as it appears in the package database, which sometimes includes an epoch (e.g., 5:1.2.3) [6][8]. Citations:
🌐 Web query:
💡 Result: Trunk employs a config-as-code philosophy to manage tools, linters, and runtimes, ensuring consistent environments across local development and CI [1][2]. All such dependencies are pinned within your repository's.trunk/trunk.yaml configuration file [3][2]. Pinning and Version Management: - Version Pinning: You can pin a specific version of a tool, linter, or runtime by appending an exclamation mark (!) to the version string in your.trunk/trunk.yaml file [4][5]. For example: lint: enabled: - pylint@2.17.5! - Preventing Upgrades: When a version is pinned with the! suffix, the trunk upgrade command will ignore it, preventing unintended updates [4][5]. - Automatic Management: When you enable a tool via trunk tools enable @, Trunk automatically updates the configuration to lock that version [3]. Trunk handles the hermetic installation and caching of these tools (in ~/.cache/trunk or.trunk/tools), ensuring they do not rely on or pollute your host system's environment [3][6][2]. - Eponymous vs. Additional Tools: If a linter depends on a tool, they may need to keep their versions synced [4]. For eponymous tools (where the tool name matches the linter name), the tool is implicitly enabled with the linter's version [7]. Additional tool dependencies must be explicitly enabled and versioned independently in the tools.enabled section of your configuration [7]. Upgrading: - To upgrade tools, you use the trunk upgrade command [4][8]. This command updates tools to their latest public releases unless they have been explicitly pinned with the! suffix [4]. You can also apply these upgrades to specific configuration files using the --apply-to flag [4][8]. Citations:
Pin the
Example fix- run: sudo apt-get update && sudo apt-get install -y yamllint
+ run: python -m pip install --disable-pip-version-check "yamllint==<approved-version>"🤖 Prompt for AI AgentsSource: MCP tools |
||
|
|
||
| - name: Run remaining trunk linters | ||
| run: | | ||
| set -euo pipefail | ||
| # actionlint runs in the docker step above (reads | ||
| # .github/actionlint.yaml for ignore rules). | ||
| # Same whitespace-only formatting contract as `trunk fmt`. | ||
| taplo fmt --check | ||
| # Same relaxed ruleset as `.trunk/trunk.yaml`'s yamllint section. | ||
| yamllint -c .trunk/configs/.yamllint.yaml . | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -163,6 +163,12 @@ pub fn spawn_speculation_task( | |
| cache: CoalesceCache, | ||
| thermal_gate: Arc<dyn crate::ThermalGate>, | ||
| ) { | ||
| // Best-effort background task. The hypervisor constructor may run outside | ||
| // a Tokio runtime (sync CLI wiring, unit tests); without a reactor there | ||
| // is nothing to spawn onto, so skip silently rather than panic. | ||
| if tokio::runtime::Handle::try_current().is_err() { | ||
| return; | ||
| } | ||
|
Comment on lines
+169
to
+171
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. Suggestion: The guard permanently disables speculation when Severity Level: Major
|
||
| tokio::spawn(async move { | ||
| loop { | ||
| tokio::time::sleep(SPECULATION_INTERVAL).await; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -167,9 +167,14 @@ mod tests { | |||||
|
|
||||||
| use super::*; | ||||||
|
|
||||||
| /// Serializes all audit tests that mutate process-global env vars. | ||||||
| /// The tests otherwise race on `SHARECLI_AUDIT_LOG` (e.g. one test | ||||||
| /// removes the var while another is mid-emit, so the file is never | ||||||
| /// written and `read_to_string` fails with `NotFound`). | ||||||
| static ENV_LOCK: Mutex<()> = Mutex::new(()); | ||||||
|
|
||||||
| #[test] | ||||||
| fn emit_if_configured_respects_env_gate() { | ||||||
| static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); | ||||||
| let _env = ENV_LOCK.lock().unwrap(); | ||||||
|
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. WARNING: The previous
Suggested change
Reply with |
||||||
| let dir = tempfile::tempdir().unwrap(); | ||||||
| let path = dir.path().join("gated.jsonl"); | ||||||
|
|
@@ -205,9 +210,9 @@ mod tests { | |||||
|
|
||||||
| #[test] | ||||||
| fn path_respects_env_override() { | ||||||
| let _env = ENV_LOCK.lock().unwrap(); | ||||||
| let dir = tempfile::tempdir().unwrap(); | ||||||
| let path = dir.path().join("custom.jsonl"); | ||||||
| let _guard = WRITE_LOCK.lock().unwrap_or_else(|e| e.into_inner()); | ||||||
| unsafe { | ||||||
| std::env::set_var("SHARECLI_AUDIT_LOG", &path); | ||||||
| } | ||||||
|
|
@@ -219,7 +224,6 @@ mod tests { | |||||
|
|
||||||
| #[test] | ||||||
| fn rotates_when_over_max_bytes() { | ||||||
| static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); | ||||||
| let _env = ENV_LOCK.lock().unwrap(); | ||||||
| let dir = tempfile::tempdir().unwrap(); | ||||||
| let path = dir.path().join("audit.jsonl"); | ||||||
|
|
||||||
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.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: KooshaPari/sharecli
Length of output: 245
🏁 Script executed:
Repository: KooshaPari/sharecli
Length of output: 2594
Scope
security-events: writeto the Scorecard job.scorecard-actiononly needscontents: read, whilegithub/codeql-action/upload-sarifneedssecurity-events: write. The workflow-level permission grantssecurity-events: writeto every job in this workflow and any future jobs. Movesecurity-events: writeunderjobs.analysis.permissionsand keep only the Scorecard job’s required read permissions at the workflow level or job level as appropriate.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 25-25: overly broad permissions (excessive-permissions): security-events: write is overly broad at the workflow level
(excessive-permissions)
🤖 Prompt for AI Agents
Source: Linters/SAST tools