Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(audit): add redeliver button to hooks table #562

Merged
merged 9 commits into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cypress/fixtures/hooks_5.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[
{
"id": 5,
"number": 5,
"repo_id": 1,
"build_id": 3,
"source_id": "7bd477e4-4415-11e9-9359-0d41fdf9567e",
Expand All @@ -14,6 +15,7 @@
},
{
"id": 4,
"number": 4,
"repo_id": 1,
"build_id": 2,
"source_id": "7bd477e4-4415-11e9-9359-0d41fdf9567e",
Expand All @@ -27,6 +29,7 @@
},
{
"id": 3,
"number": 3,
"repo_id": 1,
"build_id": 1,
"source_id": "7bd477e4-4415-11e9-9359-0d41fdf9567e",
Expand All @@ -40,6 +43,7 @@
},
{
"id": 2,
"number": 2,
"repo_id": 1,
"build_id": 1,
"source_id": "7bd477e4-4415-11e9-9359-0d41fdf9567e",
Expand All @@ -53,6 +57,7 @@
},
{
"id": 1,
"number": 1,
"repo_id": 1,
"build_id": 0,
"source_id": "7bd477e4-4415-11e9-9359-0d41fdf9567e",
Expand Down
25 changes: 25 additions & 0 deletions cypress/integration/hooks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ context('Hooks', () => {
it('should show host', () => {
cy.get('@firstHook').contains('github.com');
});
it('should show redeliver hook', () => {
cy.get('@firstHook').within(() => {
cy.get('[data-test=redeliver-hook-5]').should('exist');
});
});
context('failure', () => {
beforeEach(() => {
cy.get('@lastHook').within(() => {
Expand All @@ -102,6 +107,26 @@ context('Hooks', () => {
});
});
});
context('successful redeliver hook', () => {
beforeEach(() => {
cy.redeliverHook();
cy.get('[data-test=redeliver-hook-1]').as('redeliverHook');
});

it('should show alert', () => {
cy.get('@redeliverHook').click();
cy.get('[data-test=alert]').should('contain', 'hook * redelivered');
});
});
context('unsuccessful redeliver hook', () => {
beforeEach(() => {
cy.redeliverHookError();
});

it('should show error', () => {
cy.get('[data-test=alerts]').should('exist').contains('Error');
});
});
});
});

Expand Down
19 changes: 19 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,25 @@ Cypress.Commands.add('hookPages', () => {
});
});

Cypress.Commands.add('redeliverHook', () => {
cy.server();
cy.route({
method: 'POST',
url: '*api/v1/hooks/*/*/*/redeliver',
response: 'hook * redelivered',
});
});

Cypress.Commands.add('redeliverHookError', () => {
cy.server();
cy.route({
method: 'POST',
url: '*api/v1/hooks/github/octocat/*/redeliver',
status: 500,
response: 'unable to redeliver hook',
});
});

