Skip to content

refactor(deploy): consolidate deploy creation logic - #8605

Merged
serhalp merged 2 commits into
mainfrom
serhalp/deploy-types-refactors-batch1
Oct 14, 2026
Merged

serhalp merged 2 commits into
mainfrom
serhalp/deploy-types-refactors-batch1

Conversation

@serhalp

@serhalp serhalp commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Batch 1 of 3 of follow-ups to #8599. Out of an abundance of caution, that PR was kept purely focused on type changes.

  • Create deploys through a single helper, instead of duplicating across --build and --no-build
    • Behaviour change (technically): with --build, a deploy response without an id no longer falls back to an empty-string deploy ID; the deploy ID is passed through as returned by the API, matching the --no-build path. ✅ Verified not possible in backend code.
  • Use optional chaining where we now can.
    • Behaviour change (technically): a non-object published_deploy (for example a function) with a truthy locked property now counts as locked. ✅ Verified not possible in backend code.
  • Remove optional chaining now revealed to be unnecessary.
    • Behaviour change (technically) if the types are wrong. ✅ Verified not possible in build and backend code.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 751cfe09-4670-4fcc-8347-c898b84afd07
📥 Commits

Reviewing files that changed from the base of the PR and between a5c7b12 and 95f4a8d.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 8a812efd-e6c9-44ba-b0ee-ddace78427eb
📥 Commits

Reviewing files that changed from the base of the PR and between 31ed36f and a5c7b12.

📒 Files selected for processing (2)
  • eslint-suppressions.json
  • src/commands/deploy/deploy.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

💤 Files with no reviewable changes (1)
  • eslint-suppressions.json

Included review availability: This review used your included allowance. 9 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour. Your free on-demand review promotion remains active until October 9, 2026 at 6:00 PM UTC.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Deployments now create a deploy record in both build and no-build workflows when one is not already available. Production deploys also check the deploy’s locked status before proceeding.
    • Deploy folder resolution no longer requires site data to be supplied, including for anonymous deploys. Deploy creation continues to include the applicable draft, branch, upload URL, and source details.

Deploy site data handling now uses optional folder-helper inputs and direct property access. A new helper centralizes production preparation and deploy creation. Both the no-build and build paths use it. Deploy creation no longer receives options.message as a title, and the TypeScript lint suppression for deploy.ts was removed.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Refactor

Suggested reviewers: ndhoule

Merge Risk: ⚪ Minimal · up to a5c7b

No merge-blocking issue was established; deploy messages still reach deploy creation.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: consolidating deploy creation logic across deployment paths.
Description check Passed The description is directly related to the changeset and explains the deploy helper consolidation, optional-chaining changes, and reported behavior changes.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

📊 Benchmark results

Comparing with 336e09e

  • Dependency count: 1,019 (no change)
  • Package size: 380 MB (no change)
  • Number of ts-expect-error directives: 280 (no change)

@pkg-pr-new

pkg-pr-new Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/netlify-cli@8605

commit: 95f4a8d

- Create deploys through a single helper, instead of duplicating across `--build` and `--no-build`
  - Behaviour change (technically): with `--build`, a deploy response without an `id` no longer
    falls back to an empty-string deploy ID; the deploy ID is passed through as returned by the API,
    matching the `--no-build` path.
- Use optional chaining where we now can.
  - Behaviour change (technically): a non-object `published_deploy` (for example a
    function) with a truthy `locked` property now counts as locked.
