Skip to content

Commit

Permalink
feat: Add :Octo run list to view workflow runs and logs
Browse files Browse the repository at this point in the history
* feat: poc octo run list

* feat: define octo key mappings

* feat: add customizable icons

* .

* revert lint changes

* fix lint

* feat: customizable refresh interval

* add space between jobs

* feat: use telescope

* open buffer when pressing <cr>

* .

* get step logs for single job workflows

* multi-job-support

* cache workflow runs

* .

* add error message for failing to get logs

* refactor: cleanup highlights

* add refresh keybinding

* add notice and strip ansi codes

* dedupe steps

* feat: handle zip archive with logs

* add open in browser keybind

* cleanup zip archive, keybindings

* .

* normalize

* cr fix

Co-authored-by: Will Dean <[email protected]>

* refactor: move all requires to the top of file

* use octo.utils.error

* refactor: workflow_runs telescope

* fix: invalid require

* add loading msg for workflow logs, cleanup old files to avoid conflicts

* fix: nil value

* style: lint issues

* try fix unique os.tmpname

* .

* update readme

* update os.tmpname

* fix: rand filename

* feat: improve random name seeding

* fix: skip logs for skipped steps

* feat: show failed and skipped runs in telescope

* fix: workflow with long names not working

* use utils.get_remote_name

* use existing octo.gh

* utils info over vim.notify

* use octo.picker

* refactor: gh run list

* add copy_url command

* feat: use ∨ for expanded nodes

* feat: close parent

* fix: some workflow logs cannot be read due to truncating

* use octo to notify

---------

Co-authored-by: Will Dean <[email protected]>
Co-authored-by: Will Dean <[email protected]>
  • Loading branch information
