Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 17 additions & 22 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot

version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "rust-toolchain"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
rebase-strategy: "disabled"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
rebase-strategy: "disabled"

- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: "weekly"
rebase-strategy: "disabled"
91 changes: 1 addition & 90 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,6 @@ env:
GITHUB_ACTIONS: true

jobs:
# Detect if Rust code has changed
changes:
runs-on: ubuntu-latest
outputs:
rust: ${{ steps.filter.outputs.rust }}
docs: ${{ steps.filter.outputs.docs }}
steps:
- uses: actions/checkout@v6
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
rust:
- '**/*.rs'
- '**/Cargo.toml'
- '**/Cargo.lock'
- '**/build.rs'
- 'justfile'
- 'rust-toolchain.toml'
- 'deny.toml'
docs:
- 'docs/**'
- '*.md'
- '.kiro/**'
- 'spec/**'

# Code quality checks - always run
quality:
runs-on: ubuntu-latest
steps:
Expand All @@ -68,11 +41,8 @@ jobs:
- name: Run clippy (all features)
run: cargo clippy --all-targets --all-features -- -D warnings

# MSRV (Minimum Supported Rust Version) check
msrv:
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.rust == 'true'
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@1.91.0
Expand All @@ -85,8 +55,6 @@ jobs:

test:
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.rust == 'true'
steps:
- uses: actions/checkout@v6

Expand All @@ -106,27 +74,18 @@ jobs:
- name: Build release
run: cargo build --release --all-features

# Test cross-platform - only run when Rust code changes
test-cross-platform:
strategy:
matrix:
include:
# Primary Support - Linux
- os: ubuntu-latest
platform: "Linux"
# Disabled due to lack of ARM runners on GitHub Actions, will re-enable when available
# - os: arm
# platform: "Linux"
# Primary Support - macOS (using available runners)
- os: macos-latest
platform: "macOS"
# Primary Support - Windows
- os: windows-latest
platform: "Windows"

runs-on: ${{ matrix.os }}
needs: changes
if: needs.changes.outputs.rust == 'true'
steps:
- uses: actions/checkout@v6

Expand All @@ -138,15 +97,12 @@ jobs:
with:
tool: cargo-nextest

# Run tests and build the release binary
- run: cargo nextest run --all-features
- run: cargo build --release --all-features

# Generate coverage for TLS-enabled builds - only run when Rust code changes
coverage:
runs-on: ubuntu-latest
needs: [changes, test, test-cross-platform]
if: needs.changes.outputs.rust == 'true'
needs: [test, test-cross-platform]
steps:
- uses: actions/checkout@v6

Expand Down Expand Up @@ -177,48 +133,3 @@ jobs:
with:
token: ${{ secrets.QLTY_COVERAGE_TOKEN }}
files: target/lcov.info
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The qlty coverage upload is configured to read "target/lcov.info", but earlier in this job the LCOV report is written to "lcov.info" (repo root). This mismatch will prevent qlty from finding the report. Align the output path and the upload path (either write into target/lcov.info or upload lcov.info).

Suggested change
files: target/lcov.info
files: lcov.info

Copilot uses AI. Check for mistakes.

# Gate job for branch protection - always runs and reports aggregate status
# Use this as the required status check instead of individual jobs
ci-gate:
name: CI Gate
runs-on: ubuntu-latest
needs: [quality, msrv, test, test-cross-platform, coverage]
if: always()
steps:
- name: Check job results
run: |
echo "Quality: ${{ needs.quality.result }}"
echo "MSRV: ${{ needs.msrv.result }}"
echo "Test: ${{ needs.test.result }}"
echo "Test Cross-Platform: ${{ needs.test-cross-platform.result }}"
echo "Coverage: ${{ needs.coverage.result }}"

# Fail if any required job failed
# Jobs that were skipped (due to path filters) are OK
if [[ "${{ needs.quality.result }}" == "failure" || "${{ needs.quality.result }}" == "cancelled" ]]; then
echo "::error::Quality checks failed"
exit 1
fi

if [[ "${{ needs.msrv.result }}" == "failure" || "${{ needs.msrv.result }}" == "cancelled" ]]; then
echo "::error::MSRV check failed"
exit 1
fi

if [[ "${{ needs.test.result }}" == "failure" || "${{ needs.test.result }}" == "cancelled" ]]; then
echo "::error::Tests failed"
exit 1
fi

if [[ "${{ needs.test-cross-platform.result }}" == "failure" || "${{ needs.test-cross-platform.result }}" == "cancelled" ]]; then
echo "::error::Cross-platform tests failed"
exit 1
fi

if [[ "${{ needs.coverage.result }}" == "failure" || "${{ needs.coverage.result }}" == "cancelled" ]]; then
echo "::error::Coverage generation failed"
exit 1
fi

echo "All CI checks passed (or were skipped due to no relevant changes)"
50 changes: 50 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: "36 23 * * 3"
push:
branches: ["main"]

# Declare default permissions as read-only.
permissions: read-all

jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
if: github.event.repository.default_branch == github.ref_name
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow has an if: condition that references github.event_name == 'pull_request', but this workflow is not configured to run on pull_request events. This makes the condition misleading/dead code. Either add a pull_request trigger (if PR runs are desired) or simplify/remove the condition to match the actual triggers.

