Skip to content

Migration guide

Sijawusz Pur Rahnama edited this page Jul 23, 2026 · 24 revisions

v1.6 → v1.7

Overview

Ameba 1.7 is a major release with significant new features, 37 new rules, infrastructure changes, and several breaking changes. This guide walks through each breaking change and what you need to do to migrate.

Minimum Crystal version: 1.19.0


Renamed Rules

Documentation/DocumentationAdmonitionDocumentation/Admonition

PR: #647

The rule name was shortened for consistency. If you reference this rule in your .ameba.yml, CLI --only/--except flags, or inline # ameba:disable directives, update it:

# Before
Documentation/DocumentationAdmonition:
  Enabled: true

# After
Documentation/Admonition:
  Enabled: true
# Before
# ameba:disable Documentation/DocumentationAdmonition

# After
# ameba:disable Documentation/Admonition

Lint/DuplicatedRequireLint/DuplicateRequire

PR: #873

Renamed from Duplicated to Duplicate for grammatical correctness. Apply the same migration pattern as above:

# Before
Lint/DuplicatedRequire:
  Enabled: true

# After
Lint/DuplicateRequire:
  Enabled: true

Deprecated Rules

Performance/AnyInsteadOfEmpty — Deprecated

PR: #846

This rule was replaced by Performance/AnyInsteadOfPresent and will emit a deprecation notice. It will be fully removed in a future version. If you use it, consider migrating away from it.


Rules Disabled by Default

Documentation/Admonition — now disabled by default

PR: #648

This rule checks for NOTE/TODO/WARNING markers in documentation comments. It's now disabled by default because it's a subjective style preference and may be too noisy for many projects.

If you relied on this rule being active, enable it explicitly:

Documentation/Admonition:
  Enabled: true

Lint/Typos — now disabled by default

PR: #721

This rule is disabled by default due to significant performance issues:

  • It uses a global mutex that severely slows execution
  • It loads each file into memory to pass to the typos CLI
  • It requires its own file exclusion list separate from Ameba's
  • It only catches typos within source files — less effective than running typos via CLI or GitHub Action directly

If you want to keep using it, enable it explicitly:

Lint/Typos:
  Enabled: true

Recommendation: Use the typos CLI directly or via a GitHub Action instead, for better performance and coverage.


Removed Rule Options

Lint/UselessAssign: ExcludeTypeDeclarations option removed

PR: #769

The ExcludeTypeDeclarations option has been removed because the rule now always skips type declarations within call arguments (previously this was opt-in). Type declarations used as call arguments like foo(x : String) are never flagged as useless assignments, regardless of this setting.

Lint/UselessAssign:
  ExcludeTypeDeclarations: true # Remove this line

Simply delete the ExcludeTypeDeclarations line from your config. Type declarations within calls are already handled correctly by the new liveness-based analysis.

Lint/SpecFilename: IgnoredDirs and IgnoredFilenames options removed

PR: #850

These two options have been replaced with a single unified IgnoredPaths option that accepts glob patterns:

# Before
Lint/SpecFilename:
  Enabled: true
  IgnoredDirs: [spec/support spec/fixtures spec/data]
  IgnoredFilenames: [spec_helper]

# After
Lint/SpecFilename:
  Enabled: true
  IgnoredPaths:
    - spec/support/**
    - spec/fixtures/**
    - spec/data/**
    - spec/**/spec_helper.cr

The new defaults for IgnoredPaths are:

IgnoredPaths:
  - spec/support/**
  - spec/fixtures/**
  - spec/data/**
  - spec/**/spec_helper.cr

ECR File Linting

PRs: #536, #540, #541, #546

Ameba now supports linting .ecr files. This also changed the default glob/exclusion handling:

Aspect v1.6 v1.7
Default Globs ["**/*.cr", "!lib"] ["**/*.{cr,ecr}"]
Default Excluded [] (empty) ["lib"]

The lib folder exclusion moved from being an inline !lib negated glob to a proper Excluded entry. If you have a custom Globs or Excluded in your .ameba.yml, review whether you need to update it:

# If you were overriding Globs/Excluded before, you should now ensure
# .ecr files are included and lib is excluded:
Globs:
  - "**/*.{cr,ecr}"

Excluded:
  - lib

If you don't override these settings, the defaults handle this automatically.


CLI Breaking Changes

Empty values are being ignored

All flag values that are empty strings are ignored.

$ ameba --only ""
# Before: raises an error and exits with status code 255
Rule `` does not exist

$ ameba --only ""
# After: ignores the empty value

--fail-level replaced with --min-severity

PR: #761

The --fail-level flag has been replaced with --min-severity. These have different semantics:

  • --fail-level (old): Controlled only the exit code — all issues were reported, but only those at or above the given severity would cause a non-zero exit.
  • --min-severity (new): Controls which issues are reported at all — only issues at or above the given severity are shown. The exit code behavior is unaffected (any issue = non-zero exit).
# Before
$ ameba --fail-level warning

# After
$ ameba --min-severity warning

Valid values: convention, warning, error (same as before).

Migration tip: If you used --fail-level convention (the default), you can simply drop the flag — the default behavior is the same. If you used a stricter level, migrate to --min-severity and be aware that issues below that threshold will now be completely hidden, not just ignored for exit code purposes.

--ignore-unmatched-paths flag added

To opt out of the new "raise on invalid file path" behavior, use the new --ignore-unmatched-paths flag (see below).

--only and --except flags no longer ignore configuration Globs/Excluded

To opt out of the new behavior, use the new --ignore-config flag:

# Before
ameba --only RuleName

# After
ameba --ignore-config --only RuleName

Config Changes

Silently ignore unknown config attributes

PR: #840

Previously, Ameba would raise an error on unknown YAML attributes in .ameba.yml. Now it silently ignores them. This makes the config file more forward-compatible (e.g., when downgrading Ameba versions).

This means typos in config keys will no longer cause an error, but will silently do nothing. Validate your config carefully after upgrading.

Raise on invalid file path or glob pattern

PR: #827

Ameba now raises an error if a provided file path or glob resolves to no files, instead of silently succeeding:

$ ameba typo.cr
# Before: silently exited 0, checked nothing

$ ameba typo.cr
# After: raises an error and exits with status code 255
No files found matching `typo.cr`

Use the new --ignore-unmatched-paths flag to opt back into the old silent behavior:

$ ameba --ignore-unmatched-paths typo.cr

Project Root Detection

PR: #588

Ameba now properly detects the project root directory. Running ameba within /path/to/project directory will result in the same behavior as running ameba /path/to/project.

Globs are resolved relative to the project root. When you pass a path like ameba /path/to/project, Ameba finds the nearest .ameba.yml file in that project, and uses the directory containing it as the project root.

Relative source paths are normalized.


Rule versioning

PRs: #471, #752, #767

To lock Ameba ruleset to a specific version, set the Version attribute in your .ameba.yml configuration:

Version: 1.6.4

Or use the --up-to-version flag when running Ameba via CLI:

$ ameba --up-to-version 1.6.4

Versioned Documentation

PRs: #702, #704

Documentation URLs now include the version. If you link to Ameba documentation, the URL structure has changed. Rule presenter output also now includes the versioned documentation URL.


Infrastructure / Build Changes

Crystal Version Requirements

PRs: #678, #802

Ameba 1.7 requires Crystal >= 1.19.0

This is a hard requirement — the compiler will emit an error on older versions.

Skip Auto Compilation (postinstall script removed)

PR: #741

The postinstall script has been removed. The bin/ameba binary is no longer compiled automatically when you run shards install or shards update.

Local Migration

Add an ameba target to your shard.yml:

targets:
  ameba:
    main: lib/ameba/bin/ameba.cr

Then build it:

$ shards build ameba

Alternatively, build directly:

$ crystal build -o bin/ameba lib/ameba/bin/ameba.cr

CI Migration

Recommended: Use the Ameba GitHub Action — typical run is ~several seconds vs around a minute for local builds.

Add a ameba.yml workflow file:

name: Ameba

on:
  push:
  pull_request:

permissions:
  contents: read

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Download source
        uses: actions/checkout@v7

      - name: Run Ameba Linter
        uses: crystal-ameba/github-action@master

If you must build locally in CI, add a build step:

- name: Build Ameba Linter
  run: crystal build -o bin/ameba lib/ameba/bin/ameba.cr

- name: Run Ameba
  run: bin/ameba

bin/ameba.cr Executable No Longer Installed

PR: #807

Previously, bin/ameba.cr was copied to the user's bin/ directory on each shards install/update, which overrode any customizations made to it.

Now, use the canonical source file at lib/ameba/bin/ameba.cr:

$ crystal run lib/ameba/bin/ameba.cr
# or
$ crystal build -o bin/ameba lib/ameba/bin/ameba.cr

Summary: Quick Migration Checklist

Area Action Required
Config Rename Documentation/DocumentationAdmonitionDocumentation/Admonition
Config Rename Lint/DuplicatedRequireLint/DuplicateRequire
Config Remove ExcludeTypeDeclarations from Lint/UselessAssign
Config Replace IgnoredDirs + IgnoredFilenames with IgnoredPaths in Lint/SpecFilename
Config Review Globs/Excluded for .ecr file inclusion and lib exclusion
CLI flags Replace --fail-level with --min-severity
Shard Update shard.yml with an ameba target if using local binary
CI Switch to GitHub Action or add a build step for bin/ameba
Crystal Ensure Crystal >= 1.19.0
Documentation Check rule documentation URLs are versioned
Inline directives Update # ameba:disable for renamed rules

Clone this wiki locally