Skip to content

Conversation

@yordis
Copy link
Contributor

@yordis yordis commented Dec 20, 2025

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.

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.
@yordis yordis marked this pull request as ready for review December 20, 2025 01:37
Copilot AI review requested due to automatic review settings December 20, 2025 01:37

```
$ mise tasks add test -- echo 'running tests'
$ mise task add test -- echo 'running tests'
Copy link
Contributor Author

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

Copy link
Contributor

Copilot AI left a 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.
Copy link

Copilot AI Dec 20, 2025

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."

Copilot uses AI. Check for mistakes.
# Execute multiple tasks each with their own arguments.
$ mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2
$ mise tasks cmd1 arg1 arg2 ::: cmd2 arg1 arg2
Copy link

Copilot AI Dec 20, 2025

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.

Suggested change
$ mise tasks cmd1 arg1 arg2 ::: cmd2 arg1 arg2
$ mise run cmd1 arg1 arg2 ::: cmd2 arg1 arg2

Copilot uses AI. Check for mistakes.
### `-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
Copy link

Copilot AI Dec 20, 2025

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
Comment on lines +1151 to +1155
"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.",
Copy link

Copilot AI Dec 20, 2025

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."

Copilot uses AI. Check for mistakes.
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"
Copy link

Copilot AI Dec 20, 2025

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.

Suggested change
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"

Copilot uses AI. Check for mistakes.
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"
Copy link

Copilot AI Dec 20, 2025

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.

Suggested change
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"

Copilot uses AI. Check for mistakes.
- **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
Copy link

Copilot AI Dec 20, 2025

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.

Suggested change
Edit a tasks with $EDITOR
Edit a task with $EDITOR

Copilot uses AI. Check for mistakes.
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 {
Copy link

Copilot AI Dec 20, 2025

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.

Suggested change
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 {

Copilot uses AI. Check for mistakes.
- `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):**
Copy link

Copilot AI Dec 20, 2025

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.

Suggested change
**Mise-specific variables (override standard ones if both are set):**
**Mise-specific variables (used as fallbacks if standard ones are not set):**

Copilot uses AI. Check for mistakes.
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"
Copy link

Copilot AI Dec 20, 2025

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."

Suggested change
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"

Copilot uses AI. Check for mistakes.
@yordis yordis marked this pull request as draft December 20, 2025 01:47
@yordis
Copy link
Contributor Author

yordis commented Dec 20, 2025

@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)}')"

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)}')"

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.json

The 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:".

Suggested change
age_pub="$(echo "$age" | grep -E "(Public key:|# public key:)" | awk '{print $(NF)}')"
age_pub="$(echo "$age" | grep "# public key:" | awk '{print $4}')"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants