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

fix(repo): add approval timeout setting to reflect server capability #835

Merged
merged 2 commits into from
Jan 14, 2025
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
3 changes: 2 additions & 1 deletion cypress/fixtures/repository.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@
}
},
"pipeline_type": "yaml",
"approve_build": "fork-always"
"approve_build": "fork-always",
"approval_timeout": 7
}
3 changes: 2 additions & 1 deletion cypress/fixtures/repository_updated.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@
}
},
"pipeline_type": "yaml",
"approve_build": "fork-no-write"
"approve_build": "fork-no-write",
"approval_timeout": 10
}
43 changes: 43 additions & 0 deletions cypress/integration/repo_settings.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ context('Repo Settings', () => {
cy.login('/github/octocat/settings');
});

it('approval timeout should show', () => {
cy.get('[data-test=repo-approval-timeout]').should('be.visible');
});

it('build limit input should show', () => {
cy.get('[data-test=repo-limit]').should('be.visible');
});
Expand Down Expand Up @@ -89,6 +93,45 @@ context('Repo Settings', () => {
cy.get('@pipelineTypeRadio').should('have.checked');
});

it('approval timeout input should allow number input', () => {
cy.get('[data-test=repo-approval-timeout]').as('repoApprovalTimeout');
cy.get('[data-test=repo-approval-timeout] input').as(
'repoApprovalTimeoutInput',
);
cy.get('@repoApprovalTimeoutInput')
.should('be.visible')
.type('{selectall}123');
cy.get('@repoApprovalTimeoutInput').should('have.value', '123');
});

it('approval timeout input should not allow letter/character input', () => {
cy.get('[data-test=repo-approval-timeout]').as('repoApprovalTimeout');
cy.get('[data-test=repo-approval-timeout] input').as(
'repoApprovalTimeoutInput',
);
cy.get('@repoApprovalTimeoutInput')
.should('be.visible')
.type('{selectall}cat');
cy.get('@repoApprovalTimeoutInput').should('not.have.value', 'cat');
cy.get('@repoApprovalTimeoutInput').type('{selectall}12cat34');
cy.get('@repoApprovalTimeoutInput').should('have.value', '1234');
});

it('clicking update on approval timeout should update timeout and hide button', () => {
cy.get('[data-test=repo-approval-timeout]').as('repoApprovalTimeout');
cy.get('[data-test=repo-approval-timeout] input').as(
'repoApprovalTimeoutInput',
);
cy.get('@repoApprovalTimeoutInput').should('be.visible').clear();
cy.get('@repoApprovalTimeoutInput').type('{selectall}80');
cy.get('[data-test=repo-approval-timeout] + button')
.should('be.visible')
.click({ force: true });
cy.get('[data-test=repo-approval-timeout] + button').should(
'be.disabled',
);
});