Suggested change
if: github.event.repository.default_branch == github.ref_name
if: github.event.repository.default_branch == github.ref_name

Copilot uses AI. Check for mistakes.
permissions:
# Needed to upload the results to the code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write

steps:
- name: "Checkout code"
uses: actions/checkout@v6
with:
persist-credentials: false

- name: "Run analysis"
uses: ossf/scorecard-action@v2.4.3
with:
results_file: results.sarif
results_format: sarif
publish_results: true

- name: "Upload artifact"
uses: actions/upload-artifact@v6
with:
name: SARIF file
path: results.sarif
retention-days: 5

- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: results.sarif
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,4 @@ megalinter-reports/*
target/*
stringy-output/*
tests/fixtures/*
.claude.local.md
89 changes: 89 additions & 0 deletions .mergify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
queue_rules:
- name: default
merge_method: squash
merge_conditions:
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Mergify queue_rules, the required-check list should be under the correct schema key (commonly conditions:). With merge_conditions: here, Mergify may ignore the rule and not enforce the required CI checks. Rename to the correct key so the queue rule is applied.

Suggested change
merge_conditions:
conditions:

Copilot uses AI. Check for mistakes.
- check-success = quality
- check-success = msrv
- check-success = test
- "check-success = test-cross-platform (ubuntu-latest, Linux)"
- "check-success = test-cross-platform (macos-latest, macOS)"
- "check-success = test-cross-platform (windows-latest, Windows)"
- check-success = coverage

pull_request_rules:
# Tier 1: Maintainer PRs -- queue when maintainer adds 'lgtm' label
- name: Queue maintainer PRs with lgtm label
conditions:
- base = main
- "author=@maintainers"
- label = lgtm
- label != do-not-merge
actions:
queue:
name: default

# Tier 2: Trusted bot PRs -- auto-queue when checks pass
- name: Auto-approve and queue dependabot PRs
conditions:
- base = main
- author = dependabot[bot]
- label != do-not-merge
- -files~=\.github/workflows/release\.yml
actions:
review:
type: APPROVE
message: Automatically approved by Mergify
queue:
name: default

# Tier 3: All other PRs (external contributors, copilot) -- require maintainer approval
- name: Queue external PRs when approved by maintainer
conditions:
- base = main
- "-author=@maintainers"
- author != dependabot[bot]
- "approved-reviews-by=@maintainers"
- label != do-not-merge
actions:
queue:
name: default

- name: Keep PRs up to date with main
conditions:
- base = main
- -conflict
- -draft
- -author = dependabot[bot]
- label != do-not-merge
actions:
update: {}

merge_protections:
- name: Enforce conventional commit
description: Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
if:
- base = main
success_conditions:
- "title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\\(.+\\))?:"

- name: CI must pass
description: >-
All CI checks must pass. This protection prevents manual merges
that bypass the merge queue.
if:
- base = main
success_conditions:
- check-success = quality
- check-success = msrv
- check-success = test
- "check-success = test-cross-platform (ubuntu-latest, Linux)"
- "check-success = test-cross-platform (macos-latest, macOS)"
- "check-success = test-cross-platform (windows-latest, Windows)"
- check-success = coverage

- name: Do not merge outdated PRs
description: Make sure PRs are within 10 commits of the base branch before merging
if:
- base = main
success_conditions:
- "#commits-behind <= 10"
23 changes: 22 additions & 1 deletion .serena/project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,27 @@ excluded_tools: []
# initial prompt for the project. It will always be given to the LLM upon activating the project
# (contrary to the memories, which are loaded on demand).
initial_prompt: ""

# the name by which the project can be referenced within Serena
project_name: "Stringy"

# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default)
included_optional_tools: []

# list of mode names to that are always to be included in the set of active modes
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this setting overrides the global configuration.
# Set this to [] to disable base modes for this project.
# Set this to a list of mode names to always include the respective modes for this project.
base_modes:

# list of mode names that are to be activated by default.
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# This setting can, in turn, be overridden by CLI parameters (--mode).
default_modes:
Comment on lines +99 to +106
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base_modes: is declared but has no value, which YAML parses as null. If the intent is an empty list, set it to []; if the intent is to inherit global base modes, omit this key entirely.

Suggested change
base_modes:
# list of mode names that are to be activated by default.
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# This setting can, in turn, be overridden by CLI parameters (--mode).
default_modes:
# list of mode names that are to be activated by default.
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# This setting can, in turn, be overridden by CLI parameters (--mode).

Copilot uses AI. Check for mistakes.
Comment on lines +99 to +106
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default_modes: is declared but has no value, which YAML parses as null. If the intent is an empty list, set it to []; if the intent is to inherit global defaults, omit this key entirely.

Suggested change
base_modes:
# list of mode names that are to be activated by default.
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# This setting can, in turn, be overridden by CLI parameters (--mode).
default_modes:
# list of mode names that are to be activated by default.
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# This setting can, in turn, be overridden by CLI parameters (--mode).

Copilot uses AI. Check for mistakes.

# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
fixed_tools: []
Loading
Loading