3 people authored Feb 23, 2025
1 parent 8deff2b commit d514e01
Show file tree
Hide file tree
Showing 12 changed files with 824 additions and 1 deletion.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ require"octo".setup({
auto_show_threads = true, -- automatically show comment threads on cursor move
focus = "right", -- focus right buffer on diff open
},
runs = {
icons = {
pending = "🕖",
in_progress = "🔄",
failed = "",
succeeded = "",
skipped = "",
cancelled = "",
},
},
pull_requests = {
order_by = { -- criteria to sort the results of `Octo pr list`
field = "CREATED_AT", -- either COMMENTS, CREATED_AT or UPDATED_AT (https://docs.github.com/en/graphql/reference/enums#issueorderfield)
Expand Down Expand Up @@ -174,6 +184,12 @@ require"octo".setup({
},
mappings_disable_default = false, -- disable default mappings if true, but will still adapt user mappings
mappings = {
runs = {
expand_step = { lhs = "o", desc = "expand workflow step" },
open_in_browser = { lhs = "<C-b>", desc = "open workflow run in browser" },
refresh = { lhs = "<C-r>", desc = "refresh workflow" },
copy_url = { lhs = "<C-y>", desc = "copy url to system clipboard" },
},
issue = {
close_issue = { lhs = "<localleader>ic", desc = "close issue" },
reopen_issue = { lhs = "<localleader>io", desc = "reopen issue" },
Expand Down Expand Up @@ -389,6 +405,7 @@ If no command is passed, the argument to `Octo` is treated as a URL from where a
| | close | Close the review window and return to the PR |
| actions | | Lists all available Octo actions |
| search | <query> | Search GitHub for issues and PRs matching the [query](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests) |
| run | list | List workflow runs |
| notification | list | Shows current unread notifications |

0. `[repo]`: If repo is not provided, it will be derived from `<cwd>/.git/config`.
Expand Down
10 changes: 10 additions & 0 deletions lua/octo/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ function M.setup()

-- supported commands
M.commands = {
run = {
list = function()
local function co_wrapper()
require("octo.workflow_runs").list()
end

local co = coroutine.create(co_wrapper)
coroutine.resume(co)
end,
},
actions = function()
M.actions()
end,
Expand Down
30 changes: 29 additions & 1 deletion lua/octo/config.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local vim = vim
local M = {}

---@alias OctoMappingsWindow "issue" | "pull_request" | "review_thread" | "submit_win" | "review_diff" | "file_panel" | "repo" | "notification"
---@alias OctoMappingsWindow "issue" | "pull_request" | "review_thread" | "submit_win" | "review_diff" | "file_panel" | "repo" | "notification" | "runs"
---@alias OctoMappingsList { [string]: table}
---@alias OctoPickers "telescope" | "fzf-lua" | "snacks"
---@alias OctoSplit "right" | "left"
Expand Down Expand Up @@ -43,6 +43,17 @@ local M = {}
---@class OctoConfigDiscussions
---@field order_by OctoConfigOrderBy

---@class OctoConfigWorkflowIcons
---@field pending string
---@field skipped string
---@field in_progress string
---@field failed string
---@field succeeded string
---@field cancelled string

---@class OctoConfigRuns
---@field icons OctoConfigWorkflowIcons

---@class OctoConfigNotifications
---@field current_repo_only boolean

Expand Down Expand Up @@ -88,6 +99,7 @@ local M = {}
---@field ui OctoConfigUi
---@field issues OctoConfigIssues
---@field reviews OctoConfigReviews
---@field runs OctoConfigRuns
---@field pull_requests OctoConfigPR
---@field file_panel OctoConfigFilePanel
---@field colors OctoConfigColors
Expand Down Expand Up @@ -161,6 +173,16 @@ function M.get_default_values()
auto_show_threads = true,
focus = "right",
},
runs = {
icons = {
pending = "🕖",
in_progress = "🔄",
failed = "",
succeeded = "",
skipped = "",
cancelled = "",
},
},
pull_requests = {
order_by = {
field = "CREATED_AT",
Expand Down Expand Up @@ -188,6 +210,12 @@ function M.get_default_values()
},
mappings_disable_default = false,
mappings = {
runs = {
expand_step = { lhs = "o", desc = "expand workflow step" },
open_in_browser = { lhs = "<C-b>", desc = "open workflow run in browser" },
refresh = { lhs = "<C-r>", desc = "refresh workflow" },
copy_url = { lhs = "<C-y>", desc = "copy url to system clipboard" },
},
issue = {
close_issue = { lhs = "<localleader>ic", desc = "close issue" },
reopen_issue = { lhs = "<localleader>io", desc = "reopen issue" },
Expand Down
2 changes: 2 additions & 0 deletions lua/octo/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ M.OCTO_EMPTY_MSG_VT_NS = vim.api.nvim_create_namespace "octo_empty_msg_vt"
M.OCTO_THREAD_HEADER_VT_NS = vim.api.nvim_create_namespace "octo_thread_header_vt"
M.OCTO_EVENT_VT_NS = vim.api.nvim_create_namespace "octo_event_vt"

M.OCTO_WORKFLOW_NS = vim.api.nvim_create_namespace "octo_workflow"

M.NO_BODY_MSG = "No description provided."

M.LONG_ISSUE_PATTERN = "([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)#(%d+)"
Expand Down
2 changes: 2 additions & 0 deletions lua/octo/navigation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ function M.open_in_browser(kind, repo, number)
cmd = string.format("gh gist view --web %s", number)
elseif kind == "project" then
cmd = string.format("gh project view --owner %s --web %s", repo, number)
elseif kind == "workflow_run" then
cmd = string.format("gh run view %s --web", number)
end
end
pcall(vim.cmd, "silent !" .. cmd)
Expand Down
1 change: 1 addition & 0 deletions lua/octo/pickers/fzf-lua/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ M.picker = {
users = require "octo.pickers.fzf-lua.pickers.users",
notifications = M.not_implemented,
milestones = M.not_implemented,
workflow_runs = M.not_implemented,
}

return M
1 change: 1 addition & 0 deletions lua/octo/pickers/snacks/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ M.picker = {
project_columns_v2 = M.not_implemented,
prs = M.pull_requests,
repos = M.not_implemented,
workflow_runs = M.not_implemented,
review_commits = M.not_implemented,
search = M.not_implemented,
users = M.not_implemented,
Expand Down
10 changes: 10 additions & 0 deletions lua/octo/pickers/telescope/entry_maker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,16 @@ function M.gen_from_git_changed_files()
end
end

function M.gen_from_workflow_run()
return function(workflow_run)
return {
display = workflow_run.display,
value = workflow_run,
ordinal = workflow_run.display,
}
end
end

function M.gen_from_review_thread(linenr_length)
local make_display = function(entry)
if not entry then
Expand Down
8 changes: 8 additions & 0 deletions lua/octo/pickers/telescope/previewers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local previewers = require "telescope.previewers"
local pv_utils = require "telescope.previewers.utils"
local ts_utils = require "telescope.utils"
local defaulter = ts_utils.make_default_callable
local workflow_runs_previewer = require("octo.workflow_runs").previewer

local vim = vim

Expand Down Expand Up @@ -224,7 +225,14 @@ local issue_template = defaulter(function(opts)
}
end, {})

local workflow_runs = defaulter(function(opts)
return previewers.new_buffer_previewer {
define_preview = workflow_runs_previewer,
}
end, {})

return {
workflow_runs = workflow_runs,
discussion = discussion,
issue = issue,
gist = gist,
Expand Down
25 changes: 25 additions & 0 deletions lua/octo/pickers/telescope/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,30 @@ function M.pending_threads(threads)
:find()
end

function M.workflow_runs(workflow_runs, title, on_select_cb)
pickers
.new({}, {
prompt_title = title or false,
results_title = false,
preview_title = false,
finder = finders.new_table {
results = workflow_runs,
entry_maker = entry_maker.gen_from_workflow_run(),
},
sorter = conf.generic_sorter {},
previewer = previewers.workflow_runs.new {},
attach_mappings = function()
actions.select_default:replace(function(prompt_bufnr)
local selection = action_state.get_selected_entry(prompt_bufnr)
actions.close(prompt_bufnr)
on_select_cb(selection.value)
end)
return true
end,
})
:find()
end

---
-- PROJECTS
---
Expand Down Expand Up @@ -1472,6 +1496,7 @@ M.picker = {
notifications = M.notifications,
pending_threads = M.pending_threads,
project_cards = M.select_project_card,
workflow_runs = M.workflow_runs,
project_cards_v2 = M.not_implemented,
project_columns = M.select_target_project_column,
project_columns_v2 = M.not_implemented,
Expand Down
1 change: 1 addition & 0 deletions lua/octo/pickers/vim-clap/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ M.picker = {
search = M.not_implemented,
users = M.not_implemented,
milestones = M.not_implemented,
workflow_runs = M.not_implemented,
}

return M
Loading

0 comments on commit d514e01

Please sign in to comment.