Scripted Main (Scripts as Modules): Modulino - sgml/signature GitHub Wiki

Production‑Masquerading Workaround with Submodules, Modulinos, and Monkeypatching

A Q&A‑Formatted, Step‑by‑Step Description (No Code)


Q: What is the purpose of this pattern?

The purpose is to create a controlled workflow in which a local or CI environment can temporarily override a specific behavior in the production codebase without modifying the production code itself. The workflow allows the environment to behave as if it were production while still applying a targeted override. This enables deterministic testing, debugging, or analysis of production logic without altering the real production repository.


Q: How should the repository be structured?

  1. Create a main repository that will orchestrate the workflow.
  2. Inside this repository, create a directory dedicated to holding the production code.
  3. Configure this directory as a git submodule pointing to the real production repository.
  4. Create a separate directory for tooling, which will contain the modulino responsible for applying the override and running the behavior.
  5. Create a directory for CI configuration, such as a workflows directory, which will contain the GitHub Actions workflow definition.
  6. Ensure that each of these directories has a single, clear responsibility: production code, override logic, and CI automation.

Q: How is the production code brought into the main repository?

  1. Identify the production repository and the specific commit or branch that should be used.
  2. Add the production repository as a git submodule in the designated directory.
  3. Initialize and update the submodule so that the production code is present on disk.
  4. Treat the submodule as read‑only; do not modify files inside it.
  5. When a newer version of production is needed, update the submodule pointer rather than editing the code directly.

Q: What is the role of the modulino?

  1. The modulino is a module that can be both imported and executed directly.
  2. When imported, it defines the logic required to locate the production code and prepare the override.
  3. When executed directly, it performs the sequence of actions required to apply the override and run the behavior.
  4. It acts as the orchestrator of the workaround, ensuring that the override is applied only at runtime and only in the appropriate environment.
  5. It keeps the override logic separate from the production code, preserving the integrity of the production repository.

Q: How does the monkeypatch conceptually work?

  1. Identify the specific behavior in the production code that needs to be overridden.
  2. Define an alternative behavior that should replace the original one during execution.
  3. At runtime, before any dependent logic is executed, replace the reference to the original behavior with the alternative one.
  4. Ensure that this replacement is temporary and applies only within the current process.
  5. After execution, the production code remains unchanged on disk, and the override disappears automatically.

Q: How does localhost masquerade as production?

  1. Determine which environment variables normally indicate that the system is running in production.
  2. In the local environment configuration, set these variables to values that indicate production.
  3. Add an additional variable that explicitly marks the environment as a local masquerade rather than real production.
  4. In the modulino, read both the production indicator and the masquerade flag.
  5. Apply the override only when both conditions are satisfied.
  6. This ensures that localhost follows the production code path while still applying the override.

Q: How is the pattern executed locally?

  1. Clone the main repository onto the local machine.
  2. Initialize and update the submodule so that the production code is available.
  3. Set the environment variables to indicate production and to mark the environment as a local masquerade.
  4. Execute the modulino directly from the command line.
  5. The modulino detects the masquerading environment, applies the override, and runs the behavior.
  6. The production code remains unchanged after execution.

Q: How is the pattern executed in GitHub Actions without relying on git merge?

  1. Create a workflow file in the workflows directory of the main repository.
  2. Configure the workflow to trigger on the desired events.
  3. Add a step that checks out the main repository and initializes the submodules.
  4. Add a step that sets the environment variables to indicate production and to mark the environment as a CI masquerade.
  5. Add a step that executes the modulino.
  6. The modulino detects the masquerading environment, applies the override, and runs the behavior.
  7. The workflow does not require any merge operations, making it resilient even when merge functionality is broken.

Q: Why is this approach not a hack or an anti‑pattern?

  1. The override is isolated in a separate module and does not modify production code.
  2. The production code is treated as a read‑only dependency.
  3. The override is applied only at runtime and only in specific environments.
  4. The workflow is deterministic and reproducible.
  5. The structure respects separation of concerns.
  6. The override is reversible and leaves no persistent changes.
  7. The CI pipeline does not depend on complex git operations.
  8. The masquerading behavior is explicit and documented.
  9. The override is targeted and controlled rather than broad or hidden.
  10. The approach is safer and more auditable than modifying production code directly.

Q: What is the overall execution flow?

  1. The main repository is checked out locally or in CI.
  2. The production submodule is initialized and updated.
  3. Environment variables are set to indicate a production‑like environment and a masquerade flag.
  4. The modulino is executed.
  5. The modulino detects the masquerading environment.
  6. The modulino applies the override to the production behavior.
  7. The modulino runs the behavior using the overridden logic.
  8. The process ends, leaving the production code unchanged.

References