Skip to content

feat: add env-file and env-from support for all job types#540

Merged
CybotTM merged 4 commits intomainfrom
feat/env-file-env-from
Mar 22, 2026
Merged

feat: add env-file and env-from support for all job types#540
CybotTM merged 4 commits intomainfrom
feat/env-file-env-from

Conversation

@CybotTM
Copy link
Copy Markdown
Member

@CybotTM CybotTM commented Mar 21, 2026

Summary

Adds two new configuration options for loading environment variables from external sources, available on all job types (exec, run, local, service-run):

  • env-file: Load KEY=VALUE pairs from files (like Docker's --env-file). Supports multiple files via INI shadow keys or JSON arrays in Docker labels.
  • env-from: Copy environment variables from a running Docker container at job execution time.

Merge order (last wins): env-file < env-from < environment (explicit always wins).

Example (INI config)

[job-run "backup"]
schedule = @daily
image = alpine
env-file = /config/db.env
env-file = /config/app.env
env-from = my-app-container
environment = OVERRIDE=explicit
command = backup.sh

Example (Docker labels)

labels:
  ofelia.job-run.backup.schedule: "@daily"
  ofelia.job-run.backup.image: "alpine"
  ofelia.job-run.backup.env-file: "/config/db.env"
  ofelia.job-run.backup.env-from: "my-app-container"
  ofelia.job-run.backup.command: "backup.sh"

Design decisions

  • Idempotent: j.Environment is never mutated — ResolveJobEnvironment() returns a fresh merged slice each run, safe for cron-scheduled jobs
  • Narrow interface: ContainerInspector interface (satisfied by DockerProvider) instead of coupling to full provider
  • LocalJob graceful degradation: env-from logs a warning and is skipped (no Docker provider available)
  • env-file parser: Handles comments, blank lines, quoted values, export prefix, and special characters (#, ;) in values

Test plan

  • 22 unit tests for ParseEnvFile, MergeEnvironments, ResolveEnvFrom, ResolveJobEnvironment
  • 3 integration tests for INI config parsing with shadow keys, env-from, and combined usage
  • Full test suite passes (all packages)
  • CI passes

Closes #314
Closes #336
Closes #351

Copilot AI review requested due to automatic review settings March 21, 2026 23:17
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 21, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the configuration capabilities of Ofelia by adding support for loading environment variables from external sources. This change provides users with more flexibility in managing environment variables for their jobs, making it easier to configure and deploy applications. The implementation includes thorough testing and considers various design aspects such as idempotency and graceful degradation.

Highlights

  • Environment Variable Loading: This PR introduces the ability to load environment variables from external files (env-file) and copy them from running Docker containers (env-from) for all job types.
  • Configuration Options: Two new configuration options, env-file and env-from, are added to the job configurations, allowing for more flexible environment management.
  • Merge Order: The merge order for environment variables is defined as env-file < env-from < environment, ensuring that explicitly defined variables always take precedence.
  • Testing: Comprehensive unit and integration tests have been added to ensure the correct functionality of the new features.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 21, 2026

✅ Mutation Testing Results

Mutation Score: 87.18% (threshold: 60%)

✨ Good job! Mutation score meets the threshold.

What is mutation testing?

Mutation testing measures test quality by introducing small changes (mutations) to the code and checking if tests detect them. A higher score means better test effectiveness.

  • Killed mutants: Tests caught the mutation (good!)
  • Survived mutants: Tests missed the mutation (needs improvement)

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances job configuration by introducing env-file and env-from options, allowing environment variables to be loaded from .env files and inherited from other Docker containers, respectively. Core logic for parsing .env files, resolving container environments, and merging these sources with explicit environment variables was added in core/envfile.go, along with comprehensive unit and integration tests. The job execution mechanisms across execjob.go, localjob.go, runjob.go, and runservice.go were updated to incorporate this new environment resolution. A review comment identified a bug in the ParseEnvFile function, noting that lines starting with an equals sign are currently parsed incorrectly and should be skipped to match Docker's behavior.

Copy link
Copy Markdown

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

Adds support for loading job environments from external sources across Ofelia job types, enabling env-file (dotenv-style files) and env-from (copy env from a running container) with defined merge precedence.

Changes:

  • Introduces ResolveJobEnvironment with helpers to parse env files, resolve env from containers, and merge sources with last-wins semantics.
  • Wires env-file/env-from into exec/run/service-run/local job execution paths.
  • Extends Docker label decoding and adds unit/integration tests for parsing/decoding behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
core/runservice.go Uses resolved merged environment when creating service specs.
core/runjob.go Uses resolved merged environment when building container configs.
core/localjob.go Resolves env sources for local jobs (with warning-only behavior for env-from).
core/execjob.go Resolves env sources for exec jobs in both Run and RunWithStreams.
core/envfile.go Adds env-file parsing, env-from resolution via container inspection, and merge logic.
core/envfile_test.go Unit tests for ParseEnvFile/MergeEnvironments/ResolveEnvFrom/ResolveJobEnvironment.
config/validator.go Marks env-file / env-from as optional fields (validator allowlist).
cli/envfile_integration_test.go Integration tests ensuring INI decoding supports shadow keys and env-from.
cli/docker-labels.go Extends label param handling to accept JSON arrays for env-file/env-from.

@CybotTM CybotTM force-pushed the feat/env-file-env-from branch from bb3e745 to 9eb9704 Compare March 21, 2026 23:27
github-actions[bot]
github-actions bot previously approved these changes Mar 21, 2026
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

github-actions[bot]
github-actions bot previously approved these changes Mar 21, 2026
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

github-actions[bot]
github-actions bot previously approved these changes Mar 21, 2026
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

CybotTM added 4 commits March 22, 2026 15:24
Add two new configuration options for loading environment variables
from external sources, available on all job types (exec, run, local,
service-run):

- env-file: Load KEY=VALUE pairs from files (like Docker --env-file).
  Supports multiple files via INI shadow keys or JSON arrays in labels.
  Handles comments, blank lines, quoted values, export prefix, and
  special characters (#, ;) in values.

- env-from: Copy environment variables from a running Docker container
  at job execution time. For local jobs, warns and skips gracefully.

Merge order (last wins): env-file < env-from < environment (explicit).

Environment resolution is idempotent — the original Environment field
is never mutated, so cron-scheduled jobs resolve fresh each run.

Closes #314
Closes #336
Closes #351

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
- Skip lines with empty key (e.g., "=value") matching Docker behavior
- Increase scanner buffer to 1MB for long values (certs, JSON blobs)
- Add nil-provider guard to exported ResolveEnvFrom
- Add tests for empty key and nil provider cases

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
- Add #nosec G304 for intentional user-configured file path in ParseEnvFile
- Use static sentinel ErrNilContainerInspector instead of dynamic error
- Fix gci import group ordering (stdlib / third-party / project)

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
The standalone gosec CLI does not recognize //nolint:gosec directives
(those are golangci-lint specific). Use // #nosec G304 which is the
standard gosec suppression format used throughout the codebase.

Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
@CybotTM CybotTM force-pushed the feat/env-file-env-from branch from ca5699e to 32e5507 Compare March 22, 2026 14:24
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Automated approval for solo maintainer project

All CI checks passed. See SECURITY.md for compensating controls.

@CybotTM CybotTM added this pull request to the merge queue Mar 22, 2026
Merged via the queue into main with commit 3a56104 Mar 22, 2026
29 checks passed
@CybotTM CybotTM deleted the feat/env-file-env-from branch March 22, 2026 14:32
@CybotTM CybotTM mentioned this pull request Mar 22, 2026
github-merge-queue bot pushed a commit that referenced this pull request Mar 22, 2026
## Summary

Release v0.23.0 with CHANGELOG update.

### Added
- `env-file`: load environment variables from files for all job types
(#540, closes #314)
- `env-from`: copy environment variables from a running container (#540,
closes #336, #351)

### Fixed
- `#`/`;` in env-substituted values truncated by INI comment parsing
(#539, fixes #538)
- Env expansion in webhook configs, section names, and log-level
pre-parse (#539)

### Security
- SHA-pin all GitHub Actions (#536)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants