Skip to content

High billing consumption generated by installing DDEV with github-action-setup-ddev #42

@mxr576

Description

@mxr576

As it was reported on Drupal Slack, installing DDEV with this GitHub Action could lead to unexpectedly high (1-7 minutes) GitHub Action minutes consumption in random cases.

I think this problem is also visible on this project.

Proof:

The actual command execution completes in ~3 seconds, but GitHub Actions bills for 1-2 minutes due to infrastructure overhead from multiple shell process spawns.

RCA:
TL;DR sudo apt install command MUST BE avoid on GHA because that is a real time-consumer that randomly increases your billed hours.

Expected Impact:

  • Billing reduction: 2 minutes → 1 minute (~50% cost reduction)
  • Execution time: Reduced process overhead from 60-90s to 5-10s
  • Reliability: Maintained backward compatibility and error handling
  • Developer experience: No workflow changes required
Outdated RCA & Proposed solution

Root Cause Analysis:

The current main.js implementation creates significant overhead through:

  1. 8 separate execShellCommand() calls - each spawning individual shell processes
  2. Sequential execution pattern - preventing command optimization
  3. Process initialization overhead - 60-90 seconds of cumulative overhead across spawns
  4. Ubuntu runner variability - apt operations timing inconsistencies between 20s-2min

Proposed Solution: Optimize main.js execution pattern

Technique 1: Command Batching
Combine related shell operations to reduce process spawning from 8 to 3-5 executions:

// Batch repository setup and installation (5 commands → 1 execution)
const setupCommands = [
  'sudo install -m 0755 -d /etc/apt/keyrings',
  'curl -fsSL https://pkg.ddev.com/apt/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/ddev.gpg > /dev/null',
  'sudo chmod a+r /etc/apt/keyrings/ddev.gpg',
  'echo "deb [signed-by=/etc/apt/keyrings/ddev.gpg] https://pkg.ddev.com/apt/ * *" | sudo tee /etc/apt/sources.list.d/ddev.list >/dev/null',
  `(sudo apt-get update || true) && sudo apt-get install -y ${ddevPackage} && mkcert -install`
];

yield execBatchCommands(setupCommands, "DDEV repository setup and installation");

Technique 2: Optimized Process Spawning
Replace individual shell spawns with batch execution using bash -c:

function execBatchCommands(commands, description) {
  return new Promise((resolve, reject) => {
    const batchCmd = commands.join(' && ');
    const process = child_process_1.spawn('bash', ['-c', batchCmd]);
    // ... error handling
  });
}

Technique 3: Strategic Error Isolation
Maintain separate executions only for operations requiring error isolation:

  • Version hold operations (if version ≠ latest)
  • Autostart with directory context
  • Critical configuration steps

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions