Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
+137
View File
@@ -0,0 +1,137 @@
name: Bug Report
description: "Found a bug? Please search through our open issues and docs, to make sure it isn't already submitted. If you have an SSH related issue, please use the SSH Template below"
labels: ["bug", "ready-to-implement"]
body:
- type: checkboxes
attributes:
label: "Pre-submit Checks"
options:
- label: "I have [searched Warp bugs](https://github.com/warpdotdev/warp/issues?q=is%3Aissue+label%3ABUG) and there are no duplicates"
required: true
- label: "I have [searched Warp known issues page](https://docs.warp.dev/help/known-issues) and my issue is not there"
required: true
- label: "I have an issue with AI and have included the debugging ID (Optional, but helps expedite the AI quality fix). [Debugging ID instructions](https://docs.warp.dev/agent-platform/agent/ai-faqs#gathering-ai-debugging-id)"
required: false
- label: "I have technical issue and have included the logs (optional, but helps expedite the bug fix). [Log instructions](https://docs.warp.dev/support-and-community/troubleshooting-and-support/sending-us-feedback#gathering-warp-logs)"
required: false
- type: textarea
id: "describe-the-bug"
attributes:
label: "Describe the bug"
description: "A clear and concise description of what the bug is."
placeholder: Tell us what you see.
validations:
required: true
- type: textarea
id: "to-reproduce"
attributes:
label: "To reproduce"
description: "Bug reports with clear reproduction will get prioritized higher and addressed more quickly."
placeholder: "Steps to reproduce: 1. Go to '...' 2. Click on '...' 3. Scroll down to '...' 4. See error '...'"
validations:
required: true
- type: textarea
id: "expected-behavior"
attributes:
label: "Expected behavior"
description: "A clear and concise description of what you expected to happen."
placeholder: Tell us what you expect to see.
validations:
required: false
- type: textarea
id: "screenshots-logs"
attributes:
label: "Screenshots, videos, and logs"
description: "If applicable, add screenshots/videos/logs to help us understand your problem. While optional, these help expedite the time in which your bug is addressed."
validations:
required: false
- type: dropdown
id: "os"
attributes:
label: "Operating system (OS)"
multiple: false
options:
- "Select an OS"
- macOS
- Linux
- Windows
validations:
required: true
- type: input
id: "os-version"
attributes:
label: "Operating system and version"
description: "For example: Debian 11.2"
validations:
required: true
- type: input
id: "local-shell-version"
attributes:
label: "Shell Version"
description: "For example, `bash 4.0` e.g. Run `bash --version` or `zsh --version`"
validations:
required: false
- type: input
id: "warp-version"
attributes:
label: "Current Warp version"
description: "Open the Settings Dialog (CMD-,) using the Command Palette or by clicking the three dots > Settings > Account. Once you're on the Account page click the copy icon that's to the right of the version number. `v0.2047.04.07.47.47.stable_47`"
validations:
required: false
- type: dropdown
id: "regression"
attributes:
label: "Regression"
description: "Is this a regression (used to work in a previous Warp version)?"
multiple: false
options:
- "No, this bug or issue has existed throughout my experience using Warp"
- "Yes, this bug started recently or with an X Warp version"
validations:
required: true
- type: input
id: "warp-version-regression-date"
attributes:
label: "Recent working Warp date"
description: "Most recent date that Warp worked as expected"
validations:
required: false
- type: textarea
id: "additional-context"
attributes:
label: "Additional context"
description: "Add any other context about the problem here. If using Warp on Linux, tell us if you're using X11 or Wayland. If the issue is graphical, run Warp with the following command `RUST_LOG=wgpu_core=info,wgpu_hal=info MESA_DEBUG=1 EGL_LOG_LEVEL=debug warp-terminal` attach logs and tell us the result of `eglinfo`."
validations:
required: false
- type: dropdown
id: "blocker"
attributes:
label: "Does this block you from using Warp daily?"
description: "All feedback will be reviewed, even if you select 'No'."
multiple: false
options:
- "No"
- "Yes, this issue prevents me from using Warp daily."
validations:
required: true
- type: dropdown
id: "terminals"
attributes:
label: "Is this an issue only in Warp?"
description: "Verifying this issue doesn't happen in other terminals helps us to prioritize the fix"
multiple: false
options:
- "Yes, I confirmed that this only happens in Warp, not other terminals."
- "No, this issue happens in Warp and other terminals."
validations:
required: true
- type: dropdown
id: "linear-label-bug"
attributes:
label: "Warp Internal (ignore): linear-label:b9d78064-c89e-4973-b153-5178a31ee54e"
multiple: false
options:
- Ignore
validations:
required: false
@@ -0,0 +1,68 @@
name: Feature Request
description: "Have a great new idea? Please search through our existing feature requests, and upvote it if it's already exists."
labels: ["enhancement"]
body:
- type: checkboxes
attributes:
label: "Pre-submit Checks"
options:
- label: "I have [searched Warp feature requests](https://github.com/warpdotdev/warp/issues?q=is%3Aissue+label%3AFEATURE) and there are no duplicates"
required: true
- label: "I have [searched Warp docs](https://docs.warp.dev) and my feature is not there"
required: true
- type: textarea
id: "describe-solution"
attributes:
label: "Describe the solution you'd like?"
description: "A clear and concise description of what you want to happen."
validations:
required: true
- type: textarea
id: "related-to-problem"
attributes:
label: "Is your feature request related to a problem? Please describe."
description: "A clear and concise description of what the problem is."
placeholder: "I'm always frustrated when [...]"
validations:
required: false
- type: textarea
id: "additional-context"
attributes:
label: "Additional context"
description: "Add any other context or screenshots about the feature request here. If you want to upload a picture you can drag one in from Finder."
validations:
required: false
- type: dropdown
id: "os"
attributes:
label: "Operating system (OS)"
multiple: false
options:
- "Select an OS"
- macOS
- Linux
- Windows
validations:
required: true
- type: dropdown
id: "importance"
attributes:
label: "How important is this feature to you?"
multiple: false
options:
- "1 (Not too important)"
- "2"
- "3"
- "4"
- "5 (Can't work without it!)"
validations:
required: true
- type: dropdown
id: "linear-label-feature"
attributes:
label: "Warp Internal (ignore) - linear-label:39cc6478-1249-4ee7-950b-c428edfeecd1"
multiple: false
options:
- Ignore
validations:
required: false
+73
View File
@@ -0,0 +1,73 @@
name: SSH Warpify Issues? Use this template
description: "Issue template specialized for the circumstances where SSH Warpification with tmux fails"
labels: ["bug","area:ssh"]
body:
- type: checkboxes
attributes:
label: "Pre-submit Checks"
options:
- label: "I have [searched Warp SSH issues](https://github.com/warpdotdev/Warp/issues?q=is%3Aissue+is%3Aopen+label%3ASSH-TMUX) and there are no duplicates"
required: true
- label: "I have [searched Warp known issues page](https://docs.warp.dev/help/known-issues) and my issue is not there"
required: true
- label: "I have technical issue and have included the logs (helps expedite the bug fix). [Log instructions](https://docs.warp.dev/support-and-community/troubleshooting-and-support/sending-us-feedback#gathering-warp-logs)"
required: false
- type: textarea
id: "shell-output"
attributes:
label: "Include shell output"
description: "Click on the top right icon of your terminal block, select `Copy`, and paste the contents here. Please redact any personal details."
render: shell
validations:
required: true
- type: textarea
id: "screenshots-logs"
attributes:
label: "Screenshots, videos, and logs"
description: "If applicable, add screenshots/videos/logs to help us understand your problem. While optional, these help expedite the time in which your bug is addressed."
validations:
required: false
- type: dropdown
id: "os"
attributes:
label: "Operating system (OS)"
multiple: false
options:
- "Select an OS"
- macOS
- Linux
- Windows
validations:
required: true
- type: input
id: "os-version"
attributes:
label: "Operating system and version"
description: "For example: Debian 11.2"
validations:
required: true
- type: input
id: "warp-version"
attributes:
label: "Warp Version"
description: "Warp Version"
validations:
required: false
- type: dropdown
id: "linear-label-ssh-tmux"
attributes:
label: "Warp Internal (ignore) - linear-label:7a739baa-09c3-499e-a0c9-a1a16c090597"
multiple: false
options:
- Ignore
validations:
required: false
- type: dropdown
id: "linear-label-bug"
attributes:
label: "Warp Internal (ignore): linear-label:b8107fdf-ba31-488d-b103-d271c89cac3e"
multiple: false
options:
- Ignore
validations:
required: false
+115
View File
@@ -0,0 +1,115 @@
name: Legacy SSH Issues? Use this template
description: "(Legacy) Issue template specialized for the circumstances where the shell doesn't bootstrap as a subshell over SSH"
labels: ["bug","area:ssh"]
body:
- type: checkboxes
attributes:
label: "Pre-submit Checks"
options:
- label: "I have [searched Warp SSH issues](https://github.com/warpdotdev/Warp/issues?q=is%3Aissue+is%3Aopen+label%3ASSH) and there are no duplicates"
required: true
- label: "I have [searched Warp known issues page](https://docs.warp.dev/help/known-issues) and my issue is not there"
required: true
- label: "I have technical issue and have included the logs (helps expedite the bug fix). [Log instructions](https://docs.warp.dev/support-and-community/troubleshooting-and-support/sending-us-feedback#gathering-warp-logs)"
required: false
- type: dropdown
id: "os"
attributes:
label: "Operating system (OS)"
multiple: false
options:
- "Select an OS"
- macOS
- Linux
- Windows
validations:
required: true
- type: input
id: "os-version"
attributes:
label: "Operating System and Version"
description: "For example: Debian 11.2"
validations:
required: true
- type: input
id: "local-shell-version"
attributes:
label: "Local Shell Version"
description: "Output of `echo $BASH_VERSION` or `echo $ZSH_VERSION`"
validations:
required: true
- type: input
id: "remote-shell-version"
attributes:
label: "Remote Shell Version"
description: "Output of `echo $BASH_VERSION` or `echo $ZSH_VERSION`"
validations:
required: true
- type: input
id: "warp-version"
attributes:
label: "Warp Version"
description: "Click the 3-dots menu docked to the right of the tabs in Warp and click the copy button, e.g. `v0.2022.05.30.09.10.stable_01`"
validations:
required: true
- type: checkboxes
id: "rcfiles"
attributes:
label: "Have you tried commenting out my system & user rc files?"
description: "If the issue is with your system and user rc files, please isolate the issue by [debugging your rc files](https://docs.warp.dev/help/known-issues#configuring-and-debugging-your-rc-files)."
options:
- label: "Yes"
- type: textarea
id: "screenshots-logs"
attributes:
label: "Screenshots, videos, and logs"
description: "If applicable, add screenshots/videos/logs to help us understand your problem. While optional, these help expedite the time in which your bug is addressed."
validations:
required: false
- type: textarea
id: "xtrace-output"
attributes:
label: "Include shell xtrace output"
description: "1. Ensure you're on the 3.31 version of Warp or later. 2. Run WARP_DEBUG_MODE=1 ssh YOUR-HOSTNAME-HERE 3. Save the full output starting from the ssh command block. If youre not comfortable posting the outputs to a public issue, you can email feedback@warp.dev. "
validations:
required: true
- type: dropdown
id: "blocker"
attributes:
label: "Does this block you from using Warp daily?"
description: "All feedback will be reviewed, even if you select 'No'."
multiple: false
options:
- "No"
- "Yes, this issue prevents me from using Warp daily."
validations:
required: true
- type: dropdown
id: "terminals"
attributes:
label: "Is this an issue only in Warp?"
description: "Verifying this issue doesn't happen in other terminals helps us to prioritize the fix"
multiple: false
options:
- "Yes, I confirmed that this only happens in Warp, not other terminals."
- "No, this issue happens in Warp and other terminals."
validations:
required: true
- type: dropdown
id: "linear-label-ssh"
attributes:
label: "Warp Internal (ignore) - linear-label:e7dfaa84-5fdb-4a00-b754-d8912da923fa"
multiple: false
options:
- Ignore
validations:
required: false
- type: dropdown
id: "linear-label-bug"
attributes:
label: "Warp Internal (ignore): linear-label:b8107fdf-ba31-488d-b103-d271c89cac3e"
multiple: false
options:
- Ignore
validations:
required: false
+26
View File
@@ -0,0 +1,26 @@
blank_issues_enabled: false
contact_links:
- name: Warp GitHub Search
url: https://github.com/warpdotdev/warp/issues?q=is%3Aissue+is%3Aopen+a+sort%3Areactions-%2B1-desc
about: Search Warp's open bugs and enhancements.
- name: Warp Documentation
url: https://docs.warp.dev/support-and-billing/known-issues?q=
about: Documentation for features, known issues, troubleshooting, keyboard shortcuts, telemetry table, and more!
- name: Warp Changelog
url: https://docs.warp.dev/changelog
about: See our changelog to learn about new features, improvements, bug fixes, and Oz updates.
- name: Contact Us
url: https://docs.warp.dev/support-and-community/troubleshooting-and-support/sending-us-feedback
about: Submit feedback and contact the Warp support team for things like Billing, Enterprise, and other issues.
- name: Warp Preview Slack Community
url: https://go.warp.dev/join-preview
about: Discuss give feedback on the new features with other Warp Preview users.
- name: Warp Discord Community
url: https://discord.com/invite/warpdotdev
about: Discuss what you want to see in a Modern ADE with a community of other Warp users.
- name: Warp Homepage
url: https://www.warp.dev/
about: Homepage for all things Warp.
- name: Warp Licenses
url: https://docs.warp.dev/support-and-community/privacy-security-and-licensing/open-source-licenses
about: See the open source projects Warp depends on and their licenses.
@@ -0,0 +1,10 @@
## Justification
Why do we need this cherry-pick? Does it align with our [guidelines](https://www.notion.so/warpdev/How-We-Work-Releases-8e7d7cb4f2ca44b880fa1d0ae4876473?pvs=4)?
## Testing
How did you test this change? What automated tests did you add? If you didn't add any new tests, what's your justification for not adding any?
## Validation
- [ ] I've cut a new WarpDev to validate this change
- [ ] If this change is Wednesday or later, there's a dedicated bug bash scheduled for either this change or the release
@@ -0,0 +1,38 @@
This PR template helps ensure that as we launch new features we appropriately communicate, track, document, make them accessible, etc.
## PRD checklist
- [ ] Plan for how to measure success quantified by metrics
## Coding checklist
- [ ] Test in dev for a week
- [ ] Telemetry in code
- [ ] A11y (if applicable, see [testing a11y guide](https://docs.google.com/document/d/1-H0bWss5Qw18ZpIYg-RUvN7_db1MVdWfOb5UF_GLxNc/edit?usp=sharing) for more info)
- [ ] Add to Command Palette (if applicable)
- [ ] Add toggle setting(s) to command palette (if applicable)
- [ ] Add to Mac Menu (if applicable)
- [ ] Add keybinding (if applicable), see [actions audit for inspiration](https://docs.google.com/spreadsheets/d/1C56ZIqDGjJi873-HAPdnT2DofC3Z6G-aJMYeQeERHx4/edit#gid=0)
- [ ] Sanity check within the app that it does not clash other keybindings
- [ ] No sensitive info in logs
- [ ] No crashes on dev related to the feature
- [ ] No performance regression on dev. See [dashboard](https://warp.metabaseapp.com/dashboard/1519-dev-performance-by-version?shell=zsh)
- [ ] Feature works fine, and no regression, over SSH. See [instructions](https://github.com/warpdotdev/warp-internal/tree/master/app/tests/ssh/README.md) on how to get a VM.
- [ ] Have we explicitly brainstormed how this feature will be discovered by developers?
- [ ] Link to Figma mocks
- [ ] Tested on multiple themes (both dark and light)
- [ ] If the feature being released relies on some server API, has that server API been stable on production for at least one full server release cycle? See [here](https://www.notion.so/warpdev/How-to-add-a-new-full-stack-feature-8412cede405a4ec194b32bdd4b951035?pvs=4#73b202f939834b97ab1fbdf7fc82cd53) for more details.
## Content checklist
- [ ] Help content
- [ ] Changelog entry (add entry below)
- [ ] [Telemetry entry](https://docs.warp.dev/getting-started/privacy#exhaustive-telemetry-table) (if applicable)
- [ ] Metrics dashboard in Metabase
- [ ] Tweet (if appropriate)
- [ ] Blog post (if appropriate)
## Changelog
CHANGELOG-NEW-FEATURE: {{Insert a changelog entry here}}
+182
View File
@@ -0,0 +1,182 @@
# STAKEHOLDERS
#
# Maps source-code paths to subject-matter experts for issue and PR triage.
# Format follows CODEOWNERS: <pattern> @owner1 @owner2 ...
#
# Used by the triage-new-issues workflow to assign SMEs.
# Source of truth: warpdotdev/feedback-triage-bot ownership-areas.md
# Default fallback: FA leads are tagged when no more specific path matches
/ @vorporeal @alokedesai @zachbai @bnavetta @szgupta @jefflloyd
###########################################################################
# Team: App
###########################################################################
# Conversation and session restoration / cloud-synced conversations / planning / Warp Drive
/app/src/ai/agent_conversations_model.rs @seemeroland
/app/src/ai/persisted_workspace.rs @seemeroland
/app/src/ai/restored_conversations.rs @seemeroland
/app/src/ai/conversation_details_panel.rs @seemeroland
/app/src/drive/ @seemeroland
/app/src/cloud_object/ @seemeroland
/app/src/workflows/ @seemeroland
/app/src/server/cloud_objects/ @seemeroland
/app/src/terminal/find/ @seemeroland
/app/src/uri/ @seemeroland
# Code editor / LSP / notebooks / codebase context
/app/src/code/ @kevinyang372
/app/src/editor/ @kevinyang372
/app/src/notebooks/ @kevinyang372 @bnavetta
/app/src/ai/get_relevant_files/ @kevinyang372
/crates/ai/src/index/ @kevinyang372
/crates/ai/src/project_context/ @kevinyang372
/crates/editor/ @kevinyang372 @bnavetta
/crates/lsp/ @kevinyang372
/crates/repo_metadata/ @kevinyang372
# Settings and keybindings
/app/src/settings/ @lucieleblanc
/app/src/settings_view/ @lucieleblanc
/app/src/resource_center/keybindings_page.rs @lucieleblanc
# Input editor / window, tab, and pane management / grep tool call
/app/src/terminal/input/ @vkodithala
/app/src/pane_group/ @vkodithala
/app/src/tab.rs @vkodithala
/crates/warp_ripgrep/ @vkodithala @moirahuang @szgupta
# Command palette
/app/src/command_palette.rs @acarl005
/app/src/palette.rs @acarl005
/app/src/search/command_palette/ @acarl005
# @ context, slash commands, and global search / file tree
/app/src/context_chips/ @moirahuang
/app/src/search/ai_context_menu/ @moirahuang
/app/src/search/files/ @moirahuang
/app/src/search/search_results_menu/ @moirahuang
/app/src/search/slash_command_menu/ @moirahuang
/app/src/terminal/input/slash_commands/ @moirahuang
/app/src/code/file_tree/ @moirahuang
/app/src/workspace/view/global_search/ @moirahuang
# Onboarding / code review and git diff
/app/src/ai/onboarding.rs @kevinchevalier
/app/src/code_review/ @kevinchevalier
/app/src/code/diff_viewer.rs @kevinchevalier
/app/src/code/inline_diff.rs @kevinchevalier
/crates/onboarding/ @kevinchevalier
# MCP and skills
/app/src/ai/mcp/ @peicodes
/app/src/ai/skills/ @peicodes
/crates/mcp/ @peicodes
# Conversation management / credit usage footer / input UI / natural-language detection
/app/src/ai/active_agent_views_model.rs @harryalbert
/app/src/ai/conversation_navigation/ @harryalbert
/app/src/ai/conversation_status_ui.rs @harryalbert
/app/src/ai/request_usage_model.rs @harryalbert
/app/src/search/command_palette/conversations/ @harryalbert
/app/src/workspace/view/conversation_list/ @harryalbert
/app/src/terminal/input/conversations/ @harryalbert
/app/src/input_classifier.rs @harryalbert
/crates/input_classifier/ @harryalbert
/crates/natural_language_detection/ @harryalbert
# Blocklist UX / modality and cloud mode UI / shell compatibility / completions and bootstrap / warpifying
/app/src/ai/blocklist/ @zachbai
/app/src/root_view.rs @zachbai
/app/src/terminal/bootstrap.rs @zachbai
/app/src/terminal/warpify/ @zachbai
/app/src/settings_view/warpify_page.rs @zachbai
/app/assets/bundled/bootstrap/ @zachbai
/crates/warp_completer/ @zachbai @szgupta @alokedesai
# Agent mode
/app/src/ai/agent/ @zachbai
# Image attachment, voice input, and passive suggestions
/app/src/ai/attachment_utils.rs @Advait-M
/app/src/ai/voice/ @Advait-M
/app/src/ai/predict/ @Advait-M
/app/src/ai/blocklist/passive_suggestions/ @Advait-M
/app/src/voice/ @Advait-M
/crates/voice_input/ @Advait-M
# UI framework
/crates/warpui/ @vorporeal
/crates/warpui_core/ @vorporeal
/crates/warpui_extras/ @vorporeal
/crates/ui_components/ @vorporeal
# Conversation rewind / CLI agent UI / macOS/Linux platform issues / performance issues
/app/src/terminal/cli_agent.rs @zachbai
/app/src/terminal/cli_agent_sessions/ @zachbai
/app/src/terminal/input/rewind/ @alokedesai
/app/src/workspace/rewind_confirmation_dialog.rs @alokedesai
/app/src/platform/mac/ @alokedesai
/resources/linux/ @acarl005
# /pr-comments
/app/src/search/slash_command_menu/static_commands/commands.rs @lucieleblanc
# Grep tool call UI
/app/src/ai/blocklist/action_model/execute/grep.rs @vkodithala
###########################################################################
# Team: Platform
###########################################################################
# REST API and SDKs
/app/src/server/server_api/ @ianhodge
/crates/graphql/ @ianhodge
/crates/http_client/ @ianhodge
/crates/http_server/ @ianhodge
/crates/warp_server_client/ @ianhodge
# Session sharing
/app/src/terminal/shared_session/ @abhishekp106 @szgupta @bnavetta
# Agent profiles and execution permissions
/app/src/ai/cloud_agent_config/ @abhishekp106
/app/src/ai/cloud_agent_settings.rs @abhishekp106
/app/src/ai/execution_profiles/ @abhishekp106
/app/src/terminal/profile_model_selector.rs @abhishekp106
/app/src/settings_view/execution_profile_view.rs @abhishekp106
# Environment setup / agent management view
/app/src/ai/agent_management/ @liliwilson
/app/src/ai/cloud_environments/ @liliwilson
/app/src/settings_view/agent_assisted_environment_modal.rs @liliwilson
/app/src/settings_view/environments_page/ @liliwilson
/app/src/settings_view/environments_page.rs @liliwilson
/app/src/settings_view/update_environment_form.rs @liliwilson
# OAuth, Slack, Linear, and GitHub integrations
/app/src/auth/ @Legoben @jefflloyd @vorporeal @bnavetta
/app/src/linear.rs @Legoben @jefflloyd @vorporeal @bnavetta
/app/src/server/server_api/integrations.rs @Legoben @jefflloyd @vorporeal @bnavetta
/app/src/ai/agent_sdk/oauth_flow.rs @Legoben @jefflloyd @vorporeal @bnavetta
/app/src/ai/mcp/manager/oauth.rs @Legoben @jefflloyd @vorporeal @bnavetta
/app/src/ai/mcp/templatable_manager/oauth.rs @Legoben @jefflloyd @vorporeal @bnavetta
# Self-hosted agents
/crates/remote_server/ @kevinyang372 @alokedesai
# Scheduled agents / Warp CLI / cloud and ambient agents
/app/src/ai/ambient_agents/ @bnavetta
/app/src/terminal/view/ambient_agent/ @bnavetta
/app/src/workspace/view/launch_modal/oz_launch.rs @bnavetta
/crates/warp_cli/ @bnavetta @ianhodge
# Agent SDK and platform crates
/app/src/ai/agent_sdk/ @bnavetta @ianhodge
/crates/isolation_platform/ @bnavetta @ianhodge
/crates/managed_secrets/ @bnavetta @ianhodge
/crates/warp_web_event_bus/ @bnavetta @ianhodge
# Shell completions in the Warp CLI
/crates/warp_cli/src/completions.rs @zachbai @szgupta @alokedesai
@@ -0,0 +1,42 @@
FROM archlinux:base-devel
ARG USERNAME=build
# We use 1001 as the user UID here because 1000 is the UID for `runneradmin`,
# but the actual jobs are run as `runner` (with UID 1001).
ARG USER_UID=1001
ARG USER_GID=$USER_UID
# Set the packager name in makepkg.conf (so it doesn't say "Unknown Packager")
# when someone queries package info for our packages.
RUN echo 'PACKAGER="Warp Linux Maintainers <linux-maintainers@warp.dev>"' >> /etc/makepkg.conf
# Fetch package lists and install sudo, git, and protobuf (git is needed by
# cargo to resolve git dependencies during license generation, and protobuf
# provides protoc for generating rust bindings of protobuf APIs).
RUN pacman -Sy --needed --noconfirm sudo git protobuf
# Downgrade fakeroot to version 1.34. Version 1.35 switches from calling
# `close` in a loop to using the new `close_range` syscall, which seems to
# be unavailable in the Ubuntu 20.04 environment that hosts this Docker
# container.
#
# Syscall discussion: https://archlinuxarm.org/forum/viewtopic.php?f=15&t=16943
# Downgrade discussion: https://github.com/docker/for-mac/issues/7331
RUN pacman -U --noconfirm https://archive.archlinux.org/packages/f/fakeroot/fakeroot-1.34-1-x86_64.pkg.tar.zst
# Install cargo-about, which we require for bundling third-party licenses.
RUN pacman -S --needed --noconfirm cargo-about
# Create our build user and give them sudo privileges.
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
# Run as our build user instead of root, as makepkg must be run as a non-root
# user.
USER $USERNAME
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
@@ -0,0 +1,41 @@
# Important note: This must be run after we build the release binary; this only
# packages up an already-built binary.
name: Bundle Arch Linux package
description: Bundles an Arch Linux package for the given release channel.
inputs:
channel:
description: The channel for which we want to build an Arch package.
requred: true
release-tag:
description: The git release tag.
required: true
arch:
description: The architecture we are building for
required: true
artifact:
description: The artifact type to build (app or cli)
required: false
default: app
runs:
using: composite
steps:
- name: Build Docker image
shell: bash
run: docker build -t arch-bundle-builder ${{ github.action_path }}
- name: Run in container
shell: bash
run: |
docker run --rm \
-v "${{ github.workspace }}:/github/workspace" \
-v "${{ github.workspace }}/target:/github/workspace/target" \
-w /github/workspace \
-v "${CARGO_HOME:-$HOME/.cargo}/git:/home/build/.cargo/git" \
-v "${CARGO_HOME:-$HOME/.cargo}/registry:/home/build/.cargo/registry" \
-e GIT_RELEASE_TAG="$GIT_RELEASE_TAG" \
-e GITHUB_ACTIONS="$GITHUB_ACTIONS" \
-e GITHUB_OUTPUT="/dev/null" \
arch-bundle-builder \
${{ inputs.channel }} ${{ inputs.release-tag }} ${{ inputs.arch }} ${{ inputs.artifact }}
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
BUILD_ARCH="$3"
BUILD_ARCH="${BUILD_ARCH:-$(uname -m)}"
# Ensure we build with the most up-to-date package list. This could get stale due to Docker
# filesystem caching.
sudo pacman -Sy
# Run the bundle script, specifying the release channel and tag, skipping
# building the binary (as we have already done so), and only bundling the
# Arch package.
./script/bundle --channel $1 --release-tag $2 --skip-build --packages arch --arch $BUILD_ARCH --artifact $4
+170
View File
@@ -0,0 +1,170 @@
name: "Docubot"
description: "Helps Warp engineers identify PRs that need documentation updates in GitBook"
inputs:
prompt:
description: "Prompt to send to Warp"
required: true
warp_api_key:
description: "Warp API key"
required: true
warp_channel:
description: "Warp release channel (e.g., dev, preview, stable)"
required: false
default: "dev"
profile_id:
description: "Warp profile ID"
required: false
github_token:
description: "GitHub token for cloning private repositories"
required: false
runs:
using: composite
steps:
- name: Setup Warp CLI
uses: ./.github/actions/setup_warp_cli
with:
warp_channel: ${{ inputs.warp_channel }}
- name: Clone Warp GitBook repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
repository: warpdotdev/gitbook
token: ${{ inputs.github_token }}
path: gitbook
- name: Create prompt file
shell: bash
# TODO: use sdk (python or typescript) for this
run: |
set -euo pipefail
envsubst < .github/actions/docubot/prompt.txt > prompt.output.txt
env:
# GitHub Repository Context
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY_OWNER_ID: ${{ github.repository_owner_id }}
GITHUB_REPOSITORY_ID: ${{ github.repository_id }}
GITHUB_REPOSITORY_URL: ${{ github.repositoryUrl }}
# GitHub Event Context
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_EVENT_PATH: ${{ github.event_path }}
GITHUB_EVENT_ACTION: ${{ github.event.action }}
# GitHub Workflow Context
GITHUB_WORKFLOW: ${{ github.workflow }}
GITHUB_WORKFLOW_REF: ${{ github.workflow_ref }}
GITHUB_WORKFLOW_SHA: ${{ github.workflow_sha }}
GITHUB_JOB: ${{ github.job }}
GITHUB_RUN_ID: ${{ github.run_id }}
GITHUB_RUN_NUMBER: ${{ github.run_number }}
GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}
# GitHub Actor Context
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_ACTOR_ID: ${{ github.actor_id }}
GITHUB_TRIGGERING_ACTOR: ${{ github.triggering_actor }}
# GitHub Git Context
GITHUB_REF: ${{ github.ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_REF_PROTECTED: ${{ github.ref_protected }}
GITHUB_REF_TYPE: ${{ github.ref_type }}
GITHUB_SHA: ${{ github.sha }}
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_BASE_REF: ${{ github.base_ref }}
# Issue/PR Context
PR_OR_ISSUE_TITLE: ${{ github.event.issue.title || github.event.pull_request.title }}
PR_OR_ISSUE_BODY: ${{ github.event.issue.body || github.event.pull_request.body }}
PR_OR_ISSUE_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}
PR_OR_ISSUE_URL: ${{ github.event.issue.html_url || github.event.pull_request.html_url }}
PR_OR_ISSUE_STATE: ${{ github.event.issue.state || github.event.pull_request.state }}
PR_OR_ISSUE_CREATED_AT: ${{ github.event.issue.created_at || github.event.pull_request.created_at }}
PR_OR_ISSUE_UPDATED_AT: ${{ github.event.issue.updated_at || github.event.pull_request.updated_at }}
PR_OR_ISSUE_USER_LOGIN: ${{ github.event.issue.user.login || github.event.pull_request.user.login }}
PR_OR_ISSUE_USER_ID: ${{ github.event.issue.user.id || github.event.pull_request.user.id }}
PR_OR_ISSUE_ASSIGNEES: ${{ toJson(github.event.issue.assignees) || toJson(github.event.pull_request.assignees) }}
PR_OR_ISSUE_LABELS: ${{ toJson(github.event.issue.labels) || toJson(github.event.pull_request.labels) }}
# Pull Request Specific Context
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_HEAD_REPO_FULL_NAME: ${{ github.event.pull_request.head.repo.full_name }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
PR_BASE_REPO_FULL_NAME: ${{ github.event.pull_request.base.repo.full_name }}
PR_DRAFT: ${{ github.event.pull_request.draft }}
PR_MERGED: ${{ github.event.pull_request.merged }}
PR_MERGEABLE: ${{ github.event.pull_request.mergeable }}
PR_MERGEABLE_STATE: ${{ github.event.pull_request.mergeable_state }}
PR_COMMITS: ${{ github.event.pull_request.commits }}
PR_ADDITIONS: ${{ github.event.pull_request.additions }}
PR_DELETIONS: ${{ github.event.pull_request.deletions }}
PR_CHANGED_FILES: ${{ github.event.pull_request.changed_files }}
# Issue Specific Context
ISSUE_CLOSED_AT: ${{ github.event.issue.closed_at }}
ISSUE_MILESTONE: ${{ toJson(github.event.issue.milestone) }}
# Comment Context (for issue_comment events)
COMMENT_BODY: ${{ github.event.comment.body }}
COMMENT_USER_LOGIN: ${{ github.event.comment.user.login }}
COMMENT_USER_ID: ${{ github.event.comment.user.id }}
COMMENT_CREATED_AT: ${{ github.event.comment.created_at }}
COMMENT_UPDATED_AT: ${{ github.event.comment.updated_at }}
COMMENT_HTML_URL: ${{ github.event.comment.html_url }}
# Documentation Repository Context
GITBOOK_PATH: ${{ format('{0}/gitbook', github.workspace) }}
- name: Configure git identity
shell: bash
run: |
set -euo pipefail
git config user.name "Warp Agent"
git config user.email "agent@warp.dev"
- name: Run Warp agent
shell: bash
env:
WARP_API_KEY: ${{ inputs.warp_api_key }}
GH_TOKEN: ${{ inputs.github_token }}
PROFILE_ID: ${{ inputs.profile_id }}
run: |
set -euo pipefail
# Determine the CLI command name based on channel suffix
case "${{ inputs.warp_channel }}" in
stable|stable_release|"") suffix="" ;;
preview|preview_release) suffix="-preview" ;;
dev|dev_release) suffix="-dev" ;;
local) suffix="-local" ;;
integration|integration_test) suffix="-integration" ;;
*) suffix="" ;;
esac
cmd="warp-cli${suffix}"
# Basic check the binary exists
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Error: $cmd not found on PATH after installation"
exit 1
fi
# Execute the agent run
"$cmd" agent run \
--prompt "$(cat prompt.output.txt)" \
--api-key "$WARP_API_KEY" \
--cwd "$GITHUB_WORKSPACE" \
${PROFILE_ID:+--profile "$PROFILE_ID"}
- name: Upload Warp logs
if: ${{ always() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: warp-logs.log
path: /home/runner/.local/state/warp-terminal-dev/warp_dev.log
if-no-files-found: ignore
- name: Upload Warp prompt
if: ${{ always() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: prompt.output.txt
path: prompt.output.txt
if-no-files-found: ignore
+78
View File
@@ -0,0 +1,78 @@
You are Warp, the world's best AI coding assistant for helping with GitHub PRs and issues. Here is the context for your current task:
<pr_or_issue_title>
$PR_OR_ISSUE_TITLE
</pr_or_issue_title>
<pr_or_issue_body>
$PR_OR_ISSUE_BODY
</pr_or_issue_body>
<pr_or_issue_url>
$PR_OR_ISSUE_URL
</pr_or_issue_url>
<changed_files>
$PR_CHANGED_FILES
</changed_files>
<trigger_comment>
$COMMENT_USER_LOGIN: $COMMENT_BODY
</trigger_comment>
Your persona: You are **docubot**, living inside Warp's internal codebase. When triggered, you read the context of the invoking PR and update Warp's documentation repo (`https://github.com/warpdotdev/gitbook`). The GitBook repository is already available locally at `$GITBOOK_PATH` - you have direct access to it and should use it without attempting to clone it again. The repo is organized into Markdown files and assets. Your job is to create a new branch, apply accurate documentation changes, and open a well-scoped PR with a high-quality description. You need to post the link to the PR to the original PR in Warp-internal where the changes were made.
**Available Context Variables:**
- `$PR_OR_ISSUE_NUMBER`: The PR/issue number in warp-internal
- `$PR_OR_ISSUE_USER_LOGIN`: The GitHub username of the original PR author
- `$PR_OR_ISSUE_URL`: The URL of the original warp-internal PR
- `$PR_OR_ISSUE_TITLE`: The title of the original PR
- `$GH_TOKEN`: The token you should use to authenticate with GitHub when creating the PR. DO NOT reveal the contents of this secret token.
Key rules:
- **Truth first**: Only document behavior present in the PR or linked issues. Add `<!-- TODO -->` if something is unclear.
- **Scope**: Update only affected pages plus any directly impacted references. Dont rewrite unrelated sections.
- **Consistency**: Match existing style, tone, and structure in GitBook.
- **Assets**: Place images in `.gitbook/assets/`, use kebab-case names, and add alt text.
- **Privacy**: No secrets, tokens, or internal data in examples or screenshots.
- **Cross-linking**: Update or add links between related sections where useful.
Commit & PR conventions:
- Branch name: `docubot/<short-slug-from-invoking-pr-title>`
- Commit message style: `docs(area): concise summary of change`
- PR title: `Docs: <concise summary> (from <repo>#<PR>)`
- PR description must include:
- **Summary** of what changed
- **Pages/sections updated**
- **Why** the change was made
IMPORTANT OUTPUT INSTRUCTIONS:
- You are only allowed to leave **one comment**. Do so at the end of your run. Use the `gh` CLI tool to add a comment. You can (and should) use Markdown to format this.
- If code/doc changes are requested, make the changes locally, then update them in the remote branch via `git add`, `git commit`, and `git push -u` before posting your final comment. You MUST push the local branch with `-u`, otherwise the `gh` CLI will fail when you try to create the PR.
- Your comment should either:
1. Provide a clear PR summary + next steps (if you opened a docs PR), or
2. Explain blockers/clarifications needed.
ADDITIONAL WORKFLOW REQUIREMENTS:
- **After successfully creating a GitBook PR**: You MUST comment on the original warp-internal PR to:
1. Provide a link to the new GitBook documentation PR
2. Tag the original PR author (@$PR_OR_ISSUE_USER_LOGIN) as a reviewer to review the documentation changes
3. Include a brief summary of what documentation was updated
- **Steps for commenting on original PR**:
1. First, ensure you have the GitBook PR URL from your newly created PR
2. Use `gh pr comment $PR_OR_ISSUE_NUMBER --body "[comment content]"` in the warp-internal repository
3. The comment should follow this format:
```
**Documentation Updated**
I've created a documentation PR based on the changes in this PR:
**GitBook PR**: [Insert actual GitBook PR URL here]
**What was updated:**
- [Brief bullet points of documentation changes made]
@$PR_OR_ISSUE_USER_LOGIN - Please review the documentation changes to ensure they accurately reflect your implementation.
```
- **Important**: Replace `[Insert actual GitBook PR URL here]` with the real URL of the GitBook PR you created
- **Important**: Replace `[Brief bullet points of documentation changes made]` with actual details of what you updated
- **Repository context**: Ensure you're in the warp-internal repository when running the `gh pr comment` command, not in the GitBook repository
@@ -0,0 +1,59 @@
name: Get Channel Config
description: Provides a variety of config data for the given channel type.
inputs:
config_file:
description: The path to the configuration file.
required: true
channel:
description: The channel to retrieve configuration data for.
required: true
outputs:
channel:
description: The channel that we're building a release for. (This is the same as the input value.)
value: ${{ steps.get-config.outputs.channel }}
type:
description: The release type, either "nightly" or "weekly".
value: ${{ steps.get-config.outputs.type }}
is_prerelease:
description: Whether this channel is a prerelease channel.
value: ${{ steps.get-config.outputs.is_prerelease }}
is_autopush:
description: Whether new builds for this channel automatically trigger channel versions updates.
value: ${{ steps.get-config.outputs.is_autopush }}
release_base_name:
description: The base name for the GitHub release, to which the release number is appended.
value: ${{ steps.get-config.outputs.release_base_name }}
release_body_text:
description: The body text for the GitHub release.
value: ${{ steps.get-config.outputs.release_body_text }}
sentry_project:
description: The Sentry project under which a new release should be created.
value: ${{ steps.get-config.outputs.sentry_project }}
sentry_environment:
description: The environment to set for this channel's Sentry release.
value: ${{ steps.get-config.outputs.sentry_environment }}
changelog_slack_channel:
description: The Slack channel where the release's changelog should be posted.
value: ${{ steps.get-config.outputs.changelog_slack_channel }}
gcs_cache_control_value:
description: The Cache-Control value to set for release artifacts in Cloud Storage.
value: ${{ steps.get-config.outputs.gcs_cache_control_value }}
web_gcs_bucket_prefix:
description: The GCS bucket prefix for web artifacts. (Determines if they go in a staging or prod bucket.)
value: ${{ steps.get-config.outputs.web_gcs_bucket_prefix }}
runs:
using: composite
steps:
- id: get-config
env:
CONFIG_FILE: ${{ inputs.config_file }}
CHANNEL: ${{ inputs.channel }}
run: |
echo ::echo::on
jq -e '.channels[] | select(.channel == $ENV.CHANNEL)' $CONFIG_FILE > /dev/null
# Fail if the given channel is not found in the JSON release configuration.
[ $? -eq 0 ] || (echo ::error::"Channel $CHANNEL not found in release configuration" && exit 1)
jq -rc '.channels[] | select(.channel == $ENV.CHANNEL) | to_entries | map("\(.key)=\(.value)")[]' $CONFIG_FILE >> $GITHUB_OUTPUT
echo ::echo::off
shell: bash
@@ -0,0 +1,139 @@
name: Prepare Environment
description: A shared set of setup steps to prepare the runtime environment.
inputs:
target_os:
required: true
description: The target OS that we're building for ("macos", "linux", "windows", or "wasm").
is_self_hosted:
required: true
description: Whether or not the workflow is running on a self-hosted runner.
ref:
description: If set, the ref to checkout.
install_test_deps:
description: If true, dependencies needed for running tests will be installed.
install_release_deps:
description: If true, dependencies needed for building release artifacts will be installed (e.g., cargo-about for license generation).
cache_key:
description: If set, the cache key to use. If unset, the cache key will be derived from the target OS.
runs:
using: composite
steps:
- name: Make GitHub token available in the environment
shell: bash
run: echo "GH_TOKEN=${{ github.token }}" >> $GITHUB_ENV
- name: Set up git for Windows
if: ${{ inputs.target_os == 'windows' }}
shell: bash
run: git config --system core.longpaths true
- name: Set CARGO_HOME location
if: ${{ inputs.target_os == 'windows' }}
shell: bash
run: echo "CARGO_HOME=C:\cargo" >> $GITHUB_ENV
- name: Determine repository root
id: repo-root
shell: bash
run: |
# The action lives at <repo-root>/.github/actions/prepare_environment.
# Derive the repository root from the action path.
REPO_ROOT=$(cd "${{ github.action_path }}/../../.." && pwd)
echo "path=$REPO_ROOT" >> $GITHUB_OUTPUT
# Normalize $GITHUB_WORKSPACE through cd/pwd so that path formats
# match on Windows (where $GITHUB_WORKSPACE uses backslashes but
# pwd produces MSYS-style forward-slash paths).
WORKSPACE=$(cd "$GITHUB_WORKSPACE" && pwd)
if [ "$REPO_ROOT" = "$WORKSPACE" ]; then
echo "is-workspace-root=true" >> $GITHUB_OUTPUT
else
echo "is-workspace-root=false" >> $GITHUB_OUTPUT
fi
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
if: ${{ inputs.is_self_hosted != 'true' && !startsWith(runner.name, 'nsc-runner') }}
with:
# Make sure x86_64-unknown-linux-gnu and wasm32-unknown-unknown builds
# don't share a cache, despite running on the same _host_ architecture.
key: ${{ inputs.cache_key != '' && inputs.cache_key || inputs.target_os }}
# Only cache runs on the master branch (caches on feature branches
# are not reusable).
save-if: ${{ github.ref == 'refs/heads/master' }}
- name: Set up Namespace cache
if: ${{ startsWith(runner.name, 'nsc-runner') }}
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
with:
cache: |
rust
${{ inputs.target_os == 'macos' && 'brew' || '' }}
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 # v1.18.1
env:
BINSTALL_VERSION: 1.14.4
- name: Install dependencies
shell: bash
run: |
cd "${{ steps.repo-root.outputs.path }}"
if ${{ inputs.target_os == 'macos' }}; then
# Try to install warp-channel-config but don't complain if it cannot
# be installed.
./script/install_channel_config || true
if ${{ inputs.install_release_deps == 'true' }}; then
./script/install_cargo_release_deps
else
./script/install_cargo_build_deps
fi
elif ${{ inputs.target_os == 'linux' }}; then
# Update the apt cache before installing dependencies - it can be slow, so the install scripts
# don't do it.
sudo apt-get update -y
if ${{ inputs.install_test_deps == 'true' }}; then
./script/linux/install_test_deps
elif ${{ inputs.install_release_deps == 'true' }}; then
./script/linux/install_build_deps
./script/install_cargo_release_deps
else
./script/linux/install_build_deps
fi
elif ${{ inputs.target_os == 'windows' }}; then
./script/windows/install_build_deps.ps1
if ${{ inputs.install_release_deps == 'true' }}; then
./script/install_cargo_release_deps
fi
elif ${{ inputs.target_os == 'wasm' }}; then
# Update the apt cache before installing dependencies - it can be slow, so the install scripts
# don't do it (to avoid doing it more than once).
sudo apt update -y
./script/wasm/install_build_deps
else
echo "::error::Missing logic to install build dependencies for OS \"${{ inputs.target_os }}\""
exit 1
fi
- name: Install Node
uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
with:
node-version: 20.9.0
- name: Enable Corepack
# Enables NodeJS's Corepack tool, which is necessary to use the right version of `yarn` to
# build TS command signatures.
shell: bash
run: corepack enable
- name: Install protoc for generating rust bindings of protobuf APIs
# Install protoc for generating rust bindings of protobuf APIs.
uses: ConorMacBride/install-package@3e7ad059e07782ee54fa35f827df52aae0626f30 # v1
with:
brew: protobuf
choco: protoc
- uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0
if: ${{ inputs.target_os == 'macos' && inputs.is_self_hosted != 'true' }}
with:
xcode-version: '26'
+51
View File
@@ -0,0 +1,51 @@
# Please see the documentation for all configuration options:
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "warpdotdev/tech-leads"
registries:
- github-private
# Only send security updates, not general version updates.
open-pull-requests-limit: 0
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "warpdotdev/tech-leads"
cooldown:
# Don't update to any action release that is less than two weeks old.
default-days: 14
groups:
# Group all non-major updates of official actions together - they're lower-risk.
official-actions:
applies-to: version-updates
patterns:
- "actions/*"
update-types:
- "minor"
- "patch"
# Group all non-major updates of Namespace actions together - they're lower-risk.
namespace-actions:
applies-to: version-updates
patterns:
- "namespacelabs/*"
- "namespace-actions/*"
update-types:
- "minor"
- "patch"
registries:
# Allow dependabot to access our private GitHub repositories.
github-private:
type: git
url: https://github.com
username: x-access-token
# This is a PAT (personal access token) for the warpmachineuser
# GitHub user.
password: ${{secrets.DEPENDABOT_PRIVATE_REPO_ACCESS_TOKEN}}
+168
View File
@@ -0,0 +1,168 @@
{
"labels": {
"bug": {
"color": "d73a4a",
"description": "Something isn't working."
},
"enhancement": {
"color": "a2eeef",
"description": "New feature or request."
},
"documentation": {
"color": "0075ca",
"description": "Improvements or additions to documentation."
},
"duplicate": {
"color": "cfd3d7",
"description": "This issue or pull request already exists."
},
"needs-info": {
"color": "fbca04",
"description": "More issue-specific reporter detail is needed before the problem can be confidently triaged."
},
"triaged": {
"color": "5319e7",
"description": "Issue has received an initial automated triage pass."
},
"ready-to-spec": {
"color": "1d76db",
"description": "The issue is ready for a product and technical spec."
},
"needs-mocks": {
"color": "f48c06",
"description": "The issue requires UI mocks from from Warp's design team before implementation can begin."
},
"ready-to-implement": {
"color": "0e8a16",
"description": "The issue is ready for implementation work."
},
"repro:high": {
"color": "b60205",
"description": "The report includes enough evidence that the issue appears highly reproducible."
},
"repro:medium": {
"color": "fbca04",
"description": "The report suggests a plausible repro path, but some uncertainty remains."
},
"repro:low": {
"color": "d4c5f9",
"description": "The report points to a real problem, but reproduction details are weak or inconsistent."
},
"repro:unknown": {
"color": "6e7681",
"description": "The report does not provide enough evidence to estimate reproducibility yet."
},
"accessibility": {
"color": "7306a2",
"description": "Accessibility issues or requests."
},
"os:mac": {
"color": "f5f5f7",
"description": "macOS-specific behavior, regressions, or requests."
},
"os:linux": {
"color": "e95420",
"description": "Linux-specific behavior, regressions, or requests."
},
"os:windows": {
"color": "0078d6",
"description": "Windows-specific behavior, regressions, or requests."
},
"area:agent": {
"color": "0052cc",
"description": "Agent workflows, conversations, prompts, cloud mode, and AI-specific UI."
},
"area:auth": {
"color": "5319e7",
"description": "Authentication, login, SSO, session management, and account security."
},
"area:billing": {
"color": "8b5cf6",
"description": "Pricing, plans, subscriptions, payment, and billing management."
},
"area:code-review": {
"color": "0e8a16",
"description": "Git diff views, review UI, review comments, and PR-focused agent flows."
},
"area:completions": {
"color": "2da44e",
"description": "Standard shell completions, argument completions, and path completion."
},
"area:editor-notebooks": {
"color": "1d76db",
"description": "Editors, notebooks, markdown rendering, LSP, and code display."
},
"area:launch-configs": {
"color": "c2e0c6",
"description": "Launch configurations, workflows, tab configs, and automation entry points."
},
"area:mcp": {
"color": "bfdadc",
"description": "MCP server integrations, tool connections, and resource providers."
},
"area:onboarding": {
"color": "f9d0c4",
"description": "First-run experience, onboarding flows, and related callouts."
},
"area:performance": {
"color": "e36209",
"description": "General application performance, responsiveness, and resource usage."
},
"area:performance:cpu": {
"color": "d93f0b",
"description": "CPU utilization, process efficiency, and compute-bound performance."
},
"area:performance:memory": {
"color": "d93f0b",
"description": "Memory usage, allocation, leaks, and memory-bound performance."
},
"area:performance:gpu": {
"color": "d93f0b",
"description": "GPU utilization, rendering performance, and graphics resource usage."
},
"area:search": {
"color": "0366d6",
"description": "Global search, command palette, and content discovery."
},
"area:settings-keybindings": {
"color": "d876e3",
"description": "Settings UI, preferences, keybindings, and keyboard-shortcut management."
},
"area:shell-terminal": {
"color": "006b75",
"description": "Terminal output, shell integration, prompt rendering, and block display."
},
"area:skills": {
"color": "c6e2d6",
"description": "Agent skills, skill authoring, and skill execution."
},
"area:suggestions": {
"color": "7dc4e4",
"description": "AI-predictive suggestions, prompt predictions, next-command suggestions, and auto-suggest heuristics."
},
"area:terminal-input": {
"color": "0a6b5e",
"description": "Terminal command-line input, cursor movement, key handling, and input editing."
},
"area:ssh": {
"color": "00008b",
"description": "SSH and remote-session behavior, including tmux-related terminal flows."
},
"area:ui-framework": {
"color": "5319e7",
"description": "Core Warp UI framework, rendering, layout, and windowing infrastructure."
},
"area:warp-drive": {
"color": "0e8a16",
"description": "Warp Drive objects, sync, sharing, cloud object management, and persisted artifacts."
},
"area:window-tabs-panes": {
"color": "fef2c0",
"description": "Window, tab, pane, and layout management."
},
"area:workspace": {
"color": "0550ae",
"description": "File tree, workspace navigation, project switching, and working-directory management."
}
}
}
+38
View File
@@ -0,0 +1,38 @@
## Description
<!-- Please remember to add your design buddy onto the PR for review, if it contains any UI changes! -->
## Testing
<!--
How did you test this change? What automated tests did you add? If you didn't add any new tests, what's your justification for not adding any?
If you're not sure whether you should add a test, check our testing policy: https://www.notion.so/warpdev/How-We-Code-at-Warp-257fe43d556e4b3c8dfd42f70004cc72#1f97825450504baa9c5fd87a737daa09
-->
## Server API dependencies
<!-- You may remove this section if your PR does not have any server dependencies. -->
- [ ] Is this change necessary to make the client compatible with a desired [server API breaking change](https://www.notion.so/warpdev/How-to-safely-introduce-server-API-breaking-changes-0aa805ff5d5d41fd8834f3c95caba0b4?pvs=4#d55ecf8aea3449949d3c33b0e67f6800)?
- [ ] Does this change rely on a [new server API](https://www.notion.so/warpdev/How-to-add-a-new-full-stack-feature-8412cede405a4ec194b32bdd4b951035?pvs=4#04da1e6a493542d68b3e998c7d339640)?
- [ ] If so, is the use of this API restricted to client channels that rely on the staging server (e.g. WarpDev)?
- [ ] Is this change enabling the use of a server API on client channels that rely on the production server (e.g. WarpStable)?
- [ ] If so, has the new server API been stable on production for at least one server release cycle? See [here](https://www.notion.so/warpdev/How-to-add-a-new-full-stack-feature-8412cede405a4ec194b32bdd4b951035?pvs=4#73b202f939834b97ab1fbdf7fc82cd53) for more details.
## Agent Mode
- [ ] Warp Agent Mode - This PR was created via Warp's AI Agent Mode
## Changelog Entries for Stable
<!--
The entries below will be used when constructing a soft-copy of the stable release changelog. Leave blank or remove the lines if no entry in the stable changelog is needed. Entries should be on the same line, without the `{{` `}}` brackets. You can use multiple lines, even of the same type. The valid suffixes are:
* NEW-FEATURE: for new, relatively sizable features. Features listed here will likely have docs / social media posts / marketing launches associated with them, so use sparingly.
* IMPROVEMENT: for new functionality of existing features.
* BUG-FIX: for fixes related to known bugs or regressions.
* IMAGE: the image specified by the URL (hosted on GCP) will be added to Dev & Preview releases. For Stable releases, see the pinned doc in the #release Slack channel.
* OZ: Oz-related updates. Use `CHANGELOG-OZ`. At most 4 Oz updates are shown in-app per release.
-->
CHANGELOG-NEW-FEATURE: {{text goes here...}}
CHANGELOG-IMPROVEMENT: {{text goes here...}}
CHANGELOG-BUG-FIX: {{text goes here...}}
CHANGELOG-BUG-FIX: {{more text goes here...}}
CHANGELOG-IMAGE: {{GCP-hosted URL goes here...}}
CHANGELOG-OZ: {{text goes here...}}
+19
View File
@@ -0,0 +1,19 @@
# Release Configurations
This README file documents the format of the `release_configurations.json` file located in this directory. The file defines Warp's various release channels, and provides values for the various variables that are necessary to run the `create_new_releases.yml` GitHub workflow.
At some point, we may want to replace this document with a JSON schema file (which could be used to validate the correctness of the configuration as part of PR presubmit).
## Fields
* **channel**: The channel's unique identifier
* **type**: The release cadence. At present, the valid values are "nightly" or "weekly".
* **is_prerelease**: If true, the GitHub release for this channel will be marked as prerelease.
* **is_autopush**: If true, this channel uses the "latest" keyword in `channel_versions.json` to automatically deploy new release candidates. Non-autopush channels require a manual change in order to deploy them.
* **release_base_name**: The base name of GitHub releases created for this channel.
* **release_body_text**: The body text for GitHub releases created for this channel.
* **sentry_project**: Which Sentry project should receive crash and error reports for this channel.
* **sentry_environment**: The Sentry environment that corresponds to this channel.
* **changelog_slack_channel**: The Slack channel where new changelogs will be posted whenever a new release candidates is cut.
* **gcs_cache_control_value**: The value of the cache-control response header for release DMGs.
- **IMPORTANT!!**: the value of the cache-control header _must_ be all lowercase; uppercase values will not be respected by Cloud CDN.
+162
View File
@@ -0,0 +1,162 @@
name: Check Approvals
on:
pull_request:
types: [opened, synchronize, ready_for_review]
pull_request_review:
types: [submitted]
jobs:
check_owners:
name: Check OWNERS approval
runs-on: ubuntu-latest
# Skip draft PRs.
if: github.event.pull_request.draft == false
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
# We don't actually need the contents of the files, just their names.
filter: blob:none
- name: Get changed files
id: changed_files
run: |
HEAD_SHA=${{ github.event.pull_request.head.sha }}
BASE_SHA=${{ github.event.pull_request.base.sha }}
MERGE_BASE=$(git merge-base "$BASE_SHA" "$HEAD_SHA")
CHANGED_FILES=$(git diff --name-only "$MERGE_BASE" "$HEAD_SHA" | tr '\n' ' ')
echo "files=$CHANGED_FILES" >> "$GITHUB_OUTPUT"
- name: Get PR approvers
id: approvers
env:
GH_TOKEN: ${{ github.token }}
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
PR_AUTHOR=${{ github.event.pull_request.user.login }}
# Get all approved reviews.
REVIEWERS=$(gh pr view "$PR_NUMBER" --json reviews --jq '[.reviews[] | select(.state == "APPROVED") | .author.login] | unique | join(" ")')
# Combine PR author (self-approves) with reviewers.
ALL_APPROVERS="$PR_AUTHOR $REVIEWERS"
echo "approvers=$ALL_APPROVERS" >> "$GITHUB_OUTPUT"
echo "has_reviewers=$( [[ -n "$REVIEWERS" ]] && echo true || echo false )" >> "$GITHUB_OUTPUT"
echo "PR author: $PR_AUTHOR"
echo "Reviewers who approved: $REVIEWERS"
echo "All approvers: $ALL_APPROVERS"
- name: Check OWNERS approval
env:
CHANGED_FILES: ${{ steps.changed_files.outputs.files }}
APPROVERS: ${{ steps.approvers.outputs.approvers }}
run: |
set -e
# Convert approvers to an array.
read -ra APPROVER_ARRAY <<< "$APPROVERS"
# Function to get owners for a file by walking up the directory tree.
get_owners_for_file() {
local file="$1"
local dir
dir=$(dirname "$file")
local owners=()
# Walk up the directory tree.
while [[ "$dir" != "." && "$dir" != "/" ]]; do
if [[ -f "$dir/OWNERS" ]]; then
# Read owners file, skip comments and empty lines.
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip comments and empty lines.
line=$(echo "$line" | sed 's/#.*//' | xargs)
if [[ -n "$line" ]]; then
owners+=("$line")
fi
done < "$dir/OWNERS"
fi
dir=$(dirname "$dir")
done
# Check root directory.
if [[ -f "OWNERS" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
line=$(echo "$line" | sed 's/#.*//' | xargs)
if [[ -n "$line" ]]; then
owners+=("$line")
fi
done < "OWNERS"
fi
# Return unique owners.
printf '%s\n' "${owners[@]}" | sort -u | tr '\n' ' ' | sed 's/ $//'
}
# Function to check if any approver is in the owners list.
has_owner_approval() {
local owners="$1"
for approver in "${APPROVER_ARRAY[@]}"; do
if echo "$owners" | grep -qw "$approver"; then
return 0
fi
done
return 1
}
MISSING_APPROVAL=()
FILES_CHECKED=0
for file in $CHANGED_FILES; do
# Skip if file doesn't exist (deleted files).
FILES_CHECKED=$((FILES_CHECKED + 1))
OWNERS=$(get_owners_for_file "$file")
if [[ -z "$OWNERS" ]]; then
# No OWNERS files in ancestry - automatically passes.
echo "✓ $file (no OWNERS requirement)"
continue
fi
if has_owner_approval "$OWNERS"; then
echo "✓ $file"
else
echo "✗ $file (owners: $OWNERS)"
MISSING_APPROVAL+=("$file")
fi
done
echo ""
echo "Files checked: $FILES_CHECKED"
echo "Approvers: ${APPROVER_ARRAY[*]}"
# Save missing files for comment step (must happen before exit).
echo "MISSING_FILES<<EOF" >> "$GITHUB_ENV"
for file in "${MISSING_APPROVAL[@]}"; do
OWNERS=$(get_owners_for_file "$file")
echo "- \`$file\` (needs approval from: $OWNERS)" >> "$GITHUB_ENV"
done
echo "EOF" >> "$GITHUB_ENV"
if [[ ${#MISSING_APPROVAL[@]} -gt 0 ]]; then
echo ""
echo "::error::The following files are missing OWNERS approval:"
for file in "${MISSING_APPROVAL[@]}"; do
OWNERS=$(get_owners_for_file "$file")
echo "::error:: - $file (needs approval from: $OWNERS)"
done
exit 1
fi
echo ""
echo "All files have required OWNERS approval."
- name: Comment on PR about missing approvals
if: failure() && github.event_name == 'pull_request_review' && steps.approvers.outputs.has_reviewers == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
gh pr comment "$PR_NUMBER" --body "The following files still need approval from their OWNERS:\n\n$MISSING_FILES"
+720
View File
@@ -0,0 +1,720 @@
on:
pull_request:
branches:
- 'master'
- '*_release/*'
types:
- opened
- reopened
- synchronize
- ready_for_review
workflow_dispatch:
inputs:
runner_type:
required: true
type: choice
options:
- self_hosted
- github_hosted
workflow_call:
name: Warp CI
env:
CARGO_TERM_COLOR: always
NEXTEST_PROFILE: ci
WORKSPACE_TEST_ARGS: --workspace --locked --exclude command-signatures-v2
# Include only as much debug info as is necessary to see backtraces
# in test failures. This should speed up compilation somewhat and
# reduces the size of built artifacts (which addresses issues with
# running out of space on GitHub-hosted runners).
RUSTFLAGS: -C debuginfo=line-tables-only --cfg=web_sys_unstable_apis
# Ensure we open up real windows that render their contents via the GPU,
# so that we can exercise the actual rendering logic.
WARPUI_USE_REAL_DISPLAY_IN_INTEGRATION_TESTS: 1
concurrency:
# Cancel any outstanding CI workflow runs against the same PR.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
params:
name: Compute workflow parameters
timeout-minutes: 3
runs-on: ubuntu-latest
# Don't automatically run CI for draft PRs, to reduce GitHub Actions costs.
#
# Also, don't run CI for repo-sync PRs _unless_ there is a merge conflict - for those,
# we'll want to make sure that the conflict resolution doesn't introduce any issues.
if: >-
github.event.pull_request.draft == false &&
(!startsWith(github.event.pull_request.head.ref, 'repo-sync/') || contains(github.event.pull_request.labels.*.name, 'repo-sync:conflict'))
outputs:
affects-database-schema: ${{ github.ref == 'master' || steps.filter.outputs.affects-database-schema }}
affects-rust-sources: ${{ github.ref == 'master' || steps.filter.outputs.affects-rust-sources }}
macos-runner: ${{ steps.mac_runner_type.outputs.value }}
wasm-runner: ${{ steps.wasm_runner_type.outputs.value }}
steps:
- name: Checkout sources
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check changed files
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: filter
with:
filters: |
affects-database-schema:
- 'crates/persistence/src/schema.rs'
- 'crates/persistence/migrations/**'
affects-rust-sources:
- '**.rs'
- name: Determine macOS runner type
id: mac_runner_type
run: |
RUNNER_TYPE='["namespace-profile-mac-ci"]'
echo "value=$RUNNER_TYPE" >> $GITHUB_OUTPUT
- name: Determine wasm runner type
id: wasm_runner_type
run: |
# Use a larger (16 core, 64GB ram) runner on Linux to speed up execution time.
# https://github.com/warpdotdev/warp-internal/settings/actions/runners
RUNNER_TYPE='["ubuntu-latest-large"]'
echo "value=$RUNNER_TYPE" >> $GITHUB_OUTPUT
tests:
name: Run ${{ matrix.name }} tests
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
include:
- os: "macos"
name: "MacOS"
runner: ${{ fromJSON(needs.params.outputs.macos-runner) }}
is_self_hosted: ${{ contains(fromJSON(needs.params.outputs.macos-runner), 'self-hosted') }}
extra_test_args: ""
- os: "linux"
name: "Linux"
# Use a larger (16 core, 64GB ram) runner on Linux to speed up execution time.
# https://github.com/warpdotdev/warp-internal/settings/actions/runners
runner: ubuntu-latest-large
# We don't (yet) have any self-hosted Linux runners.
is_self_hosted: false
extra_test_args: ""
- os: "windows"
name: "Windows"
runner: windows-latest-large
# We don't (yet) have any self-hosted Windows runners.
is_self_hosted: false
extra_test_args: "--exclude command-signatures-v2 --exclude warp_js"
runs-on: ${{ matrix.runner }}
needs: params
# Make sure an ID token is created with the necessary permissions to use
# GCP's Workload Identity Federation (for service account authentication).
permissions:
contents: 'read'
id-token: 'write'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: ./.github/actions/prepare_environment
with:
target_os: ${{ matrix.os }}
is_self_hosted: ${{ matrix.is_self_hosted }}
install_test_deps: true
- name: Install Shells
uses: ConorMacBride/install-package@3e7ad059e07782ee54fa35f827df52aae0626f30 # v1
if: ${{ matrix.is_self_hosted == false }}
with:
apt: zsh fish
brew: fish bash
- name: Echo Shells (UNIX)
id: echo_shells_unix
if: ${{ matrix.os != 'windows' }}
shell: bash
run: |
if ${{ matrix.os == 'macos' }}; then
LATEST_BASH_PATH="$(brew --prefix bash)/bin/bash"
echo "latest_bash_path=$LATEST_BASH_PATH" >> $GITHUB_OUTPUT
LATEST_BASH_VERSION="$($LATEST_BASH_PATH --version)"
echo "::notice title=${{ matrix.name }} Tests - Latest Bash Version::$LATEST_BASH_VERSION"
fi
DEFAULT_BASH_PATH="$(command -pv bash)"
DEFAULT_BASH_VERSION="$($DEFAULT_BASH_PATH --version)"
echo "default_bash_path=$DEFAULT_BASH_PATH" >> $GITHUB_OUTPUT
echo "::notice title=${{ matrix.name }} Tests - Default Bash Version::$DEFAULT_BASH_VERSION"
FISH_PATH="$(which fish)"
echo "fish_path=$FISH_PATH" >> $GITHUB_OUTPUT
FISH_VERSION="$($FISH_PATH --version)"
echo "::notice title=${{ matrix.name }} Tests - Fish Version::$FISH_VERSION"
ZSH_VERSION="$(zsh --version)"
ZSH_PATH="$(which zsh)"
echo "zsh_path=$ZSH_PATH" >> $GITHUB_OUTPUT
echo "::notice title=${{ matrix.name }} Tests - Zsh Version::$ZSH_VERSION"
POWERSHELL_PATH="$(which pwsh)"
POWERSHELL_VERSION=$(pwsh -version | awk '{print $2}')
echo "powershell_path=$POWERSHELL_PATH" >> $GITHUB_OUTPUT
echo "::notice title=${{ matrix.name }} Tests - Powershell Version::$POWERSHELL_VERSION"
- name: Echo Shells (Windows)
id: echo_shells_windows
if: ${{ matrix.os == 'windows' }}
shell: pwsh
run: |
$env:POWERSHELL_PATH = (Get-Command pwsh).Source
$env:POWERSHELL_VERSION = (Get-Command pwsh).Version.Major
Write-Output 'Powershell path:' $env:POWERSHELL_PATH
Write-Output 'Powershell version:' $env:POWERSHELL_VERSION
Write-Output "powershell_path=$env:POWERSHELL_PATH" >> $env:GITHUB_OUTPUT
Write-Output "::notice title=${{ matrix.name }} Tests - Powershell Version::$env:POWERSHELL_VERSION"
- name: Echo Default Shell
id: echo_default_shell
shell: bash
run: |
if ${{ matrix.os == 'windows' }}; then
DEFAULT_SHELL="${{ steps.echo_shells_windows.outputs.powershell_path }}"
else
DEFAULT_SHELL="${{ steps.echo_shells_unix.outputs.zsh_path }}"
fi
echo "Using default shell '$DEFAULT_SHELL'"
echo "default_shell_path=$DEFAULT_SHELL" >> $GITHUB_OUTPUT
- name: Install cargo nextest
if: ${{ matrix.is_self_hosted == false }}
uses: taiki-e/install-action@9a29ce630c67077a359246f3e4f84941e05f28b5 # v1
with:
tool: nextest
- name: Run ssh-agent for SSH tests
if: ${{ matrix.os == 'linux' }}
run: |
# Create the .ssh dir.
mkdir -p ~/.ssh
# Run the agent.
eval "$(ssh-agent -s)"
# Persist the SSH_AUTH_SOCK and SSH_AGENT_PID for future steps
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $GITHUB_ENV
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> $GITHUB_ENV
- name: Set up gcloud authentication for SSH tests
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
with:
workload_identity_provider: projects/63595664881/locations/global/workloadIdentityPools/github-pool/providers/github-provider
service_account: github-ci-workflow@warp-ssh-integration-testing.iam.gserviceaccount.com
- name: Install gcloud CLI tool
uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1
with:
version: '>= 397.0.0'
- name: Install vim for richer alt-screen tests
if: ${{ matrix.is_self_hosted == false }}
uses: ConorMacBride/install-package@3e7ad059e07782ee54fa35f827df52aae0626f30 # v1
with:
brew: vim
apt: vim
- name: Compile tests
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} --no-run
env:
# Attach the GitHub auth token so that requests to the GitHub API
# don't get rate limited during compilation (e.g.: retrieving
# Sentry SDK binary releases).
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run unit tests
# Unlike later test steps, only run this if previous steps succeed (so
# that we don't bother running these first tests if test compilation
# fails).
if: success()
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} -E "not package(integration)"
env:
# Unit tests may end up spawning a shell, but shouldn't care which
# shell it is. We'll use zsh, as it has the shortest bootstrap times
# and tends to be the most reliable.
WARP_SHELL_PATH: ${{ steps.echo_default_shell.outputs.default_shell_path }}
- name: Upload results of unit tests to trunk.io
# Run this step even when the tests fail. Skip if the workflow is cancelled.
if: ${{ !cancelled() }}
continue-on-error: true
uses: trunk-io/analytics-uploader@95a0fb8b29e45b6068304261fb518644b426a803 # v2.0.8
with:
junit-paths: target/nextest/ci/junit.xml
cli-version: 0.12.5
org-slug: warp
token: ${{ secrets.TRUNK_API_TOKEN }}
tags: type=unit
variant: ${{ matrix.os }}
use-cache: true
- name: Run shell-agnostic integration tests
# Run this step even if a previous test step fails
if: matrix.os != 'windows' && (success() || failure())
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
with:
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} -E "package(integration) and not test(shell_integration_tests)"
env:
# We run shell-agnostic tests against zsh, as it has the shortest
# bootstrap times and tends to be the most reliable.
WARP_SHELL_PATH: ${{ steps.echo_shells_unix.outputs.zsh_path }}
- name: Upload results of shell-agnostic integration tests to trunk.io
# Run this step even when the tests fail. Skip if the workflow is cancelled.
if: ${{ matrix.os != 'windows' && !cancelled() }}
continue-on-error: true
uses: trunk-io/analytics-uploader@95a0fb8b29e45b6068304261fb518644b426a803 # v2.0.8
with:
junit-paths: target/nextest/ci/junit.xml
cli-version: 0.12.5
org-slug: warp
token: ${{ secrets.TRUNK_API_TOKEN }}
tags: type=integration,category=shell-agnostic
variant: ${{ matrix.os }}
use-cache: true
- name: Run shell integration tests against default version of bash
# Run this step even if a previous test step fails
if: matrix.os != 'windows' && (success() || failure())
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
with:
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} -E "package(integration) and test(shell_integration_tests)"
env:
WARP_SHELL_PATH: ${{ steps.echo_shells_unix.outputs.default_bash_path }}
- name: Upload results of shell integration tests against default version of bash to trunk.io
# Run this step even when the tests fail. Skip if the workflow is cancelled.
if: ${{ matrix.os != 'windows' && !cancelled() }}
continue-on-error: true
uses: trunk-io/analytics-uploader@95a0fb8b29e45b6068304261fb518644b426a803 # v2.0.8
with:
junit-paths: target/nextest/ci/junit.xml
cli-version: 0.12.5
org-slug: warp
token: ${{ secrets.TRUNK_API_TOKEN }}
tags: type=integration,category=bash-default
variant: ${{ matrix.os }}
use-cache: true
- name: Run shell integration tests against latest version of bash
# Run this step even if a previous test step fails.
# We only run this on MacOS since the default Bash version on Mac
# was released in 2007. Most Linux distros ship with a relatively
# new (version 5.0+) version of Bash.
if: (success() || failure()) && runner.os == 'macos'
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
with:
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} -E "package(integration) and test(shell_integration_tests)"
env:
WARP_SHELL_PATH: ${{ steps.echo_shells_unix.outputs.latest_bash_path }}
- name: Upload results of shell integration tests against latest version of bash to trunk.io
# Run this step even when the tests fail. Skip if the workflow is cancelled.
if: ${{ matrix.os != 'windows' && !cancelled() }}
continue-on-error: true
uses: trunk-io/analytics-uploader@95a0fb8b29e45b6068304261fb518644b426a803 # v2.0.8
with:
junit-paths: target/nextest/ci/junit.xml
cli-version: 0.12.5
org-slug: warp
token: ${{ secrets.TRUNK_API_TOKEN }}
tags: type=integration,category=bash-latest
variant: ${{ matrix.os }}
use-cache: true
- name: Run shell integration tests against fish
# Run this step even if a previous test step fails
if: matrix.os != 'windows' && (success() || failure())
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
with:
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} -E "package(integration) and test(shell_integration_tests)"
env:
WARP_SHELL_PATH: ${{ steps.echo_shells_unix.outputs.fish_path }}
- name: Upload results of shell integration tests against fish to trunk.io
# Run this step even when the tests fail. Skip if the workflow is cancelled.
if: ${{ matrix.os != 'windows' && !cancelled() }}
continue-on-error: true
uses: trunk-io/analytics-uploader@95a0fb8b29e45b6068304261fb518644b426a803 # v2.0.8
with:
junit-paths: target/nextest/ci/junit.xml
cli-version: 0.12.5
org-slug: warp
token: ${{ secrets.TRUNK_API_TOKEN }}
tags: type=integration,category=fish
variant: ${{ matrix.os }}
use-cache: true
- name: Run shell integration tests against zsh
# Run this step even if a previous test step fails
if: matrix.os != 'windows' && (success() || failure())
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
with:
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} -E "package(integration) and test(shell_integration_tests)"
env:
WARP_SHELL_PATH: ${{ steps.echo_shells_unix.outputs.zsh_path }}
- name: Upload results of shell integration tests against zsh to trunk.io
# Run this step even when the tests fail. Skip if the workflow is cancelled.
if: ${{ matrix.os != 'windows' && !cancelled() }}
continue-on-error: true
uses: trunk-io/analytics-uploader@95a0fb8b29e45b6068304261fb518644b426a803 # v2.0.8
with:
junit-paths: target/nextest/ci/junit.xml
cli-version: 0.12.5
org-slug: warp
token: ${{ secrets.TRUNK_API_TOKEN }}
tags: type=integration,category=zsh
variant: ${{ matrix.os }}
use-cache: true
- name: Run shell integration tests against powershell
# Run this step even if a previous test step fails
if: matrix.os != 'windows' && (success() || failure())
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
with:
run: cargo nextest run ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} -E "package(integration) and test(shell_integration_tests)"
env:
WARP_SHELL_PATH: ${{ steps.echo_shells_unix.outputs.powershell_path }}
- name: Upload results of shell integration tests against powershell to trunk.io
# Run this step even when the tests fail. Skip if the workflow is cancelled.
if: ${{ matrix.os != 'windows' && !cancelled() }}
continue-on-error: true
uses: trunk-io/analytics-uploader@95a0fb8b29e45b6068304261fb518644b426a803 # v2.0.8
with:
junit-paths: target/nextest/ci/junit.xml
cli-version: 0.12.5
org-slug: warp
token: ${{ secrets.TRUNK_API_TOKEN }}
tags: type=integration,category=powershell
variant: ${{ matrix.os }}
use-cache: true
# Run doctests explicitly, as nextest doesn't yet support running them.
# See: https://github.com/nextest-rs/nextest/issues/16
- name: Run doc tests
# Run this step even if a previous test step fails
if: success() || failure()
run: cargo test ${{ env.WORKSPACE_TEST_ARGS }} ${{ matrix.extra_test_args }} --doc
# Run warp_completer tests with the "v2" (completions-on-js) flag enabled. We do this to
# ensure that the v2 completions implementation doesn't regress/rot while it's development
# is paused.
- name: Run completions-on-js tests
# Run this step even if a previous test step fails
if: matrix.os != 'windows' && (success() || failure())
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
with:
run: cargo nextest run --locked -p warp_completer --features v2
# This is longer than we like and temporary until we speed up integration tests
# The maximum timeout for the entire job is 6 hours:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes
database-migration:
name: Database Migration (Diesel)
timeout-minutes: 5
runs-on: ubuntu-latest
needs: params
if: ${{ needs.params.outputs.affects-database-schema == 'true' }}
steps:
- name: Checkout sources
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 # v1.18.1
- name: Install diesel_cli
run: |
cargo binstall diesel_cli
- name: Run all migrations on empty file
run: |
cp crates/persistence/src/schema.rs old-schema.rs
diesel migration run --database-url="test.sqlite" --migration-dir="crates/persistence/migrations"
- name: Regenerate schema and check if it is consistent with the schema at HEAD
shell: bash
run: |
diff -u old-schema.rs <(diesel print-schema --database-url="test.sqlite")
lints:
name: Formatting + Clippy (${{ matrix.name }})
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
- os: "macos"
name: "MacOS"
runner: ${{ fromJSON(needs.params.outputs.macos-runner) }}
is_self_hosted: ${{ contains(fromJSON(needs.params.outputs.macos-runner), 'self-hosted') }}
null_device: "/dev/null"
clippy_excludes: "--exclude warp_completer"
- os: "linux"
name: "Linux"
# Use a larger (16 core, 64GB ram) runner on Linux to speed up execution time.
# https://github.com/warpdotdev/warp-internal/settings/actions/runners
runner: ubuntu-latest-large
# We don't (yet) have any self-hosted Linux runners.
is_self_hosted: false
null_device: "/dev/null"
clippy_excludes: "--exclude warp_completer"
- os: "windows"
name: "Windows"
runner: windows-latest-large
# We don't (yet) have any self-hosted Windows runners.
is_self_hosted: false
null_device: "NUL"
clippy_excludes: "--exclude warp_js --exclude command-signatures-v2"
runs-on: ${{ matrix.runner }}
needs: params
# if: ${{ needs.params.outputs.affects-rust-sources == 'true' }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: ./.github/actions/prepare_environment
with:
target_os: ${{ matrix.os }}
is_self_hosted: ${{ matrix.is_self_hosted }}
- name: Ensure cargo.lock is up-to-date
run:
cargo metadata --locked --format-version=1 > ${{ matrix.null_device }} || (echo "::error::Cargo.lock is out-of-date with Cargo.toml. Run 'cargo check' to update." && exit 1)
- name: Run cargo fmt
run: cargo fmt --check
- name: Run cargo clippy
shell: bash
run: |
set -e
# On Windows, omit --all-features because pprof and related profiling features don't compile.
if [ "${{ matrix.os }}" = "windows" ]; then
cargo clippy --locked --workspace ${{ matrix.clippy_excludes }} --all-targets --tests -- -D warnings
else
cargo clippy --locked --workspace ${{ matrix.clippy_excludes }} --all-targets --all-features --tests -- -D warnings
# Run clippy on warp_completer with default, rather than all features enabled, because there is
# feature-gated logic for the WIP completions-on-js implementation.
cargo clippy --locked -p warp_completer --all-targets --tests -- -D warnings
fi
env:
# Attach the GitHub auth token so that requests to the GitHub API
# don't get rate limited during compilation (e.g.: retrieving
# Sentry SDK binary releases).
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run clang-format
if: ${{ matrix.os == 'macos' }}
run: |
if [[ ! -d $(brew --prefix clang-format) ]]; then
brew install clang-format
fi
./script/run-clang-format.py -r --extensions 'c,h,cpp,m' ./crates/warpui/src/ ./app/src/
general-lint:
name: Miscellaneous checks
timeout-minutes: 10
strategy:
fail-fast: false
runs-on: ubuntu-latest
needs: params
steps:
- name: Checkout sources
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
# Only cache runs on the master branch (caches on feature branches
# are not reusable).
save-if: ${{ github.ref == 'refs/heads/master' }}
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 # v1.18.1
- name: Check licenses for dependencies
run: |
cargo binstall --force -y cargo-deny
# Make sure all of our dependencies use licenses that are compatible with
# our usage.
cargo deny -L error check licenses
- name: Check deny.toml / about.toml license sync
run: ./script/check_license_config_sync
- name: Run WGSL formatter
run: |
# note: this matches the version used in script/install_cargo_test_deps...
# if changing here, probably a good idea to change there too to keep dev tools on local ~= CI
cargo install --git https://github.com/wgsl-analyzer/wgsl-analyzer --tag "2025-06-28" wgslfmt && \
find . -name "*.wgsl" -exec wgslfmt --check {} +
- name: Run PSScriptAnalyzer (PowerShell Lint)
run: ./script/lint_powershell -ci
shell: pwsh
- name: Validate repo-sync markers
uses: warpdotdev/repo-sync/actions/validate-markers@main
wasm-lint:
name: Formatting + Clippy (wasm)
timeout-minutes: 20
strategy:
fail-fast: false
runs-on: ${{ fromJSON(needs.params.outputs.wasm-runner) }}
needs: params
steps:
- name: Compute IS_SELF_HOSTED
id: is_self_hosted
run: |
IS_SELF_HOSTED="${{ contains(fromJSON(needs.params.outputs.wasm-runner), 'self-hosted') }}"
echo "value=$IS_SELF_HOSTED" >> $GITHUB_OUTPUT
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: ./.github/actions/prepare_environment
with:
target_os: wasm
is_self_hosted: ${{ steps.is_self_hosted.outputs.value }}
- name: Ensure cargo.lock is up-to-date
run:
cargo metadata --locked --format-version=1 >/dev/null || (echo "::error::Cargo.lock is out-of-date with Cargo.toml. Run 'cargo check' to update." && exit 1)
- name: Run cargo fmt
run: cargo fmt --check
- name: Run cargo clippy
run: |
cargo clippy --locked --target wasm32-unknown-unknown --profile release-wasm-debug_assertions -- -D warnings
check-release-compilation:
name: Verify compilation with release flags (${{ matrix.name }})
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- os: "macos"
name: "MacOS"
runner: ${{ fromJSON(needs.params.outputs.macos-runner) }}
is_self_hosted: ${{ contains(fromJSON(needs.params.outputs.macos-runner), 'self-hosted') }}
null_device: "/dev/null"
- os: "linux"
name: "Linux"
# Use a larger (16 core, 64GB ram) runner on Linux to speed up execution time.
# https://github.com/warpdotdev/warp-internal/settings/actions/runners
runner: ubuntu-latest-large
# We don't (yet) have any self-hosted Linux runners.
is_self_hosted: false
null_device: "/dev/null"
- os: "windows"
name: "Windows"
runner: windows-latest-large
# We don't (yet) have any self-hosted Windows runners.
is_self_hosted: false
null_device: "NUL"
- os: "wasm"
name: "wasm"
runner: ${{ fromJSON(needs.params.outputs.wasm-runner) }}
is_self_hosted: ${{ contains(fromJSON(needs.params.outputs.wasm-runner), 'self-hosted') }}
null_device: "/dev/null"
runs-on: ${{ matrix.runner }}
needs: params
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: ./.github/actions/prepare_environment
with:
target_os: ${{ matrix.os }}
is_self_hosted: ${{ matrix.is_self_hosted }}
- name: Verify compilation with release flags
shell: bash
run: |
if ${{ matrix.os == 'wasm' }}; then
./script/wasm/bundle --bin dev --nouniversal --check-only
else
./script/bundle --bin dev --nouniversal --check-only
fi
env:
# Attach the GitHub auth token so that requests to the GitHub API
# don't get rate limited during compilation (e.g.: retrieving
# Sentry SDK binary releases).
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# A final job that collects the results of all of the parallel CI jobs and
# makes sure that all of them pass.
#
# This allows us to tell GitHub that the only required check is this "gather"
# job, simplifying the process of adding and removing jobs to the CI
# workflow.
ci-result:
name: Check CI results
timeout-minutes: 3
runs-on: ubuntu-latest
# Always run this job, as it needs to check the results of all of the other
# jobs. If we skipped CI checks (e.g. on a draft PR), also skip this one.
if: ${{ !cancelled() && needs.params.result != 'skipped' }}
needs:
- params
- database-migration
- tests
- lints
- wasm-lint
- general-lint
- check-release-compilation
steps:
- name: Check CI results
run: |
# Convert needs context to JSON and check required jobs
echo '${{ toJSON(needs) }}' | jq -r '
# Get all jobs except database-migration
to_entries |
map(select(.key != "database-migration")) |
.[] |
if .value.result != "success" then
"::error::Required job \(.key) failed or was skipped (status: \(.value.result))"
else
empty
end
' | {
if read -r error; then
echo "$error"
exit 1
fi
}
# Special handling for conditional database-migration job.
affects_schema="${{ needs.params.outputs.affects-database-schema }}"
migration_result="${{ needs.database-migration.result }}"
if [[ "$affects_schema" == "true" && "$migration_result" != "success" ]]; then
echo "::error::Database migration job failed or was skipped when it should have run (status: $migration_result)"
exit 1
elif [[ "$affects_schema" != "true" && "$migration_result" != "skipped" ]]; then
echo "::error::Database migration job should have been skipped but wasn't (status: $migration_result)"
exit 1
fi
echo "All jobs completed successfully!"
+75
View File
@@ -0,0 +1,75 @@
# ======================================================================================
# Workflow: Close Stale Fix PRs
# ======================================================================================
# Usage:
# - This workflow runs daily and closes agent-opened CI fix PRs that have been
# open for more than 3 days.
#
# Expected Output:
# - Any open PR whose branch matches the oz-agent-fix/run-* convention and that
# was opened more than 3 days ago will be closed with an explanatory comment.
#
# ======================================================================================
name: Close Stale Fix PRs
on:
schedule:
- cron: '0 12 * * *' # 8am EST
workflow_dispatch:
jobs:
close-stale-fix-prs:
runs-on: ubuntu-latest
steps:
- name: Close Stale Fix PRs
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { owner, repo } = context.repo;
const staleCutoffMs = 3 * 24 * 60 * 60 * 1000; // 3 days in milliseconds
const now = Date.now();
// Paginate through all open PRs to find ones matching the branch convention
const openPRs = await github.paginate(github.rest.pulls.list, {
owner,
repo,
state: 'open',
per_page: 100,
});
const staleFixPRs = openPRs.filter(pr => {
const branchMatches = /^oz-agent-fix\/run-/.test(pr.head.ref);
const openedAt = new Date(pr.created_at).getTime();
const isStale = (now - openedAt) > staleCutoffMs;
return branchMatches && isStale;
});
if (staleFixPRs.length === 0) {
console.log('No stale fix PRs found.');
return;
}
console.log(`Found ${staleFixPRs.length} stale fix PR(s). Closing them...`);
for (const pr of staleFixPRs) {
const ageMs = now - new Date(pr.created_at).getTime();
const ageDays = Math.floor(ageMs / (24 * 60 * 60 * 1000));
console.log(`Closing PR #${pr.number} (branch: ${pr.head.ref}, open for ${ageDays} day(s)): ${pr.title}`);
await github.rest.issues.createComment({
owner,
repo,
issue_number: pr.number,
body: `Closing this automated CI fix PR because it has been open for more than 3 days (${ageDays} day(s)) without being merged. Please review the underlying CI failures manually if they are still relevant.`,
});
await github.rest.pulls.update({
owner,
repo,
pull_number: pr.number,
state: 'closed',
});
}
console.log('Done.');
@@ -0,0 +1,16 @@
name: Comment on Unready Assigned Issue (Local)
on:
issues:
types: [assigned]
concurrency:
group: comment-on-unready-assigned-issue-${{ github.event.issue.number || github.run_id }}
cancel-in-progress: false
jobs:
comment_when_unready:
if: github.event.assignee.login == 'oz-agent' && !contains(github.event.issue.labels.*.name, 'ready-to-spec') && !contains(github.event.issue.labels.*.name, 'ready-to-implement')
permissions:
issues: write
uses: warpdotdev/oz-for-oss/.github/workflows/comment-on-unready-assigned-issue.yml@main
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
@@ -0,0 +1,34 @@
name: Create Implementation from Issue (Local)
on:
issues:
types: [assigned, labeled]
issue_comment:
types: [created]
workflow_dispatch:
inputs:
issue_number:
description: Issue number to create an implementation for
required: true
type: string
concurrency:
group: create-implementation-issue-${{ github.event.issue.number || inputs.issue_number || github.run_id }}
cancel-in-progress: false
jobs:
# Mention, bot, event-type, and trust gates all live in the reusable
# workflow (``create-implementation-from-issue.yml``). This adapter
# exists only to subscribe to the GitHub events that can trigger
# implementation work (``issues`` assign/label by a maintainer, or a
# trusted ``@oz-agent`` issue comment) and delegate them through
# ``workflow_call``.
create_implementation:
permissions:
contents: write
issues: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/create-implementation-from-issue.yml@main
with:
issue_number: ${{ github.event.inputs.issue_number || '' }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
@@ -0,0 +1,34 @@
name: Create Spec from Issue (Local)
on:
issues:
types: [assigned, labeled]
issue_comment:
types: [created]
workflow_dispatch:
inputs:
issue_number:
description: Issue number to create a spec for
required: true
type: string
concurrency:
group: create-spec-issue-${{ github.event.issue.number || inputs.issue_number || github.run_id }}
cancel-in-progress: false
jobs:
# Mention, bot, event-type, and trust gates all live in the reusable
# workflow (``create-spec-from-issue.yml``). This adapter exists only
# to subscribe to the GitHub events that can trigger spec creation
# (``issues`` assign/label by a maintainer, or a trusted
# ``@oz-agent`` issue comment) and delegate them through
# ``workflow_call``.
create_spec:
permissions:
contents: write
issues: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/create-spec-from-issue.yml@main
with:
issue_number: ${{ github.event.inputs.issue_number || '' }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,54 @@
# A workflow to cut a new release candidate (i.e.: .stable_01) on the current
# release branch.
#
# The channel will be automatically determined from the branch name (i.e.: when
# run on a stable_release/* branch, it will assume it is building a new "stable"
# channel candidate).
name: Cut New Release Candidate
on:
workflow_dispatch:
jobs:
compute_channel:
name: Compute release channel
runs-on: ubuntu-latest
outputs:
channel: ${{ steps.compute-channel.outputs.channel }}
steps:
- name: "Compute release channel"
id: compute-channel
run: |
# Check whether the current branch name starts with "some_release/",
# and if so, extract the value of "some" into the CHANNEL variable,
# discarding the rest of the branch name.
CHANNEL="$(echo $GITHUB_REF_NAME | sed -r 's|^(\w+)_release/.*$|\1|')"
# If the sed expression doesn't match the input, it will write out the
# input, unmodified.
if [[ $CHANNEL == $GITHUB_REF_NAME ]]; then
echo "::error::Can only create new release candidates on a release branch" && exit 1
fi
echo "channel=$CHANNEL" >> $GITHUB_OUTPUT
shell: bash
create_release_candidate:
name: Create Release Candidate
uses: ./.github/workflows/create_release.yml
needs: compute_channel
with:
channel: ${{ needs.compute_channel.outputs.channel }}
secrets: inherit
update_channel_versions:
name: Update channel_versions.json
needs:
- create_release_candidate
runs-on: ubuntu-latest
steps:
- name: Invoke update workflow in channel-versions repository
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
with:
repository: warpdotdev/channel-versions
token: ${{ secrets.CHANNEL_VERSIONS_REPOSITORY_DISPATCH_TOKEN }}
event-type: update-channel-versions
+93
View File
@@ -0,0 +1,93 @@
# A workflow to cut new releases (i.e.: .stable_00) for various release
# channels.
#
# Supports cutting releases for nightly release channels, weekly release
# channels, or all release channels. Releases run in parallel where able.
name: Cut New Releases
on:
schedule:
# Run this job every morning at 3am EST.
- cron: "0 8 * * *"
workflow_dispatch:
inputs:
targets:
type: choice
description: Which releases to build. Nightly = dev; Weekly = preview/stable.
options:
- nightly
- weekly
- all
env:
CONFIG_FILE: ".github/workflows/release_configurations.json"
# The day of the week when the weekly release should be cut. This is a value
# from 1-7, with 1 representing Monday, 2 representing Tuesday, etc.
WEEKLY_RELEASE_DAY: 3 # Cut weekly builds on Wednesdays.
jobs:
get_config:
name: Get release configuration
runs-on: ubuntu-latest
env:
SCHEDULE: ${{ github.event.schedule }}
TARGETS: ${{ inputs.targets }}
outputs:
channels: ${{ steps.get-config.outputs.channels }}
steps:
- name: Check for master branch
run: |
[ $GITHUB_REF == "refs/heads/master" ] || (echo "::error::Can only cut new releases on the master branch" && exit 1)
shell: bash
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- id: get-config
run: |
# Check to see if this was auto-run as a cron job. If so, set the
# value of TARGETS based on whether the current day of the week
# is when we build weekly releases (in addition to nightly ones).
if [[ ! -z "$SCHEDULE" ]]; then
if [[ "$(date +%u)" == "$WEEKLY_RELEASE_DAY" ]]; then
TARGETS="all"
else
TARGETS="nightly"
fi
fi
echo ::echo::on
if [[ "$TARGETS" == "all" ]]; then
TARGETS="$(jq -rc '[.channels[] | .type] | unique' $CONFIG_FILE)"
else
TARGETS="[\"$TARGETS\"]"
fi
export CHANNELS="$(jq -rc '[.channels[] | select(.type | inside($ENV.TARGETS)) | .channel]' $CONFIG_FILE)"
echo "channels=$CHANNELS" >> $GITHUB_OUTPUT
# CHANNELS_INCLUDE_AUTOPUSH=$(jq -rc '[.channels[] | select(.channel | inside($ENV.CHANNELS)) | .is_autopush] | any' $CONFIG_FILE)
# echo "channels-include-autopush=$CHANNELS_INCLUDE_AUTOPUSH" >> $GITHUB_OUTPUT
echo ::echo::off
shell: bash
create_release:
name: Create Release
uses: ./.github/workflows/create_release.yml
needs: get_config
strategy:
fail-fast: false
matrix:
channel: ${{ fromJSON(needs.get_config.outputs.channels) }}
with:
channel: ${{ matrix.channel }}
secrets: inherit
update_channel_versions:
name: Update channel_versions.json
needs:
- create_release
runs-on: ubuntu-latest
steps:
- name: Invoke update workflow in channel-versions repository
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
with:
repository: warpdotdev/channel-versions
token: ${{ secrets.CHANNEL_VERSIONS_REPOSITORY_DISPATCH_TOKEN }}
event-type: update-channel-versions
+111
View File
@@ -0,0 +1,111 @@
# A workflow to delete (soft-delete) a release branch by renaming it.
#
# The branch will be renamed from its original name to deleted/{original_name}.
# For example, stable_release/v0.2025.01.01.00.00 becomes
# deleted/stable_release/v0.2025.01.01.00.00.
#
# This workflow will fail if:
# - The branch doesn't start with a release channel prefix
# (i.e.: stable_release/, preview_release/, or dev_release/)
# - The release has an entry in channel_versions.json (i.e., it's deployed)
name: Delete Release
on:
workflow_dispatch:
inputs:
branch:
description: 'The release branch to delete (e.g., stable_release/v0.2025.01.01.00.00.stable)'
required: true
type: string
confirmation:
description: 'Type DELETE to confirm'
required: true
type: string
jobs:
delete_release:
name: Delete Release Branch
runs-on: ubuntu-latest
steps:
- name: Verify confirmation
run: |
if [[ "${{ inputs.confirmation }}" != "DELETE" ]]; then
echo "::error::You must type DELETE to confirm branch deletion. \
If you're unsure about deleting, ask a TL in #oncall-client before running this workflow."
exit 1
fi
shell: bash
- name: Validate release branch
id: validate
run: |
BRANCH_NAME="${{ inputs.branch }}"
# Validate branch is a release branch and extract the channel
if [[ ! "$BRANCH_NAME" =~ ^(stable|preview|dev)_release/ ]]; then
echo "::error::Branch '$BRANCH_NAME' is not a release branch." && exit 1
fi
CHANNEL="${BASH_REMATCH[1]}"
# Extract the version base from the branch name
# e.g., "stable_release/v0.2025.01.26.12.30.stable" -> "v0.2025.01.26.12.30.stable"
VERSION_BASE="$(echo $BRANCH_NAME | sed -r 's|^\w+_release/(.*)$|\1|')"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "new_branch_name=deleted/$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "channel=$CHANNEL" >> $GITHUB_OUTPUT
echo "version_base=$VERSION_BASE" >> $GITHUB_OUTPUT
shell: bash
- name: Check if release has changelog in channel_versions.json
id: check_deployed
env:
CHANNEL: ${{ steps.validate.outputs.channel }}
VERSION_BASE: ${{ steps.validate.outputs.version_base }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Fetch channel_versions.json from the channel-versions repository
CHANNEL_VERSIONS=$(gh api repos/warpdotdev/channel-versions/contents/channel_versions.json --jq '.content' | base64 -d)
# Fail fast if the channel section is missing from channel_versions.json
CHANNEL_EXISTS=$(echo "$CHANNEL_VERSIONS" | jq -r --arg channel "$CHANNEL" 'has("changelogs") and (.changelogs | has($channel))')
if [[ "$CHANNEL_EXISTS" != "true" ]]; then
echo "::error::channel_versions.json is missing the 'changelogs.$CHANNEL' section. Cannot safely determine if release is deployed."
exit 1
fi
# Check if any key in the changelogs section for this channel starts with the version base
# Keys are like "v0.2025.01.26.12.30.stable_01" and version_base is "v0.2025.01.26.12.30.stable"
MATCHING_ENTRIES=$(echo "$CHANNEL_VERSIONS" | jq -r --arg channel "$CHANNEL" --arg version "$VERSION_BASE" \
'.changelogs[$channel] | keys[] | select(startswith($version))')
if [[ -n "$MATCHING_ENTRIES" ]]; then
echo "::error::Cannot delete release branch: version '$VERSION_BASE' has changelog entries in channel_versions.json:"
echo "$MATCHING_ENTRIES"
exit 1
fi
echo "::notice::Release has no changelog in channel_versions.json, safe to delete."
shell: bash
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.branch }}
fetch-depth: 0
- name: Rename branch to deleted/
env:
BRANCH_NAME: ${{ steps.validate.outputs.branch_name }}
NEW_BRANCH_NAME: ${{ steps.validate.outputs.new_branch_name }}
run: |
echo "Renaming branch '$BRANCH_NAME' to '$NEW_BRANCH_NAME'"
# Push the current HEAD to the new branch name
git push origin "HEAD:refs/heads/$NEW_BRANCH_NAME"
# Delete the original branch
git push origin --delete "$BRANCH_NAME"
echo "::notice::Successfully renamed branch '$BRANCH_NAME' to '$NEW_BRANCH_NAME'"
shell: bash
@@ -0,0 +1,69 @@
name: "Run Docubot on @docubot mention"
on:
# These triggers are currently disabled because they cause workflow runs for ALL
# comments in the org, even though the job only executes when @docubot is mentioned,
# which is noisy.
# issue_comment:
# types: [created]
# pull_request_review_comment:
# types: [created]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to run Docubot on (leave empty to run on current branch)'
required: false
type: string
prompt:
description: Prompt to send to Docubot
required: true
default: "Analyze this PR for documentation needs"
warp_channel:
type: choice
description: Warp release channel
required: true
default: dev
options:
- dev
- preview
- stable
profile_id:
description: Warp profile ID
required: false
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
actions: read
jobs:
run_docubot:
if: >
(
contains(github.event.comment.body, '@docubot') || inputs.prompt
)
&& github.actor != 'github-actions[bot]'
runs-on: namespace-profile-ubuntu-20-04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
# Check out the appropriate branch based on trigger type
# TODO: do this in sdk?
ref: >
${{
github.event_name == 'workflow_dispatch'
&& (inputs.pr_number != '' && format('refs/pull/{0}/head', inputs.pr_number) || github.ref)
|| (
github.event_name == 'pull_request_review_comment'
&& format('refs/pull/{0}/head', github.event.pull_request.number)
|| format('refs/pull/{0}/head', github.event.issue.number)
)
}}
- name: Call Docubot
uses: ./.github/actions/docubot
with:
prompt: ${{ github.event.comment.body || inputs.prompt}}
warp_api_key: ${{ secrets.WARP_DEV_API_KEY }}
warp_channel: ${{ inputs.warp_channel || 'dev' }}
profile_id: ${{ inputs.profile_id || vars.WARP_DEV_API_PROFILE_ID }}
github_token: ${{ secrets.PEI_GH_TOKEN_PLS_DEL }}
@@ -0,0 +1,39 @@
name: Enforce PR Issue State Logic
on:
workflow_call:
inputs:
pr_number:
description: Pull request number to evaluate
required: true
type: string
requester:
description: Login of the user whose action triggered enforcement, if any
required: false
default: ""
type: string
secrets:
OZ_MGMT_GHA_APP_ID:
required: true
OZ_MGMT_GHA_PRIVATE_KEY:
required: true
OSS_WARP_API_KEY:
required: true
outputs:
allow_review:
description: Whether downstream PR hooks may continue after enforcement.
value: ${{ jobs.enforce_issue_state.outputs.allow_review }}
jobs:
enforce_issue_state:
name: Enforce PR issue state
permissions:
contents: read
issues: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/enforce-pr-issue-state.yml@main
with:
pr_number: ${{ inputs.pr_number }}
requester: ${{ inputs.requester }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
+261
View File
@@ -0,0 +1,261 @@
name: Feature Flag Cleanup
on:
schedule:
- cron: '0 15 * * *' # 10am EST
workflow_dispatch:
# Default to a read-only token. Jobs that need to push or open PRs widen
# permissions explicitly below.
permissions:
contents: read
jobs:
analyze:
name: Analyze feature flags
runs-on: namespace-profile-ubuntu-small
permissions:
contents: read
pull-requests: read
outputs:
flag_name: ${{ steps.select_flag.outputs.flag_name }}
cargo_flag: ${{ steps.select_flag.outputs.cargo_flag }}
reviewers: ${{ steps.select_flag.outputs.reviewers }}
analyzed_sha: ${{ steps.record_sha.outputs.analyzed_sha }}
artifact_url: ${{ steps.upload_feature_flag_log.outputs.artifact-url }}
steps:
- name: Check out code
uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1
with:
fetch-depth: 0
- name: Record analyzed commit
id: record_sha
run: |
echo "analyzed_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Find old feature flags
uses: warpdotdev/oz-agent-action@main
with:
prompt: |
Your task is to find and list any feature flags which have been enabled by default for more than 3 months.
There will always be at least one such flag.
## Context
Feature flags are defined in warp_core/src/features.rs. They're enabled by default in app/Cargo.toml, using the default feature list. The mapping between Cargo features and app features is in the enabled_features function of app/src/lib.rs.
## Recommended Procedure
1. Use `git blame` on the Cargo.toml file to identify when each feature flag was enabled by default.
2. Read the enabled_features function to map Cargo features to app features.
3. Write features that have been enabled by default for more than 3 months to the output file.
You may create temporary files to store useful results, and write helper scripts for subtasks. It is not necessary to do everything in one shot.
## Result Format
List the old feature flags in ${{ runner.temp }}/flags_to_cleanup.jsonl, in this format (one flag per line):
{ "flag_name": "MyFlag", "cargo_flag": "my_flag", "date_enabled": "2025-02-21", "enabling_commit": "aad3293b8fe" }
## Reminders
* Fields in the output JSONL file have these meanings:
* "flag_name" - the name of the FeatureFlag enum variant
* "cargo_flag" - the name of the flag used in Cargo.toml
* "date_enabled" - the date on which the feature flag was enabled by default
* "enabling_commit" - the Git commit in which the feature flag was enabled by default
* You are running as part of a GitHub automation and must not commit or push any changes. Another agent will process the file you produce.
warp_api_key: ${{ secrets.WARP_API_KEY }}
share: team
- name: Upload feature flag log
id: upload_feature_flag_log
uses: namespace-actions/upload-artifact@f6ccaacc655aec41b93af180d1d7eef21af862d2 # v1.0.3
with:
name: flags-to-cleanup
path: ${{ runner.temp }}/flags_to_cleanup.jsonl
# As we test out the workflow, only clean up one flag at a time.
# We could also pick several flags, or fan out jobs for every single one.
- name: Select a flag to clean up
id: select_flag
env:
GH_TOKEN: ${{ github.token }}
run: |
cleanup_log="$RUNNER_TEMP/flags_to_cleanup.jsonl"
# Skip over flags that are also used to enable/disable functionality at runtime.
excluded_flags='["CreatingSharedSessions", "ViewingSharedSessions", "AgentMode"]'
flag_name=""
cargo_flag=""
# Iterate flags in order (oldest first) and pick the first one that is not
# excluded and does not already have an open cleanup PR. Sort by
# date_enabled here rather than relying on the analysis agent to emit
# the JSONL in any particular order.
while IFS= read -r candidate; do
[ -z "$candidate" ] && continue
candidate_flag="$(jq -r '.flag_name' <<< "$candidate")"
if [ "$(jq -n --arg flag "$candidate_flag" --argjson excluded "$excluded_flags" '$excluded | index($flag) != null')" = "true" ]; then
echo "Skipping $candidate_flag: in excluded list"
continue
fi
candidate_branch="oz-agent/cleanup-feature-flag-$candidate_flag"
existing_pr="$(gh pr list --state open --head "$candidate_branch" --json number --jq '.[0].number')"
if [ -n "$existing_pr" ] && [ "$existing_pr" != "null" ]; then
echo "Skipping $candidate_flag: open cleanup PR #$existing_pr already exists on $candidate_branch"
continue
fi
flag_name="$candidate_flag"
cargo_flag="$(jq -r '.cargo_flag' <<< "$candidate")"
break
done < <(jq -c -s 'sort_by(.date_enabled) | .[]' "$cleanup_log")
echo "flag_name=$flag_name" >> "$GITHUB_OUTPUT"
echo "cargo_flag=$cargo_flag" >> "$GITHUB_OUTPUT"
echo "Cleaning up $flag_name ($cargo_flag)"
if [ -z "$flag_name" ] || [ "$flag_name" = "null" ]; then
echo "No flag selected for cleanup"
echo "reviewers=" >> "$GITHUB_OUTPUT"
else
enabling_commit="$(jq -r -cs --arg flag "$flag_name" '.[] | select(.flag_name == $flag) | .enabling_commit' "$cleanup_log")"
committer_username=""
# Resolve the GitHub username of the commit author directly via the
# commits API. This is more reliable than mapping a commit email to
# a GitHub user, since commit emails are often noreply addresses or
# otherwise unsearchable.
if [ -n "$enabling_commit" ] && [ "$enabling_commit" != "null" ]; then
committer_username="$(gh api "repos/${{ github.repository }}/commits/$enabling_commit" --jq '.author.login // ""' 2>/dev/null || echo "")"
fi
default_reviewers="bennavetta"
# Verify the committer is still a collaborator before assigning as reviewer.
if [ -n "$committer_username" ] && gh api "repos/${{ github.repository }}/collaborators/$committer_username" --verbose 2>/dev/null; then
echo "Flag originally enabled by $committer_username"
echo "reviewers=$committer_username,$default_reviewers" >> "$GITHUB_OUTPUT"
elif [ -n "$committer_username" ]; then
echo "$committer_username is no longer a collaborator, using fallback"
echo "reviewers=$default_reviewers" >> "$GITHUB_OUTPUT"
else
echo "Could not determine flag committer, using fallback"
echo "reviewers=$default_reviewers" >> "$GITHUB_OUTPUT"
fi
fi
cleanup:
name: Run cleanup agent
needs: analyze
if: ${{ needs.analyze.outputs.flag_name && needs.analyze.outputs.flag_name != 'null' }}
runs-on: namespace-profile-ubuntu-small
permissions:
contents: read
steps:
- name: Check out code
uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1
with:
ref: ${{ needs.analyze.outputs.analyzed_sha }}
fetch-depth: 0
- name: Setup Rust cache
uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 # v1.4.2
with:
cache: rust
- name: Clean up the unused feature flag
id: cleanup_agent
uses: warpdotdev/oz-agent-action@main
with:
prompt: |
The feature flag ${{ needs.analyze.outputs.flag_name }} is now enabled by default.
Clean up all references to this flag, modifying code to always assume it is enabled. Ensure that the code is correctly formatted and that tests still pass.
Finally, remove the flag from the `FeatureFlag` enum, and remove the equivalent ${{ needs.analyze.outputs.cargo_flag }} feature in app/Cargo.toml
You are running as part of a GitHub automation that runs with a read-only token and will package your changes into a patch for a separate job to commit. Do not create a branch, do not commit, do not push, do not create a PR, and do not call `gh`. Leave your changes in the working tree only.
share: team
warp_api_key: ${{ secrets.WARP_API_KEY }}
- name: Generate cleanup patch
env:
ANALYZED_SHA: ${{ needs.analyze.outputs.analyzed_sha }}
run: |
# If the cleanup agent made any local commits, undo them while keeping
# the changes in the working tree, so the resulting patch reflects the
# full set of changes relative to the analyzed commit.
git reset --mixed "$ANALYZED_SHA"
# Stage all changes (modified, new, deleted) so the patch is complete.
git add -A
git diff --staged --binary > "$RUNNER_TEMP/cleanup.patch"
if [ ! -s "$RUNNER_TEMP/cleanup.patch" ]; then
echo "Cleanup agent produced no changes" >&2
exit 1
fi
- name: Upload cleanup patch
uses: namespace-actions/upload-artifact@f6ccaacc655aec41b93af180d1d7eef21af862d2 # v1.0.3
with:
name: cleanup-patch
path: ${{ runner.temp }}/cleanup.patch
create_pr:
name: Create cleanup PR
needs: [analyze, cleanup]
if: ${{ needs.analyze.outputs.flag_name && needs.analyze.outputs.flag_name != 'null' }}
runs-on: namespace-profile-ubuntu-small
permissions:
contents: write
pull-requests: write
steps:
- name: Check out code
uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1
with:
ref: ${{ needs.analyze.outputs.analyzed_sha }}
fetch-depth: 0
- name: Download cleanup patch
uses: namespace-actions/download-artifact@7cbad919e4b0e09f17e9d6311a444ff002992b5b # v2.0.1
with:
name: cleanup-patch
path: ${{ runner.temp }}
- name: Apply cleanup patch
run: |
git apply --binary --whitespace=nowarn "$RUNNER_TEMP/cleanup.patch"
- name: Create Pull Request
id: create_pr
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ github.token }}
base: ${{ github.event.repository.default_branch }}
commit-message: "Clean up ${{ needs.analyze.outputs.flag_name }} feature flag"
branch: "oz-agent/cleanup-feature-flag-${{ needs.analyze.outputs.flag_name }}"
author: "Oz Agent <oz-agent@warp.dev>"
delete-branch: true
reviewers: ${{ needs.analyze.outputs.reviewers }}
title: "Clean up ${{ needs.analyze.outputs.flag_name }} feature flag"
body: |
Automated cleanup of the `${{ needs.analyze.outputs.flag_name }}` feature flag.
This PR was generated by the feature flag cleanup workflow.
- run: |
echo "Full feature flag analysis results: ${{ needs.analyze.outputs.artifact_url }}"
echo "Pull request created: ${{ steps.create_pr.outputs.pull-request-url }}"
- name: Send Slack notification
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
if: ${{ steps.create_pr.outputs.pull-request-operation == 'created' }}
with:
method: chat.postMessage
token: ${{ secrets.ACTION_MONITORING_SLACK }}
payload: |
channel: "#oncall-client"
# Follows https://api.slack.com/reference/surfaces/formatting#mentioning-users.
# S09SSGE729E is the user group ID for @eng-warp-3.
text: "🧹 New feature flag cleanup PR for `${{ needs.analyze.outputs.flag_name }}`: ${{ steps.create_pr.outputs.pull-request-url }}! <!subteam^S09SSGE729E> please review\nSee logs at https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
@@ -0,0 +1,26 @@
on:
push:
branches:
# Potentially run this workflow whenever the master branch changes in,
# order to update the cache if necessary.
- master
paths:
# We only need to run this if there were changes to files that affect
# the cache key.
- 'Cargo.lock'
- '**/Cargo.toml'
- '.cargo/config.toml'
- 'rust-toolchain.toml'
# Run once per day to ensure the cache is populated even if we haven't
# modified Cargo.lock or Cargo.toml in a while.
schedule:
- cron: "0 8 * * 1-5" # Run every weekday at 3am EST.
workflow_dispatch:
name: Populate Build Cache
jobs:
populate_build_cache:
name: CI
uses: ./.github/workflows/ci.yml
secrets: inherit
@@ -0,0 +1,44 @@
{
"documentation": "See the README.md file in this directory.",
"channels": [
{
"channel": "dev",
"type": "nightly",
"is_prerelease": true,
"is_autopush": true,
"release_base_name": "Dev Release",
"release_body_text": "Nightly Warp Dev release",
"sentry_project": "warp-client-dev",
"sentry_environment": "dev_release",
"changelog_slack_channel": "#dev-beta-changelogs",
"gcs_cache_control_value": "private, max-age=604800, immutable",
"web_gcs_bucket_prefix": "warp-server-staging"
},
{
"channel": "preview",
"type": "weekly",
"is_prerelease": false,
"is_autopush": false,
"release_base_name": "Preview Release",
"release_body_text": "Warp Preview release",
"sentry_project": "warp-client-beta-stable",
"sentry_environment": "preview_release",
"changelog_slack_channel": "#dev-beta-changelogs",
"gcs_cache_control_value": "public, max-age=604800, immutable",
"web_gcs_bucket_prefix": "warp"
},
{
"channel": "stable",
"type": "weekly",
"is_prerelease": false,
"is_autopush": false,
"release_base_name": "Stable Release",
"release_body_text": "Warp Stable release",
"sentry_project": "warp-client-beta-stable",
"sentry_environment": "stable_release",
"changelog_slack_channel": "#release",
"gcs_cache_control_value": "public, max-age=604800, immutable",
"web_gcs_bucket_prefix": "warp"
}
]
}
@@ -0,0 +1,20 @@
name: Remove Stale Issue Labels on Plan Approved (Local)
on:
pull_request_target:
types: [labeled]
concurrency:
group: remove-stale-labels-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
jobs:
remove_stale_labels:
if: github.event.label.name == 'plan-approved'
permissions:
contents: read
issues: write
pull-requests: read
uses: warpdotdev/oz-for-oss/.github/workflows/remove-stale-issue-labels-on-plan-approved.yml@main
with:
pr_number: ${{ github.event.pull_request.number }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
+74
View File
@@ -0,0 +1,74 @@
name: Repo Sync
on:
push:
branches: [master]
pull_request:
types: [closed, opened, synchronize, edited, labeled]
branches: [master]
workflow_dispatch:
inputs:
action:
description: "Which action to run"
required: true
type: choice
options: [sync, escalation]
jobs:
sync:
if: github.event_name == 'push' || inputs.action == 'sync'
uses: warpdotdev/repo-sync/.github/workflows/sync.yml@main
with:
repo_sync_ref: main
app_id: ${{ vars.REPO_SYNC_APP_ID }}
public_repo: warpdotdev/warp
private_repo: warpdotdev/warp-internal
secrets:
app_private_key: ${{ secrets.REPO_SYNC_APP_PRIVATE_KEY }}
warp_api_key: ${{ secrets.WARP_API_KEY }}
restack:
# Run the restack workflow on PRs for `repo-sync/`-prefixed branches
# when they merge or are labelled with `repo-sync:needs-restack`.
if: >-
github.event_name == 'pull_request' &&
startsWith(github.event.pull_request.head.ref, 'repo-sync/') &&
(
github.event.pull_request.merged == true ||
(github.event.action == 'labeled' && github.event.label.name == 'repo-sync:needs-restack')
)
uses: warpdotdev/repo-sync/.github/workflows/restack.yml@main
with:
repo_sync_ref: main
app_id: ${{ vars.REPO_SYNC_APP_ID }}
public_repo: warpdotdev/warp
private_repo: warpdotdev/warp-internal
secrets:
app_private_key: ${{ secrets.REPO_SYNC_APP_PRIVATE_KEY }}
warp_api_key: ${{ secrets.WARP_API_KEY }}
approve:
if: >-
github.event_name == 'pull_request' &&
github.event.action != 'closed' &&
startsWith(github.event.pull_request.head.ref, 'repo-sync/')
uses: warpdotdev/repo-sync/.github/workflows/approve.yml@main
with:
repo_sync_ref: main
approver_app_id: ${{ vars.REPO_SYNC_APPROVER_APP_ID }}
public_repo: warpdotdev/warp
private_repo: warpdotdev/warp-internal
secrets:
approver_app_private_key: ${{ secrets.REPO_SYNC_APPROVER_APP_PRIVATE_KEY }}
escalation:
if: inputs.action == 'escalation'
uses: warpdotdev/repo-sync/.github/workflows/escalation.yml@main
with:
repo_sync_ref: main
app_id: ${{ vars.REPO_SYNC_APP_ID }}
public_repo: warpdotdev/warp
private_repo: warpdotdev/warp-internal
escalate_to: "@oncall-client-primary"
escalate_after: "30m"
secrets:
app_private_key: ${{ secrets.REPO_SYNC_APP_PRIVATE_KEY }}
@@ -0,0 +1,24 @@
name: Respond to PR Comment (Local)
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]
jobs:
# Mention, bot, event-type, and trust gates all live in the reusable
# workflow (``respond-to-pr-comment.yml``). This adapter exists only
# to subscribe to the three GitHub events that can carry an
# ``@oz-agent`` mention on a PR and delegate them through
# ``workflow_call``.
respond:
permissions:
contents: write
issues: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/respond-to-pr-comment.yml@main
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
@@ -0,0 +1,22 @@
name: Respond to Triaged Issue Comment (Local)
on:
issue_comment:
types: [created]
concurrency:
group: respond-to-triaged-issue-comment-${{ github.event.comment.id || github.run_id }}
cancel-in-progress: false
jobs:
# Mention, bot, event-type, and trust gates all live in the reusable
# workflow (``respond-to-triaged-issue-comment.yml``). This adapter
# exists only to subscribe to the GitHub event that can carry an
# ``@oz-agent`` mention on a triaged issue and delegate it through
# ``workflow_call``.
respond_inline:
permissions:
contents: read
issues: write
uses: warpdotdev/oz-for-oss/.github/workflows/respond-to-triaged-issue-comment.yml@main
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
+141
View File
@@ -0,0 +1,141 @@
name: Review Pull Request
on:
workflow_call:
inputs:
pr_number:
description: Pull request number to review
required: false
default: ""
type: string
trigger_source:
description: Source that requested the review
required: false
default: ""
type: string
requester:
description: Login of the user who requested the review, if any
required: false
default: ""
type: string
focus:
description: Optional extra focus guidance for the review
required: false
default: ""
type: string
comment_id:
description: Issue comment ID to react to for slash-command reviews
required: false
default: ""
type: string
secrets:
OZ_MGMT_GHA_APP_ID:
required: true
OZ_MGMT_GHA_PRIVATE_KEY:
required: true
OSS_WARP_API_KEY:
required: true
pull_request_target:
types:
- opened
- ready_for_review
- review_requested
- labeled
jobs:
resolve:
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
should_run: ${{ steps.resolve.outputs.should_run }}
pr_number: ${{ steps.resolve.outputs.pr_number }}
trigger_source: ${{ steps.resolve.outputs.trigger_source }}
requester: ${{ steps.resolve.outputs.requester }}
focus: ${{ steps.resolve.outputs.focus }}
comment_id: ${{ steps.resolve.outputs.comment_id }}
skip_reason: ${{ steps.resolve.outputs.skip_reason }}
steps:
- name: Checkout repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Resolve review context
id: resolve
env:
INPUT_PR_NUMBER: ${{ inputs.pr_number || '' }}
INPUT_TRIGGER_SOURCE: ${{ inputs.trigger_source || '' }}
INPUT_REQUESTER: ${{ inputs.requester || '' }}
INPUT_FOCUS: ${{ inputs.focus || '' }}
INPUT_COMMENT_ID: ${{ inputs.comment_id || '' }}
GITHUB_ACTOR_LOGIN: ${{ github.actor }}
run: |
python - <<'PY'
import json
import os
from pathlib import Path
event = json.loads(Path(os.environ["GITHUB_EVENT_PATH"]).read_text())
event_name = os.environ.get("GITHUB_EVENT_NAME", "")
input_pr_number = os.environ.get("INPUT_PR_NUMBER", "").strip()
pr = event.get("pull_request") or {}
head_ref = ((pr.get("head") or {}).get("ref") or "").strip()
action = (event.get("action") or "").strip()
requested_reviewer = ((event.get("requested_reviewer") or {}).get("login") or "").strip()
label_name = ((event.get("label") or {}).get("name") or "").strip()
has_pr_hooks = Path(".github/workflows/pr-hooks.yml").exists()
trigger_source = os.environ.get("INPUT_TRIGGER_SOURCE", "").strip() or event_name
requester = os.environ.get("INPUT_REQUESTER", "").strip() or os.environ.get("GITHUB_ACTOR_LOGIN", "")
focus = os.environ.get("INPUT_FOCUS", "")
comment_id = os.environ.get("INPUT_COMMENT_ID", "")
pr_number = input_pr_number or str(pr.get("number") or "")
matches_direct_trigger = (
(action == "opened" and not pr.get("draft", False))
or action == "ready_for_review"
or (action == "review_requested" and requested_reviewer == "oz-agent")
or (action == "labeled" and label_name == "oz-review")
)
if input_pr_number:
should_run = True
elif head_ref.startswith("cherrypick"):
should_run = False
elif has_pr_hooks and event_name == "pull_request_target":
should_run = False
else:
should_run = matches_direct_trigger and bool(pr_number)
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh:
fh.write(f"should_run={'true' if should_run else 'false'}\n")
fh.write(f"pr_number={pr_number}\n")
fh.write(f"trigger_source={trigger_source}\n")
fh.write(f"requester={requester}\n")
fh.write("focus<<__EOF__\n")
fh.write(focus)
fh.write("\n__EOF__\n")
fh.write(f"comment_id={comment_id}\n")
if has_pr_hooks and event_name == "pull_request_target" and not input_pr_number:
fh.write("skip_reason=pr-hooks-present\n")
elif head_ref.startswith("cherrypick"):
fh.write("skip_reason=cherrypick-branch\n")
elif not should_run:
fh.write("skip_reason=event-not-enabled\n")
PY
skip_direct_trigger:
needs: resolve
if: needs.resolve.outputs.should_run != 'true' && needs.resolve.outputs.skip_reason == 'pr-hooks-present'
runs-on: ubuntu-slim
steps:
- name: Explain skip
run: echo "PR review orchestration skipped because .github/workflows/pr-hooks.yml is present."
review_pr:
needs: resolve
if: needs.resolve.outputs.should_run == 'true'
permissions:
contents: read
pull-requests: write
issues: write
uses: warpdotdev/oz-for-oss/.github/workflows/review-pull-request.yml@main
with:
pr_number: ${{ needs.resolve.outputs.pr_number }}
trigger_source: ${{ needs.resolve.outputs.trigger_source }}
requester: ${{ needs.resolve.outputs.requester }}
focus: ${{ needs.resolve.outputs.focus }}
comment_id: ${{ needs.resolve.outputs.comment_id }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
+32
View File
@@ -0,0 +1,32 @@
# Fails a required status check if a pull request from one `repo-sync/*`
# branch targets another `repo-sync/*` branch. Combined with branch
# protection on `repo-sync/**` requiring this check, this prevents one sync
# PR from being merged into another sync PR's branch (which would bypass the
# restacking flow and corrupt the sync stack).
#
# PRs from non-`repo-sync/*` branches into `repo-sync/*` branches (e.g. for
# conflict resolution) are intentionally allowed. Direct pushes to
# `repo-sync/*` branches are also unaffected, since only the `pull_request`
# trigger is used here.
name: Sync PR Checks
on:
pull_request:
types: [opened, reopened, edited, synchronize, ready_for_review]
jobs:
check:
name: Verify PR base is the default branch
runs-on: ubuntu-slim
steps:
- name: Fail if merging a repo-sync branch into another repo-sync branch
env:
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
run: |
if [[ "$BASE_REF" == repo-sync/* && "$HEAD_REF" == repo-sync/* ]]; then
echo "::error::repo-sync/* PRs cannot be merged into other repo-sync/* branches."
echo "Wait for repo-sync to retarget this PR to the default branch before merging."
exit 1
fi
echo "Base branch '$BASE_REF' and head branch '$HEAD_REF' are OK."
@@ -0,0 +1,60 @@
name: Triage New Issues (Local)
on:
issues:
types: [opened]
issue_comment:
types: [created]
workflow_dispatch:
inputs:
issue_number:
description: Optional issue number to triage immediately
required: false
default: ''
type: string
lookback_minutes:
description: Minutes of issue history to scan when no issue number is provided
required: false
default: '60'
type: string
concurrency:
group: triage-new-issues-${{ github.event.issue.number || inputs.issue_number || github.run_id }}
cancel-in-progress: false
jobs:
triage_issues:
# A needs-info reply by the original reporter triggers re-triage
# even if it mentions @oz-agent, because the respond-to-triaged
# workflow handles explicit mentions on triaged issues separately.
if: |
(
github.event_name != 'issue_comment' &&
!contains(github.event.issue.labels.*.name, 'triaged') &&
!contains(github.event.issue.labels.*.name, 'ready-to-spec') &&
!contains(github.event.issue.labels.*.name, 'ready-to-implement')
) || (
github.event_name == 'issue_comment' &&
!github.event.issue.pull_request &&
github.event.comment.user.type != 'Bot' &&
!endsWith(github.event.comment.user.login, '[bot]') &&
(
(
contains(github.event.comment.body, '@oz-agent') &&
!contains(github.event.issue.labels.*.name, 'triaged')
) ||
(
contains(github.event.issue.labels.*.name, 'needs-info') &&
github.event.comment.user.login == github.event.issue.user.login &&
!contains(github.event.comment.body, '@oz-agent')
)
)
)
permissions:
contents: read
issues: write
uses: warpdotdev/oz-for-oss/.github/workflows/triage-new-issues.yml@main
with:
issue_number: ${{ github.event.issue.number || github.event.inputs.issue_number || '' }}
lookback_minutes: ${{ github.event.inputs.lookback_minutes || '60' }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
@@ -0,0 +1,22 @@
name: Trigger Implementation on Plan Approved (Local)
on:
pull_request_target:
types: [labeled]
concurrency:
group: trigger-impl-plan-approved-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: false
jobs:
trigger_implementation:
if: >-
github.event.label.name == 'plan-approved' &&
github.event.pull_request.state == 'open'
name: Trigger implementation for approved plan
permissions:
contents: write
issues: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/trigger-implementation-on-plan-approved.yml@main
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
+23
View File
@@ -0,0 +1,23 @@
name: Update Dedupe Skill (Local)
on:
schedule:
- cron: '30 9 * * 1' # Every Monday at 09:30 UTC
workflow_dispatch:
inputs:
lookback_days:
description: Number of days to look back for closed-as-duplicate signals
required: false
default: '7'
type: string
jobs:
update_dedupe:
permissions:
contents: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/update-dedupe.yml@main
with:
lookback_days: ${{ github.event.inputs.lookback_days || '7' }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
@@ -0,0 +1,23 @@
name: Update PR Review Skill (Local)
on:
schedule:
- cron: '0 9 * * 1' # Every Monday at 09:00 UTC
workflow_dispatch:
inputs:
lookback_days:
description: Number of days to look back for PR feedback
required: false
default: '7'
type: string
jobs:
update_pr_review:
permissions:
contents: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/update-pr-review.yml@main
with:
lookback_days: ${{ github.event.inputs.lookback_days || '7' }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
+23
View File
@@ -0,0 +1,23 @@
name: Update Triage Skill (Local)
on:
schedule:
- cron: '15 9 * * 1' # Every Monday at 09:15 UTC
workflow_dispatch:
inputs:
lookback_days:
description: Number of days to look back for triage feedback
required: false
default: '7'
type: string
jobs:
update_triage:
permissions:
contents: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/update-triage.yml@main
with:
lookback_days: ${{ github.event.inputs.lookback_days || '7' }}
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
@@ -0,0 +1,18 @@
name: Verify PR Comment (Local)
on:
issue_comment:
types: [created]
jobs:
# Slash-command parsing, bot gating, and trust admission live in the
# reusable workflow. This local adapter only subscribes to PR issue
# comments and delegates through ``workflow_call``.
verify:
permissions:
contents: read
issues: write
pull-requests: write
uses: warpdotdev/oz-for-oss/.github/workflows/verify-pr-comment.yml@main
secrets:
OZ_MGMT_GHA_APP_ID: ${{ secrets.OZ_MGMT_GHA_APP_ID }}
OZ_MGMT_GHA_PRIVATE_KEY: ${{ secrets.OZ_MGMT_GHA_PRIVATE_KEY }}
WARP_API_KEY: ${{ secrets.OSS_WARP_API_KEY }}
@@ -0,0 +1,71 @@
# ======================================================================================
# Workflow: Cleanup Fix PRs
# ======================================================================================
# Usage:
# - This workflow cleans up PRs generated by Fix Failing Checks
#
# Expected Output:
# - The workflow should close all PRs created by the github-actions bot that are based on a branch with the auto-fix-ci label after it closes
#
# ======================================================================================
name: Cleanup Fix PRs
on:
pull_request:
types: [closed]
jobs:
close-fix-prs:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'auto-fix-ci')
steps:
- name: Close Dependent Fix PRs
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { pull_request: pr, repository } = context.payload;
const { owner, repo } = context.repo;
const closedBranch = pr.head.ref;
console.log(`Original PR #${pr.number} closed. Head ref was: ${closedBranch}`);
// Find open PRs that target the closed PR's branch
const { data: openPRs } = await github.rest.pulls.list({
owner,
repo,
state: 'open',
base: closedBranch
});
if (openPRs.length === 0) {
console.log('No open fix PRs found targeting this branch.');
return;
}
console.log(`Found ${openPRs.length} open PRs targeting ${closedBranch}. Closing them...`);
for (const openPR of openPRs) {
if (openPR.user.login !== 'github-actions[bot]') {
console.log(`Skipping PR #${openPR.number} created by ${openPR.user.login} (not github-actions[bot])`);
continue;
}
console.log(`Closing PR #${openPR.number}: ${openPR.title}`);
// Comment on the fix PR
await github.rest.issues.createComment({
owner,
repo,
issue_number: openPR.number,
body: `Closing this fix PR because the parent PR #${pr.number} has been merged.`
});
// Close the fix PR
await github.rest.pulls.update({
owner,
repo,
pull_number: openPR.number,
state: 'closed'
});
}