Cypress.Commands.add('checkA11yForPage', (path = '/', opts = {}) => {
cy.login(path);
cy.injectAxe();
Expand Down
11 changes: 11 additions & 0 deletions src/elm/Api.elm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module Api exposing
, getSourceRepositories
, getStepLogs
, getToken
, redeliverHook
, repairRepo
, restartBuild
, try
Expand Down Expand Up @@ -65,6 +66,8 @@ import Vela
, DeploymentId
, Engine
, Event
, Hook
, HookNumber
, Hooks
, Key
, Log
Expand Down Expand Up @@ -617,6 +620,14 @@ getHooks model maybePage maybePerPage org repository =
|> withAuth model.session


{-| redeliverHook : redelivers a hook
-}
redeliverHook : PartialModel a -> Org -> Repo -> HookNumber -> Request String
redeliverHook model org repository hookNumber =
post model.velaAPI (Endpoint.Hook org repository hookNumber) Http.emptyBody Json.Decode.string
|> withAuth model.session


{-| getAllSecrets : fetches secrets for the given type org and key
-}
getAllSecrets : PartialModel a -> Engine -> Type -> Org -> Key -> Request Secret
Expand Down
5 changes: 5 additions & 0 deletions src/elm/Api/Endpoint.elm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Vela
, DeploymentId
, Engine
, Event
, HookNumber
, Name
, Org
, Ref
Expand Down Expand Up @@ -49,6 +50,7 @@ type Endpoint
| RepositoryRepair Org Repo
| UserSourceRepositories
| Hooks (Maybe Pagination.Page) (Maybe Pagination.PerPage) Org Repo
| Hook Org Repo HookNumber
| OrgBuilds (Maybe Pagination.Page) (Maybe Pagination.PerPage) (Maybe Event) Org
| Builds (Maybe Pagination.Page) (Maybe Pagination.PerPage) (Maybe Event) Org Repo
| Build Org Repo BuildNumber
Expand Down Expand Up @@ -105,6 +107,9 @@ toUrl api endpoint =
Hooks maybePage maybePerPage org repo ->
url api [ "hooks", org, repo ] <| Pagination.toQueryParams maybePage maybePerPage

Hook org repo hookNumber ->
url api [ "hooks", org, repo, hookNumber, "redeliver" ] []

OrgBuilds maybePage maybePerPage maybeEvent org ->
url api [ "repos", org, "builds" ] <| Pagination.toQueryParams maybePage maybePerPage ++ [ UB.string "event" <| Maybe.withDefault "" maybeEvent ]

Expand Down
33 changes: 32 additions & 1 deletion src/elm/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ import Vela
, Favicon
, Field
, FocusFragment
, HookNumber
, Hooks
, Key
, Log
Expand Down Expand Up @@ -411,6 +412,7 @@ type Msg
| UpdateRepoCounter Org Repo Field Int
| RestartBuild Org Repo BuildNumber
| CancelBuild Org Repo BuildNumber
| RedeliverHook Org Repo HookNumber
| GetPipelineConfig Org Repo BuildNumber Ref FocusFragment Bool
| ExpandPipelineConfig Org Repo BuildNumber Ref FocusFragment Bool
-- Inbound HTTP responses
Expand All @@ -432,6 +434,7 @@ type Msg
| BuildsResponse Org Repo (Result (Http.Detailed.Error String) ( Http.Metadata, Builds ))
| DeploymentsResponse Org Repo (Result (Http.Detailed.Error String) ( Http.Metadata, List Deployment ))
| HooksResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Hooks ))
| RedeliverHookResponse Org Repo HookNumber (Result (Http.Detailed.Error String) ( Http.Metadata, String ))
| BuildResponse Org Repo (Result (Http.Detailed.Error String) ( Http.Metadata, Build ))
| BuildAndPipelineResponse Org Repo (Maybe ExpandTemplatesQuery) (Result (Http.Detailed.Error String) ( Http.Metadata, Build ))
| DeploymentResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Deployment ))
Expand Down Expand Up @@ -1135,6 +1138,11 @@ update msg model =
, cancelBuild model org repo buildNumber
)

RedeliverHook org repo hookNumber ->
( model
, redeliverHook model org repo hookNumber
)