- Remove optional chaining now revealed to be unnecessary.
  - Behaviour change (technically) if the types are wrong (they aren't).
@serhalp
serhalp force-pushed the serhalp/deploy-types-refactors-batch1 branch from d5abf07 to a5c7b12 Compare October 9, 2026 17:28
@serhalp
serhalp marked this pull request as ready for review October 9, 2026 17:41
@serhalp
serhalp requested a review from a team as a code owner October 9, 2026 17:41
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@serhalp
serhalp enabled auto-merge (squash) October 14, 2026 14:09
@serhalp
serhalp merged commit 04f0868 into main Oct 14, 2026
37 checks passed
@serhalp
serhalp deleted the serhalp/deploy-types-refactors-batch1 branch October 14, 2026 14:17
serhalp added a commit that referenced this pull request Oct 16, 2026
Batch 2 of 3 of follow-ups to #8599 (batch 1 here: #8605). Out of an abundance of caution, that PR was kept purely focused on type changes.

- Drop runtime checks for options the types now require
- Remove the unused `assetType` option from file hashing
- Only upload in-memory bodies for static files
  - Every upload built its body with `body ?? fs.createReadStream(filepath)`, although only the
    generated `netlify.toml` (an `InlineUploadFile`) ever carries an in-memory body. Static files
    still upload their inline `body` when present and stream `filepath` otherwise; functions, edge
    functions and servers now always stream from `filepath`.
- Build the functions config with `Object.fromEntries`
  - The per-function config payload sent to the API was accumulated with a spreading `reduce`. It is
    now built by a named `toFunctionConfigPayload` mapper and `Object.fromEntries`, which also gives
    the payload a derived type.
serhalp added a commit that referenced this pull request Oct 16, 2026
Batch 2 of 3 of follow-ups to #8599 (batch 1 here: #8605). Out of an abundance of caution, that PR was kept purely focused on type changes.

- Drop runtime checks for options the types now require
- Remove the unused `assetType` option from file hashing
- Only upload in-memory bodies for static files
  - Every upload built its body with `body ?? fs.createReadStream(filepath)`, although only the
    generated `netlify.toml` (an `InlineUploadFile`) ever carries an in-memory body. Static files
    still upload their inline `body` when present and stream `filepath` otherwise; functions, edge
    functions and servers now always stream from `filepath`.
- Build the functions config with `Object.fromEntries`
  - The per-function config payload sent to the API was accumulated with a spreading `reduce`. It is
    now built by a named `toFunctionConfigPayload` mapper and `Object.fromEntries`, which also gives
    the payload a derived type.
serhalp added a commit that referenced this pull request Oct 16, 2026
Batch 3 of 3 of follow-ups to #8599 ([batch 1](#8605), [batch 2](#8626)). Out of an abundance of caution, that PR was kept purely focused on type changes.

- Share one poller between `waitForDiff` and `waitForDeploy` instead of duplicating code
- Resolve the drop deploy poll with the ready deploy
  - `waitForDropDeploy` captured the ready deploy in an outer variable and returned it with a
    non-null assertion after polling. The poll now resolves with it directly via
    `pWaitFor.resolveWith`.
- Rethrow the final drop upload error from inside the retry loop
  - The drop file upload retry loop remembered the last error, skipped the backoff on the final
    attempt, and threw the remembered error after the loop. It now throws directly on a permanent
    failure or on the last attempt, and otherwise backs off and retries. The status is read through
    an `instanceof Error` guard instead of a cast.
- Don't return the upload promise to the backoff emitter. It wasn't used, resulting in lint errors
  about promise misuse.
serhalp added a commit that referenced this pull request Oct 16, 2026
Batch 2 of 3 of follow-ups to #8599 (batch 1 here: #8605). Out of an abundance of caution, that PR was kept purely focused on type changes.

- Drop runtime checks for options the types now require
- Remove the unused `assetType` option from file hashing
- Only upload in-memory bodies for static files
  - Every upload built its body with `body ?? fs.createReadStream(filepath)`, although only the
    generated `netlify.toml` (an `InlineUploadFile`) ever carries an in-memory body. Static files
    still upload their inline `body` when present and stream `filepath` otherwise; functions, edge
    functions and servers now always stream from `filepath`.
- Build the functions config with `Object.fromEntries`
  - The per-function config payload sent to the API was accumulated with a spreading `reduce`. It is
    now built by a named `toFunctionConfigPayload` mapper and `Object.fromEntries`, which also gives
    the payload a derived type.
serhalp added a commit that referenced this pull request Oct 16, 2026
Batch 3 of 3 of follow-ups to #8599 ([batch 1](#8605), [batch 2](#8626)). Out of an abundance of caution, that PR was kept purely focused on type changes.

- Share one poller between `waitForDiff` and `waitForDeploy` instead of duplicating code
- Resolve the drop deploy poll with the ready deploy
  - `waitForDropDeploy` captured the ready deploy in an outer variable and returned it with a
    non-null assertion after polling. The poll now resolves with it directly via
    `pWaitFor.resolveWith`.
- Rethrow the final drop upload error from inside the retry loop
  - The drop file upload retry loop remembered the last error, skipped the backoff on the final
    attempt, and threw the remembered error after the loop. It now throws directly on a permanent
    failure or on the last attempt, and otherwise backs off and retries. The status is read through
    an `instanceof Error` guard instead of a cast.
- Don't return the upload promise to the backoff emitter. It wasn't used, resulting in lint errors
  about promise misuse.
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