Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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 you’re 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
|
||||
@@ -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}}
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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. Don’t 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'
|
||||
@@ -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}}
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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...}}
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
@@ -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!"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 }}
|
||||
@@ -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 }}
|
||||
@@ -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 }}
|
||||
@@ -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 }}
|
||||
@@ -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 }}
|
||||
@@ -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 }}
|
||||
@@ -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'
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user