-
-
Notifications
You must be signed in to change notification settings - Fork 775
feat(sops): support standard SOPS environment variables #7461
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
base: main
Are you sure you want to change the base?
Conversation
Add support for SOPS_AGE_KEY_FILE and SOPS_AGE_KEY environment variables, falling back to mise-specific settings if not set. This improves compatibility with existing SOPS workflows without requiring duplicate configuration.
|
|
||
| ``` | ||
| $ mise tasks add test -- echo 'running tests' | ||
| $ mise task add test -- echo 'running tests' |
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.
I didn't change this, some codegen did
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.
Pull request overview
This PR adds support for standard SOPS environment variables (SOPS_AGE_KEY_FILE and SOPS_AGE_KEY) to improve compatibility with existing SOPS workflows. The implementation checks these standard variables first before falling back to mise-specific settings.
Key changes:
- Modified the age key lookup logic to prioritize standard SOPS environment variables over mise-specific settings
- Updated documentation to describe the new precedence order and environment variable support
- Added comprehensive e2e tests to verify the new functionality and precedence behavior
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 29 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sops.rs | Implements precedence logic: checks SOPS_AGE_KEY_FILE, then SOPS_AGE_KEY, then mise-specific settings; stores and restores environment variables |
| settings.toml | Updates descriptions for age_key and age_key_file settings to mention SOPS environment variable fallback |
| schema/mise.json | Updates JSON schema descriptions to match settings.toml changes |
| e2e/secrets/test_secrets | Adds comprehensive tests for standard SOPS environment variables and precedence verification; fixes age-keygen output parsing |
| docs/environments/secrets/sops.md | Documents the new environment variables support and precedence order |
| docs/cli/tasks/validate.md | Updates command examples from mise tasks validate to mise task validate |
| docs/cli/tasks/run.md | Contains documentation updates with some grammar issues |
| docs/cli/tasks/edit.md | Contains documentation updates with some grammar issues |
| docs/cli/tasks/add.md | Updates command examples from mise tasks to mise task |
| docs/cli/run.md | Contains documentation updates with some grammar issues |
| docs/cli/index.md | Updates shorthand description to use mise task instead of mise tasks |
| docs/cli/generate/task-stubs.md | Updates example to use mise task add instead of mise tasks add |
| mise.usage.kdl | Contains many documentation updates including fixes to command references and some grammar issues |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Run task(s) | ||
|
|
||
| This command will run a task, or multiple tasks in parallel. | ||
| This command will run a tasks, or multiple tasks in parallel. |
Copilot
AI
Dec 20, 2025
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.
The grammar here is incorrect. "This command will run a tasks" is grammatically wrong. It should either be "This command will run a task" (singular) or "This command will run tasks" (plural without 'a'). Based on the context that follows ("or multiple tasks in parallel"), the correct phrasing should be: "This command will run a task, or multiple tasks in parallel."
| # Execute multiple tasks each with their own arguments. | ||
| $ mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2 | ||
| $ mise tasks cmd1 arg1 arg2 ::: cmd2 arg1 arg2 |
Copilot
AI
Dec 20, 2025
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.
This change is incorrect. The command should be mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2 not mise tasks cmd1 arg1 arg2 ::: cmd2 arg1 arg2. The mise run command is the correct way to execute tasks, not mise tasks.
| $ mise tasks cmd1 arg1 arg2 ::: cmd2 arg1 arg2 | |
| $ mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2 |
| ### `-n --dry-run` | ||
|
|
||
| Don't actually run the task(s), just print them in order of execution | ||
| Don't actually run the tasks(s), just print them in order of execution |
Copilot
AI
Dec 20, 2025
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.
The grammar here is incorrect. "Don't actually run the tasks(s)" has incorrect punctuation. It should be either "task(s)" or "tasks" but not "tasks(s)". The original "task(s)" was correct notation to indicate singular or plural.
| Don't actually run the tasks(s), just print them in order of execution | |
| Don't actually run the tasks, just print them in order of execution |
| "description": "The age private key to use for sops secret decryption. Falls back to SOPS_AGE_KEY environment variable if not set.", | ||
| "type": "string" | ||
| }, | ||
| "age_key_file": { | ||
| "description": "Path to the age private key file to use for sops secret decryption.", | ||
| "description": "Path to the age private key file to use for sops secret decryption. Falls back to SOPS_AGE_KEY_FILE environment variable if not set.", |
Copilot
AI
Dec 20, 2025
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.
The descriptions state that the settings "Falls back to SOPS_AGE_KEY environment variable if not set" and "Falls back to SOPS_AGE_KEY_FILE environment variable if not set", but this is backwards. Based on the implementation in src/sops.rs, the standard SOPS environment variables are checked first, and the mise-specific settings are used as fallbacks. The descriptions should be corrected to something like "Mise-specific setting for age private key. If not set, falls back to the standard SOPS_AGE_KEY environment variable."
| alias r | ||
| long_help "Run task(s)\n\nThis command will run a task, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a task, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" | ||
| after_long_help "Examples:\n\n # Runs the \"lint\" tasks. This needs to either be defined in mise.toml\n # or as a standalone script. See the project README for more information.\n $ mise run lint\n\n # Forces the \"build\" tasks to run even if its sources are up-to-date.\n $ mise run build --force\n\n # Run \"test\" with stdin/stdout/stderr all connected to the current terminal.\n # This forces `--jobs=1` to prevent interleaving of output.\n $ mise run test --raw\n\n # Runs the \"lint\", \"test\", and \"check\" tasks in parallel.\n $ mise run lint ::: test ::: check\n\n # Execute multiple tasks each with their own arguments.\n $ mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2\n" | ||
| long_help "Run task(s)\n\nThis command will run a tasks, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a tasks, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" |
Copilot
AI
Dec 20, 2025
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.
The grammar here is incorrect. "If source is configured on a tasks" is grammatically wrong. It should be "If source is configured on a task" (singular). The original text "If source is configured on a task" was correct.
| long_help "Run task(s)\n\nThis command will run a tasks, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a tasks, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" | |
| long_help "Run task(s)\n\nThis command will run a task, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a task, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the task.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" |
| alias r | ||
| long_help "Run task(s)\n\nThis command will run a task, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a task, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" | ||
| after_long_help "Examples:\n\n # Runs the \"lint\" tasks. This needs to either be defined in mise.toml\n # or as a standalone script. See the project README for more information.\n $ mise run lint\n\n # Forces the \"build\" tasks to run even if its sources are up-to-date.\n $ mise run build --force\n\n # Run \"test\" with stdin/stdout/stderr all connected to the current terminal.\n # This forces `--jobs=1` to prevent interleaving of output.\n $ mise run test --raw\n\n # Runs the \"lint\", \"test\", and \"check\" tasks in parallel.\n $ mise run lint ::: test ::: check\n\n # Execute multiple tasks each with their own arguments.\n $ mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2\n" | ||
| long_help "Run task(s)\n\nThis command will run a tasks, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a tasks, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" |
Copilot
AI
Dec 20, 2025
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.
The grammar here is incorrect. "If source is configured on a tasks" is grammatically wrong. It should be "If source is configured on a task" (singular). The original text "If source is configured on a task" was correct.
| long_help "Run task(s)\n\nThis command will run a tasks, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a tasks, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" | |
| long_help "Run task(s)\n\nThis command will run a task, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a task, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the task.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" |
| - **Source code**: [`src/cli/tasks/edit.rs`](https://github.com/jdx/mise/blob/main/src/cli/tasks/edit.rs) | ||
|
|
||
| Edit a task with $EDITOR | ||
| Edit a tasks with $EDITOR |
Copilot
AI
Dec 20, 2025
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.
The grammar here is incorrect. "Edit a tasks with $EDITOR" should be singular: "Edit a task with $EDITOR". The article "a" indicates singular, so "tasks" (plural) is grammatically incorrect.
| Edit a tasks with $EDITOR | |
| Edit a task with $EDITOR |
| arg <TASK_FLAG> | ||
| } | ||
| flag "-g --glob" help="Files to watch\nDefaults to sources from the task(s)" var=#true hide=#true { | ||
| flag "-g --glob" help="Files to watch\nDefaults to sources from the tasks(s)" var=#true hide=#true { |
Copilot
AI
Dec 20, 2025
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.
The grammar here is incorrect. "Defaults to sources from the tasks(s)" has incorrect punctuation. It should be either "task(s)" or "tasks" but not "tasks(s)". The original "task(s)" was correct notation to indicate singular or plural.
| flag "-g --glob" help="Files to watch\nDefaults to sources from the tasks(s)" var=#true hide=#true { | |
| flag "-g --glob" help="Files to watch\nDefaults to sources from the task(s)" var=#true hide=#true { |
| - `SOPS_AGE_KEY_FILE` - Path to age private key file | ||
| - `SOPS_AGE_KEY` - Age private key content directly | ||
|
|
||
| **Mise-specific variables (override standard ones if both are set):** |
Copilot
AI
Dec 20, 2025
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.
The documentation states that "Mise-specific variables (override standard ones if both are set)" but this is incorrect based on the actual implementation. Looking at the code in src/sops.rs, the standard SOPS variables (SOPS_AGE_KEY_FILE and SOPS_AGE_KEY) are checked first and take precedence over the mise-specific variables. The documentation should state that mise-specific variables are used as fallbacks, not overrides.
| **Mise-specific variables (override standard ones if both are set):** | |
| **Mise-specific variables (used as fallbacks if standard ones are not set):** |
| alias r | ||
| long_help "Run task(s)\n\nThis command will run a task, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a task, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" | ||
| after_long_help "Examples:\n\n # Runs the \"lint\" tasks. This needs to either be defined in mise.toml\n # or as a standalone script. See the project README for more information.\n $ mise run lint\n\n # Forces the \"build\" tasks to run even if its sources are up-to-date.\n $ mise run build --force\n\n # Run \"test\" with stdin/stdout/stderr all connected to the current terminal.\n # This forces `--jobs=1` to prevent interleaving of output.\n $ mise run test --raw\n\n # Runs the \"lint\", \"test\", and \"check\" tasks in parallel.\n $ mise run lint ::: test ::: check\n\n # Execute multiple tasks each with their own arguments.\n $ mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2\n" | ||
| long_help "Run task(s)\n\nThis command will run a tasks, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a tasks, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" |
Copilot
AI
Dec 20, 2025
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.
The grammar here is incorrect. "This command will run a tasks" is grammatically wrong. It should either be "This command will run a task" (singular) or "This command will run tasks" (plural without 'a'). Based on the context that follows ("or multiple tasks in parallel"), the correct phrasing should be: "This command will run a task, or multiple tasks in parallel."
| long_help "Run task(s)\n\nThis command will run a tasks, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a tasks, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" | |
| long_help "Run task(s)\n\nThis command will run a task, or multiple tasks in parallel.\nTasks may have dependencies on other tasks or on source files.\nIf source is configured on a tasks, it will only run if the source\nfiles have changed.\n\nTasks can be defined in mise.toml or as standalone scripts.\nIn mise.toml, tasks take this form:\n\n [tasks.build]\n run = \"npm run build\"\n sources = [\"src/**/*.ts\"]\n outputs = [\"dist/**/*.js\"]\n\nAlternatively, tasks can be defined as standalone scripts.\nThese must be located in `mise-tasks`, `.mise-tasks`, `.mise/tasks`, `mise/tasks` or\n`.config/mise/tasks`.\nThe name of the script will be the name of the tasks.\n\n $ cat .mise/tasks/build<<EOF\n #!/usr/bin/env bash\n npm run build\n EOF\n $ mise run build" |
|
@jdx I am not sure what is happening with the CI to be honest, could you give me a north star here? |
| precedence_std_file="$HOME/precedence_standard.txt" | ||
| precedence_mise_file="$HOME/precedence_mise.txt" | ||
| age_pub1="$(mise x -- age-keygen -o "$precedence_std_file" 2>&1 | grep -E "(Public key:|# public key:)" | awk '{print $(NF)}')" | ||
| age_pub2="$(mise x -- age-keygen -o "$precedence_mise_file" 2>&1 | grep -E "(Public key:|# public key:)" | awk '{print $(NF)}')" |
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.
The error in the autofix workflow is because you're evaluating both files, but you're only using the first variable.
| mise use sops age | ||
| age="$(mise x -- age-keygen 2>&1)" | ||
| age_pub="$(echo "$age" | grep "# public key:" | awk '{print $4}')" | ||
| age_pub="$(echo "$age" | grep -E "(Public key:|# public key:)" | awk '{print $(NF)}')" |
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.
I have a feeling this is slightly wrong, and is causing the age key to be duplicated and parsed twice not once.
See here how it errors because key is repeated twice with a newline:
mise x -- sops encrypt -i --age 'age1uhptxxssjextd7ycq27n7slrruv9nzlgdjfmuvc59vwyksuq93mqfdd8xj
age1uhptxxssjextd7ycq27n7slrruv9nzlgdjfmuvc59vwyksuq93mqfdd8xj' .env.jsonThe env variable $age_pub gets the wrong value here when you extract it:
age_pub='age1uhptxxssjextd7ycq27n7slrruv9nzlgdjfmuvc59vwyksuq93mqfdd8xj
age1uhptxxssjextd7ycq27n7slrruv9nzlgdjfmuvc59vwyksuq93mqfdd8xj'because your grep -E "(Public key:|# public key:)" accepts both patterns Public key: and # public key:, so both get matched.
Just revert back to the old grep "# public key:".
| age_pub="$(echo "$age" | grep -E "(Public key:|# public key:)" | awk '{print $(NF)}')" | |
| age_pub="$(echo "$age" | grep "# public key:" | awk '{print $4}')" |
Add support for SOPS_AGE_KEY_FILE and SOPS_AGE_KEY environment
variables, falling back to mise-specific settings if not set. This
improves compatibility with existing SOPS workflows without requiring
duplicate configuration.