it('build limit input should allow number input', () => {
cy.get('[data-test=repo-limit]').as('repoLimit');
cy.get('[data-test=repo-limit] input').as('repoLimitInput');
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ services:
# https://go-vela.github.io/docs/administration/server/
server:
container_name: server
image: server:local
image: target/vela-server:latest
plyr4 marked this conversation as resolved.
Show resolved Hide resolved
networks:
- vela
environment:
Expand Down
106 changes: 106 additions & 0 deletions src/elm/Pages/Org_/Repo_/Settings.elm
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ toLayout user route model =
-}
type alias Model =
{ repo : WebData Vela.Repository
, inApprovalTimeout : Maybe Int
, inLimit : Maybe Int
, inCounter : Maybe Int
, inTimeout : Maybe Int
Expand All @@ -120,6 +121,7 @@ type alias Model =
init : Shared.Model -> Route { org : String, repo : String } -> () -> ( Model, Effect Msg )
init shared route () =
( { repo = RemoteData.Loading
, inApprovalTimeout = Nothing
, inLimit = Nothing
, inCounter = Nothing
, inTimeout = Nothing
Expand Down Expand Up @@ -156,6 +158,8 @@ type Msg
| AllowEventsUpdate { allowEvents : Vela.AllowEvents, event : Vela.AllowEventsField } Bool
| AccessUpdate String
| ForkPolicyUpdate String
| ApprovalTimeoutOnInput String
| ApprovalTimeoutUpdate Int
| BuildLimitOnInput String
| BuildLimitUpdate Int
| BuildTimeoutOnInput String
Expand Down Expand Up @@ -552,6 +556,34 @@ update shared route msg model =
}
)

ApprovalTimeoutOnInput val ->
( { model
| inApprovalTimeout = Just <| Maybe.withDefault 0 <| String.toInt val
}
, Effect.none
)

ApprovalTimeoutUpdate val ->
let
payload =
{ defaultRepoPayload
| approval_timeout = Just val
}

body =
Http.jsonBody <| Vela.encodeRepoPayload payload
in
( model
, Effect.updateRepo
{ baseUrl = shared.velaAPIBaseURL
, session = shared.session
, onResponse = UpdateRepoResponse { field = Vela.ApprovalTimeout }
, org = route.params.org
, repo = route.params.repo
, body = body
}
)

BuildLimitOnInput val ->
( { model
| inLimit = Just <| Maybe.withDefault 0 <| String.toInt val
Expand Down Expand Up @@ -721,6 +753,7 @@ view shared route model =
[ viewAllowEvents shared repo AllowEventsUpdate
, viewAccess repo AccessUpdate
, viewForkPolicy repo ForkPolicyUpdate
, viewApprovalTimeout repo model.inApprovalTimeout ApprovalTimeoutUpdate ApprovalTimeoutOnInput
, viewLimit shared repo model.inLimit BuildLimitUpdate BuildLimitOnInput
, viewTimeout repo model.inTimeout BuildTimeoutUpdate BuildTimeoutOnInput
, viewBuildCounter repo model.inCounter BuildCounterUpdate BuildCounterOnInput
Expand Down Expand Up @@ -834,6 +867,79 @@ viewForkPolicy repo msg =
]


{-| viewApprovalTimeout : takes model and repo and renders the settings category for updating repo build approval timeout.
-}
viewApprovalTimeout : Vela.Repository -> Maybe Int -> (Int -> msg) -> (String -> msg) -> Html msg
viewApprovalTimeout repo inApprovalTimeout clickMsg inputMsg =
section [ class "settings", Util.testAttribute "repo-settings-approval-timeout" ]
[ h2 [ class "settings-title" ] [ text "Approval Timeout" ]
, p [ class "settings-description" ] [ text "Number of days before builds pending approval are marked as error and discarded. Discarded builds must be restarted to approve." ]
, div [ class "form-controls" ]
[ viewApprovalTimeoutInput repo inApprovalTimeout inputMsg
, viewUpdateApprovalTimeout repo inApprovalTimeout <| clickMsg <| Maybe.withDefault 0 inApprovalTimeout
]
]


{-| viewApprovalTimeoutInput : takes repo, user input, and button action and renders the text input for updating build approval timeout.
-}
viewApprovalTimeoutInput : Vela.Repository -> Maybe Int -> (String -> msg) -> Html msg
viewApprovalTimeoutInput repo inApprovalTimeout inputMsg =
div [ class "form-control", Util.testAttribute "repo-approval-timeout" ]
[ input
[ id <| "repo-approval-timeout"
, onInput inputMsg
, type_ "number"
, Html.Attributes.min "1"
, Html.Attributes.max "60"
, value <| String.fromInt <| Maybe.withDefault repo.approval_timeout inApprovalTimeout
]
[]
, label [ class "form-label", for "repo-approval-timeout" ] [ text "days" ]
]


{-| viewUpdateApprovalTimeout : takes maybe int of user entered approval timeout and current repo approval timeout and renders the button to submit the update.
-}
viewUpdateApprovalTimeout : Vela.Repository -> Maybe Int -> msg -> Html msg
viewUpdateApprovalTimeout repo inApprovalTimeout msg =
case inApprovalTimeout of
Just _ ->
button
[ classList
[ ( "button", True )
, ( "-outline", True )
]
, onClick msg
, disabled <| not <| validApprovalTimeout 60 inApprovalTimeout repo <| Just repo.approval_timeout
]
[ text "update" ]

_ ->
text ""


{-| validApprovalTimeout : takes maybe string of user entered approval timeout and returns whether or not it is a valid update.
-}
validApprovalTimeout : Int -> Maybe Int -> Vela.Repository -> Maybe Int -> Bool
validApprovalTimeout maxApprovalTimeout inApprovalTimeout _ repoApprovalTimeout =
case inApprovalTimeout of
Just t ->
if t >= 1 && t <= maxApprovalTimeout then
case repoApprovalTimeout of
Just ti ->
t /= ti

Nothing ->
True

else
False

Nothing ->
False


{-| viewLimit : takes model and repo and renders the settings category for updating repo build limit.
-}
viewLimit : Shared.Model -> Vela.Repository -> Maybe Int -> (Int -> msg) -> (String -> msg) -> Html msg
Expand Down
13 changes: 13 additions & 0 deletions src/elm/Vela.elm
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ type alias Repository =
, allowEvents : AllowEvents
, enabled : Enabled
, pipeline_type : String
, approval_timeout : Int
}


Expand All @@ -487,6 +488,7 @@ emptyRepository =
, allowEvents = defaultAllowEvents
, enabled = Disabled
, pipeline_type = ""
, approval_timeout = 0
}


Expand Down Expand Up @@ -514,6 +516,7 @@ decodeRepository =
-- "enabled"
|> optional "active" enabledDecoder Disabled
|> optional "pipeline_type" string ""
|> optional "approval_timeout" int 0


decodeRepositories : Decoder (List Repository)
Expand All @@ -536,6 +539,7 @@ type alias RepoPayload =
, timeout : Maybe Int
, counter : Maybe Int
, pipeline_type : Maybe String
, approval_timeout : Maybe Int
}


Expand All @@ -552,6 +556,7 @@ encodeRepoPayload repo =
, ( "timeout", encodeOptional Json.Encode.int repo.timeout )
, ( "counter", encodeOptional Json.Encode.int repo.counter )
, ( "pipeline_type", encodeOptional Json.Encode.string repo.pipeline_type )
, ( "approval_timeout", encodeOptional Json.Encode.int repo.approval_timeout )
]


Expand All @@ -567,6 +572,7 @@ defaultRepoPayload =
, timeout = Nothing
, counter = Nothing
, pipeline_type = Nothing
, approval_timeout = Nothing
}


Expand All @@ -580,6 +586,7 @@ type RepoFieldUpdate
| Timeout
| Counter
| PipelineType
| ApprovalTimeout


type alias RepoFieldUpdateResponseConfig =
Expand Down Expand Up @@ -718,6 +725,12 @@ repoFieldUpdateToResponseConfig field =
"$ pipeline syntax type set to '" ++ repo.pipeline_type ++ "'."
}

ApprovalTimeout ->
{ successAlert =
\repo ->
"$ build approval timeout set to " ++ String.fromInt repo.approval_timeout ++ " day(s)."
}



-- ALLOW EVENTS
Expand Down
Loading