GetPipelineConfig org repo buildNumber ref lineFocus refresh ->
( { model
| pipeline =
Expand Down Expand Up @@ -1488,6 +1496,21 @@ update msg model =
Err error ->
( { model | repo = updateHooks (toFailure error) rm }, addError error )

RedeliverHookResponse org repo hookNumber response ->
case response of
Ok ( _, redeliverResponse ) ->
let
redeliveredHook =
"Hook " ++ String.join "/" [ org, repo, hookNumber ]
in
( model
, getHooks model org repo Nothing Nothing
)
|> Alerting.addToastIfUnique Alerts.successConfig AlertsUpdate (Alerts.Success "Success" (redeliveredHook ++ " redelivered.") Nothing)

Err error ->
( model, addError error )

BuildResponse org repo response ->
case response of
Ok ( _, build ) ->
Expand Down Expand Up @@ -2434,10 +2457,13 @@ viewContent model =
( String.join "/" [ org, repo ] ++ " hooks" ++ Util.pageToString maybePage
, div []
[ Pager.view model.repo.hooks.pager Pager.defaultLabels GotoPage
, lazy Pages.Hooks.view
, lazy2 Pages.Hooks.view
{ hooks = model.repo.hooks
, time = model.time
, org = model.repo.org
, repo = model.repo.name
}
RedeliverHook
, Pager.view model.repo.hooks.pager Pager.defaultLabels GotoPage
]
)
Expand Down Expand Up @@ -4139,6 +4165,11 @@ getHooks model org repo maybePage maybePerPage =
Api.try HooksResponse <| Api.getHooks model maybePage maybePerPage org repo


redeliverHook : Model -> Org -> Repo -> HookNumber -> Cmd Msg
redeliverHook model org repo hookNumber =
Api.try (RedeliverHookResponse org repo hookNumber) <| Api.redeliverHook model org repo hookNumber


getRepo : Model -> Org -> Repo -> Cmd Msg
getRepo model org repo =
Api.try RepoResponse <| Api.getRepo model org repo
Expand Down
42 changes: 34 additions & 8 deletions src/elm/Pages/Hooks.elm
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ Use of this source code is governed by the LICENSE file in this repository.
module Pages.Hooks exposing (view)

import Ansi.Log
import Api
import Array
import Errors exposing (viewResourceError)
import Html
exposing
( Html
, a
, code
, div
, small
Expand All @@ -23,6 +25,7 @@ import Html.Attributes
exposing
( attribute
, class
, href
, scope
)
import Pages.Build.Logs exposing (decodeAnsi)
Expand All @@ -34,8 +37,11 @@ import Util
import Vela
exposing
( Hook
, HookNumber
, Hooks
, HooksModel
, Org
, Repo
)


Expand All @@ -44,17 +50,23 @@ import Vela
type alias PartialModel =
{ hooks : HooksModel
, time : Posix
, org : Org
, repo : Repo
}


type alias RedeliverHook msg =
Org -> Repo -> HookNumber -> msg



-- VIEW


{-| view : renders hooks
-}
view : PartialModel -> Html msg
view { hooks, time } =
view : PartialModel -> RedeliverHook msg -> Html msg
view { hooks, time, org, repo } redeliverHook =
case hooks.hooks of
RemoteData.Success hooks_ ->
div []
Expand All @@ -64,7 +76,7 @@ view { hooks, time } =
"hooks"
"No hooks found for this organization/repo"
tableHeaders
(hooksToRows time hooks_)
(hooksToRows time hooks_ org repo redeliverHook)
Nothing
)
]
Expand All @@ -81,10 +93,10 @@ view { hooks, time } =

{-| hooksToRows : takes list of hooks and produces list of Table rows
-}
hooksToRows : Posix -> Hooks -> Table.Rows Hook msg
hooksToRows now hooks =
hooksToRows : Posix -> Hooks -> Org -> Repo -> RedeliverHook msg -> Table.Rows Hook msg
hooksToRows now hooks org repo redeliverHook =
hooks
|> List.map (\hook -> [ Just <| Table.Row hook (renderHook now), hookErrorRow hook ])
|> List.map (\hook -> [ Just <| Table.Row hook (renderHook now org repo redeliverHook), hookErrorRow hook ])
|> List.concat
|> List.filterMap identity

Expand All @@ -104,8 +116,8 @@ tableHeaders =

{-| renderHook : takes hook and renders a table row
-}
renderHook : Posix -> Hook -> Html msg
renderHook now hook =
renderHook : Posix -> Org -> Repo -> RedeliverHook msg -> Hook -> Html msg
renderHook now org repo redeliverHook hook =
tr [ Util.testAttribute <| "hooks-row", hookStatusToRowClass hook.status ]
[ td
[ attribute "data-label" "status"
Expand Down Expand Up @@ -144,6 +156,20 @@ renderHook now hook =
, class "break-word"
]
[ text hook.branch ]
, td
[ attribute "data-label" "redeliver"
, scope "row"
, class "break-word"
]
[ a
[ href "#"
, class "break-word"
, Util.onClickPreventDefault <| redeliverHook org repo <| String.fromInt hook.number
, Util.testAttribute <| "redeliver-hook-" ++ String.fromInt hook.number
]
[ text "Redeliver Hook"
]
]
]


Expand Down
7 changes: 7 additions & 0 deletions src/elm/Vela.elm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module Vela exposing
, Field
, FocusFragment
, Hook
, HookNumber
, Hooks
, HooksModel
, Key
Expand Down Expand Up @@ -206,6 +207,10 @@ type alias BuildNumber =
String


type alias HookNumber =
String


type alias DeploymentId =
String

Expand Down Expand Up @@ -1643,6 +1648,7 @@ type alias Hook =
, repo_id : Int
, build_id : Int
, source_id : String
, number : Int
, created : Int
, host : String
, event : String
Expand All @@ -1660,6 +1666,7 @@ decodeHook =
|> optional "repo_id" int -1
|> optional "build_id" int -1
|> optional "source_id" string ""
|> optional "number" int -1
|> optional "created" int -1
|> optional "host" string ""
|> optional "event" string ""
Expand Down