Skip to content

fix(apphosting): remove colliding -i flag and support --id option in builds:create - #11084

Open
Noxtimo wants to merge 1 commit into
firebase:mainfrom
Noxtimo:fix/apphosting-builds-create-id
Open

fix(apphosting): remove colliding -i flag and support --id option in builds:create#11084
Noxtimo wants to merge 1 commit into
firebase:mainfrom
Noxtimo:fix/apphosting-builds-create-id

Conversation

@Noxtimo

@Noxtimo Noxtimo commented Sep 12, 2026

Copy link
Copy Markdown

Description

In firebase apphosting:builds:create, the build ID option was declared as -i, --id <buildId>. However, -i, --interactive is globally registered across all CLI commands in src/index.ts. Passing -i <buildId> caused Commander to parse -i as the boolean --interactive flag, leaving the build ID argument unconsumed.

Additionally, Commander populates options.id for --id <buildId>, but the command action was reading options.buildId. As a result, user-specified build IDs passed via --id were silently ignored in favor of an autogenerated ID.

This change removes the conflicting -i short flag (following the convention in #11057) and resolves (options.id as string) || (options.buildId as string) so custom build IDs are correctly applied.

Scenarios Tested

  • Verified apphosting:builds:create does not register the conflicting -i short flag.
  • Verified apphosting:builds:create continues to autogenerate a build ID when --id is omitted.
  • Verified apphosting:builds:create respects custom build IDs passed via --id <buildId>.
  • Verified apphosting:builds:create respects options.buildId for programmatic usage.
  • Ran Mocha unit tests: npx mocha src/commands/apphosting-builds-create.spec.ts (4/4 passing).
  • Ran lint and type compilation: npm run lint:changed-files and npm run test:compile (both passed cleanly).

Sample Commands

firebase apphosting:builds:create my-backend --id custom-build-123

…builds:create

### Description
In `firebase apphosting:builds:create`, the build ID option was declared as `-i, --id <buildId>`. However, `-i, --interactive` is globally registered across all CLI commands in `src/index.ts`. Passing `-i <buildId>` caused Commander to parse `-i` as the boolean `--interactive` flag, leaving the build ID argument unconsumed.

Additionally, Commander populates `options.id` for `--id <buildId>`, but the command action was reading `options.buildId`. As a result, user-specified build IDs passed via `--id` were silently ignored in favor of an autogenerated ID.

This change removes the conflicting `-i` short flag (following the convention in firebase#11057) and resolves `(options.id as string) || (options.buildId as string)` so custom build IDs are correctly applied.

### Scenarios Tested
- Verified apphosting:builds:create does not register the conflicting -i short flag.
- Verified apphosting:builds:create continues to autogenerate a build ID when --id is omitted.
- Verified apphosting:builds:create respects custom build IDs passed via --id <buildId>.
- Verified apphosting:builds:create respects options.buildId for programmatic usage.
- Ran Mocha unit tests: npx mocha src/commands/apphosting-builds-create.spec.ts (4/4 passing).
- Ran lint and type compilation: npm run lint:changed-files and npm run test:compile (both passed cleanly).

### Sample Commands
firebase apphosting:builds:create my-backend --id custom-build-123

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

Copy link
Copy Markdown
Contributor

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 fixes the --id option in the apphosting:builds:create command by removing the conflicting -i short flag and updating the build ID resolution logic to respect the --id option. It also introduces comprehensive unit tests for these changes. The review feedback recommends avoiding as unknown as type casting by defining a proper interface extending Command to align with the repository style guide, and suggests using a regular expression for a more robust check of the short flag in tests.

Comment on lines +3 to +18
import { Command } from "../command";
import { command as apphostingBuildsCreate } from "./apphosting-builds-create";
import * as apphosting from "../gcp/apphosting";

describe("apphosting:builds:create", () => {
const PROJECT_ID = "test-project";
const BACKEND_ID = "test-backend";
const LOCATION = "us-central1";

let command: Command;
let getNextRolloutIdStub: sinon.SinonStub;
let createBuildStub: sinon.SinonStub;

beforeEach(() => {
command = apphostingBuildsCreate;
(command as unknown as { befores: unknown[] }).befores = []; // Bypass pre-action hooks for unit testing action

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Avoid using as unknown as as an escape hatch to access private/internal properties of Command. Instead, define a proper interface extending Command to cleanly type the internal properties we need to mock or inspect in tests, adhering to the repository style guide.

import { Command } from "../command";
import { command as apphostingBuildsCreate } from "./apphosting-builds-create";
import * as apphosting from "../gcp/apphosting";

interface TestCommand extends Command {
  befores: unknown[];
  options: string[][];
}

describe("apphosting:builds:create", () => {
  const PROJECT_ID = "test-project";
  const BACKEND_ID = "test-backend";
  const LOCATION = "us-central1";

  let command: TestCommand;
  let getNextRolloutIdStub: sinon.SinonStub;
  let createBuildStub: sinon.SinonStub;

  beforeEach(() => {
    command = apphostingBuildsCreate as TestCommand;
    command.befores = []; // Bypass pre-action hooks for unit testing action
References
  1. Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards. (link)

Comment on lines +30 to +32
const options = (command as unknown as { options: string[][] }).options;
const hasConflictingShortFlag = options.some((opt) => opt[0].startsWith("-i,"));
expect(hasConflictingShortFlag).to.be.false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using the typed TestCommand interface allows us to access options directly without casting. Additionally, checking for the short flag using a regular expression is more robust than startsWith("-i,") as it correctly handles cases where the short flag might be defined without a comma (e.g., "-i <buildId>").

Suggested change
const options = (command as unknown as { options: string[][] }).options;
const hasConflictingShortFlag = options.some((opt) => opt[0].startsWith("-i,"));
expect(hasConflictingShortFlag).to.be.false;
const options = command.options;
const hasConflictingShortFlag = options.some((opt) => /(?:^|\s)-i\b/.test(opt[0]));
expect(hasConflictingShortFlag).to.be.false;
References
  1. Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards. (link)

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