feat(scaffold): expose --max-changes as a configurable merge-threshold flag @jorrite (#3236)
## what- Adds a real
--max-changesint flag to bothatmos scaffold generate --updateandatmos init --update(env varsATMOS_SCAFFOLD_MAX_CHANGES/ATMOS_INIT_MAX_CHANGES), wired through the existing (previously test-only)engine.Processor.SetMaxChanges. - Default stays
50(no behavior change for existing callers). Only negative values are rejected — there is intentionally no upper bound (see "why" below). - Adds
SetMaxChangesto theScaffoldUI/InitUIinterfaces (and regenerates their mocks), renaming the previously-unwiredInitUI.SetThresholdtoSetMaxChangesto match. - Adds unit tests, CLI-level range-validation tests, and full end-to-end tests (real git repos, real merges) proving the flag actually reaches the merge engine and changes outcomes under both
trackedandrenderedupdate strategies. - Updates
docs/prd/atmos-scaffold.mdand thescaffold generate/initCLI docs. - Adds a changelog post (
website/blog/2026-09-30-scaffold-max-changes-flag.mdx) and a roadmap milestone, since this is a new user-visible flag.
why
- The 3-way merge threshold behind
--updatewas hardcoded at 50% with no way to configure it — any update whose conflict touched more than half a file's lines failed outright, with no option to proceed and resolve conflict markers by hand instead. - While field-testing this flag before opening the PR, I found the underlying change-percentage metric (
pkg/generator/merge, pre-existing, untouched here) isn't capped at 100 —countDifferentLinescounts both deletions and insertions, so a realistic multi-line conflict routinely computes past 100%, and can exceed 200% when both the user's local edits and the template's changes diverge heavily from the common base.- This meant an initial 0-100-range version of this flag was actively misleading: a user told "raise it to 100 to always allow the merge through" could still hit a hard failure on an ordinary conflict.
- Fixed by removing the upper bound entirely (only reject negative values) and rewriting every doc/hint/help surface to state plainly that only
0guarantees the check never fires — any positive value just makes a hard failure progressively less likely, never impossible.
references
docs/prd/atmos-scaffold.mdpreviously listed--max-changesunder "Still not implemented."- Related prior work: #3047 (base-ref-anchoring and conflict-marker fixes for
--update, already shipped, not touched here).
🤖 Generated with Claude Code
Summary by CodeRabbit
-
New Features
- Added
--max-changestoatmos initandatmos scaffold generate --update. The default limit is 50%; set it to0to disable the change-percentage check. - Configure the limit with
ATMOS_INIT_MAX_CHANGESorATMOS_SCAFFOLD_MAX_CHANGES. Positive values do not guarantee an update will proceed because the calculated change percentage can exceed 100%.
- Added
-
Bug Fixes
- Improved merge change detection for files with different line endings while preserving line endings in merge results.
-
Documentation
- Added guidance and examples for configuring the merge threshold.
docs(skills): add GitHub Actions to Native CI migration reference @osterman (#3246)
## what- Adds a new agent-skill reference,
agent-skills/skills/atmos-migration/references/to-native-ci.md, that maps common third-party GitHub Actions Terraform CI patterns to Atmos Native CI equivalents: running Atmos from the container image instead of an install/setup action, replacinghashicorp/setup-terraform/opentofu/setup-opentofuwith the toolchain, replacingaws-actions/configure-aws-credentials(andazure/login/google-github-actions/auth) withauth.providers/auth.identitiesand CI profiles, replacing thedflook/terraform-github-actionssuite andtfcmt, native planfile storage semantics,tfsec/checkov/kics/infracostscanning hooks, notification hooks (kind: commandandkind: step+type: webhook), and status-check/comment/template configuration. - Wires the new reference into
atmos-migration/SKILL.md(frontmatterreferences:list, routing table, and "When to Escalate" section) and adds a back-link fromatmos-ci/SKILL.md's Related Skills table for discoverability. - Adds two pre-existing test-fixture fingerprints to
.gitleaksignore(pkg/component/helm/secret_values_integration_test.go,pkg/io/masker_test.go) surfaced by a local merge fromorigin/main; both are intentional fake-secret fixtures for the secrets-masking tests, not real credentials. - Adds a reusable
.github/actions/swap-spacelocal action. It puts a swapfile on whichever of/mntor/has more free space, sizes it to leave a reserve of free disk, and warns and shrinks or skips the file rather than failing when space is short. Thegovulncheckjob in.github/workflows/codeql.ymluses it to add 20G of swap, itsGOMEMLIMITgoes from 12GiB to 32GiB, and the scan step is capped at 30 minutes. The full analysis now completes in about 11 minutes instead of OOM-killing the runner.
why
- The
atmos-migrationskill already covered migrating Terraform code/state (native Terraform, Terraform Workspaces, Terragrunt, Terramate, task runners, auth configs) but had no guidance for migrating an existing repo's CI/CD off third-party GitHub Actions onto Atmos Native CI, even thoughatmos-ciandatmos-modernizationonly cover Cloud Posse's own deprecated wrapper actions. aws-actions/configure-aws-credentialsanddflook/terraform-github-actionsare the most widely used Terraform GitHub Actions in the wild, so agents need a concrete, verified recipe for converting them (and adjacent tools liketfcmt,tfsec/checkov,infracost) rather than inventing unverified config.govulncheckwas failing on every branch still pinned tocontainerd/v2v2.3.5. Advisory GO-2026-6597 (published 2026-10-01) makes govulncheck build its whole-program call graph. On this module that pass peaked at about 25GB RSS when measured locally, past the public runner's 16GB, so the runner was OOM-killed (Killed, exit 143, or "The operation was canceled"). The old 12GiB limit couldn't shrink a heap that size; it only kept the garbage collector running nonstop.
references
- GO-2026-6597
- golang/go#79053 (govulncheck call-graph memory on large modules)
- #3227 (Dependabot bump of containerd to v2.3.6, which removes the trigger)
Summary by CodeRabbit
- Documentation
- Added guidance for migrating GitHub Actions Terraform pipelines and scanner workflows to Atmos Native CI, including permissions, authentication, status reporting, planfiles, and validation.
- Updated migration and vendoring guidance for component updates, token configuration, and workflow behavior.
- Expanded CI and hooks references with guidance on concurrency, state-lock timeouts, scanner permissions, and TFLint hooks.
- Chores
- Added secret-scanning exceptions for two findings in test files.
- Improved vulnerability scanning capacity and added a configurable swap-space action.
fix(ci): preserve release tags and isolate concurrent tests @osterman (#3243)
## what- Preserve and verify release tags when rewriting notes, with regression coverage for stable/prerelease tags, missing or changed tags, and malformed responses.
- Fix premature singleflight registration signaling and sandbox the deployment-status test's Terraform writes, with the original shared vendor fixture restored.
- Validation: full Go build, scoped lint, release-note tests (96.9% coverage), Terraform-output package tests, 30 race-detector repetitions, both vendor CLI cases, and three deployment-status runs confirming the shared mock fixture remains unchanged.
why
- Prevent draft updates from losing their release tags and fix Windows shards 4 and 8 at their causes: premature synchronization and a Terraform test writing state into a fixture concurrently read by vendoring.
references
- Release-notes summarizer: #3045
- Release incident: https://github.com/cloudposse/atmos/actions/runs/36771391085
- Windows test failures: https://github.com/cloudposse/atmos/actions/runs/36889110856
Summary by CodeRabbit
- Bug Fixes
- Release-note updates now preserve the existing release tag and detect when the tag is missing or changes during an update.
- Tests
- Improved coverage for release-tag handling and concurrent Terraform workdir provisioning.
- Updated deployment-status checks to verify the Terraform workspace is written to the configured sandbox.
feat(auth): add azure/pim-role identity for just-in-time PIM role activation @aknysh (#3239)
## what- Add a new
azure/pim-roleauth identity kind that activates a PIM-eligible Azure resource role just-in-time as part of the identity chain. - On authentication it resolves the principal object id from the parent management token, short-circuits if the role is already active at the scope, requires an existing eligibility, resumes a pending approval request instead of filing a duplicate, files a
SelfActivaterequest, and polls until it provisions. - It mints no new credentials: the elevation applies to the existing principal server-side, so
Authenticatereturns the parent credentials unchanged and the activation is inherited transparently byatmos terraform,atmos auth exec, the AKS exec plugin, and MCP servers. - Principal config:
role_definition_id(required),scope(required),duration(optional Go-style, converted to ISO-8601),justification(optional default). - Justification is an auth-level concern (not PIM-specific), so it is supplied via a new global
--justificationflag (like--identity) orATMOS_AUTH_JUSTIFICATION. Precedence:--justification>ATMOS_AUTH_JUSTIFICATION>principal.justification> interactive prompt; the flag/env reach the identity through thejustificationviper key. - ARM PIM calls live behind a
PIMClientinterface (dependency-injection seam) with an HTTP implementation that targets the correct Resource Manager endpoint per cloud environment (public / US Gov / China) and filters to the caller via$filter=asTarget(). - Add PIM error sentinels to
errors/errors.go; register the kind in the auth factory; export a token object-id helper and aResourceManagerEndpoint()cloud-environment helper. - Docs: new config reference section,
commands/authusage + login notes, a changelog blog post, and a roadmap milestone. PRD status updated to Implemented.
why
- Azure resource roles are increasingly PIM-eligible (just-in-time) rather than standing, so an operator holds the role only after activating it, for a time-boxed window, with a justification.
- There is no native
azcommand for activating an eligible Azure resource role, so activation is a multi-step ARM REST dance that operators otherwise hand-roll every working session. - Atmos Auth already models identity chaining ("become more privileged") and credential time-boxing, but Azure only had
azure/subscription. This expresses the elevation once, in config, so every downstream consumer inherits it with no extra wiring.
references
- PRD:
docs/prd/azure-pim-role-identity.md - Follow-up (pre-flight cap of
durationat the role's PIM activation-policy maximum): #3238 - Microsoft docs: PIM for Azure resources; Role Assignment Schedule Requests (
requestType: SelfActivate, api-version2020-10-01); Role Eligibility Schedule Instances ($filter=asTarget())
Summary by CodeRabbit
- New Features
- Added just-in-time activation of eligible Azure resource roles through PIM, chained to an existing Azure identity. Parent credentials remain unchanged.
- Skips activation when the role is already active and resumes matching pending requests rather than creating duplicates.
- Supports optional activation duration and justification via
--justification,ATMOS_AUTH_JUSTIFICATION, identity configuration, or an interactive prompt. - Non-interactive activation requires a justification, and approval waits are bounded.
- Warns when a supplied justification is not used.
- Documentation
- Added Azure PIM configuration and login guidance, and documented Interactive Browser authorization-code/PKCE support.
- Bug Fixes
- Provides clearer feedback for missing eligibility or justification, activation failures, and timeouts.
fix(ci): drop HOMEBREW_NO_INSTALL_FROM_API from the Homebrew bump step @aknysh (#3240)
## what- Remove
HOMEBREW_NO_INSTALL_FROM_API: "1"from the "Bump Homebrew formula" step in.github/workflows/build.ymlsobrew bump-formula-prruns in its default formulae-API mode. - Keep
HOMEBREW_NO_AUTO_UPDATE: "1"; update the step comment to explain why the var must not be set.
why
- With that env var set, the step forces a full
homebrew-coretap clone and makesbump-formula-prresolve the formula from the freshly cloned tree, which fails withNo available formula with the name "atmos". Did you mean aptos?— on every release run sampled (v1.228.0, v1.229.0, v1.230.0, v1.230.1). As a result the Homebrew bump has always been done manually. - The formula genuinely exists (
Formula/a/atmos.rbon homebrew-core'smain, served byformulae.brew.sh). The var was added on the mistaken premise that it was needed to make the formula editable;bump-formula-predits, forks under the bot token, and opens the PR itself without it. - This is the next layer after #3229 (which fixed the earlier
brew: command not foundPATH bug and let this step run for the first time, exposing this latent failure). - Verified locally:
brew bump-formula-pr --dry-run --version=1.230.1 atmosin API mode resolvesatmoscleanly (proceeds to the duplicate-PR check with no "No available formula" error — the exact CI failure).actionlintreports no findings in the edited step.
references
- Fix log:
docs/fixes/2026-10-01-homebrew-bump-no-install-from-api.md - Prior related fix (PATH): #3229
- Interim manual bump for the current release: homebrew-core PR #314644 (atmos 1.230.1)
Summary by CodeRabbit
- Bug Fixes
- Improved Homebrew release formula updates by allowing Homebrew’s API mode to resolve the
atmosformula, avoiding lookup failures caused by forced tap mode.
- Improved Homebrew release formula updates by allowing Homebrew’s API mode to resolve the
- Documentation
- Added a note describing the formula update issue, the workflow change, validation performed, and the pending end-to-end confirmation.
🤖 Automatic Updates
build(deps): bump github.com/containerd/containerd/v2 from 2.3.5 to 2.3.6 in the go_modules group across 1 directory @[dependabot[bot]](https://github.com/apps/dependabot) (#3227)
Bumps the go_modules group with 1 update in the / directory: [github.com/containerd/containerd/v2](https://github.com/containerd/containerd).Updates Sourced from github.com/containerd/containerd/v2's releases.
Welcome to the v2.3.6 release of containerd!
The sixth patch release for containerd 2.3 contains various fixes
and updates including a security patch.
Please try out the release binaries and report any issues at
https://github.com/containerd/containerd/issues.
... (truncated)
github.com/containerd/containerd/v2 from 2.3.5 to 2.3.6
Release notes
containerd 2.3.6
Security Updates
Highlights
Container Runtime Interface (CRI)
Image Storage
Runtime
Contributors
Changes
086fc0d40e Prepare release notes for v2.3.6
3e3b3daabc Merge commit from fork
03fbef37da Bound Walk references
bfe167214b Bound Dispatch concurrency and references
5f17a29a9b core/mount: Keep lazy copy for filtered options
Commits
ee27353 Merge pull request #14226 from samuelkarp/prepare-release-2.3.6
086fc0d Prepare release notes for v2.3.6
3e3b3da Merge commit from fork
92e6694 Merge pull request #14192 from vvoland/13433-release/2.3
f7ae0f2 Merge pull request #14211 from k8s-infra-cherrypick-robot/cherry-pick-14207-t...
7fd198f cri: tolerate wrapped ENOTSUP during relabel
03fbef3 Bound Walk references
bfe1672 Bound Dispatch concurrency and references
5f17a29 core/mount: Keep lazy copy for filtered options
4979657 core/mount: Return copied filtered mount options
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore <dependency name> major versionwill close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)@dependabot ignore <dependency name> minor versionwill close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)@dependabot ignore <dependency name>will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)@dependabot unignore <dependency name>will remove all of the ignore conditions of the specified dependency@dependabot unignore <dependency name> <ignore condition>will remove the ignore condition of the specified dependency and ignore conditions
You can disable automated security fix PRs for this repo from the Security Alerts page.