feat: add Check Now button for on-demand bandwidth testing
Some checks failed
Build and Release / Lint (push) Failing after 2m5s
Build and Release / Unit Tests (push) Successful in 2m45s
Build and Release / Create Release (push) Has been skipped
Build and Release / Build Binaries (amd64, darwin) (push) Has been skipped
Build and Release / Build Binaries (amd64, linux) (push) Has been skipped
Build and Release / Build Binaries (amd64, windows) (push) Has been skipped
Build and Release / Build Binaries (arm64, darwin) (push) Has been skipped
Build and Release / Build Binaries (arm64, linux) (push) Has been skipped
Build and Release / Integration Tests (PostgreSQL) (push) Successful in 1m0s
Some checks failed
Build and Release / Lint (push) Failing after 2m5s
Build and Release / Unit Tests (push) Successful in 2m45s
Build and Release / Create Release (push) Has been skipped
Build and Release / Build Binaries (amd64, darwin) (push) Has been skipped
Build and Release / Build Binaries (amd64, linux) (push) Has been skipped
Build and Release / Build Binaries (amd64, windows) (push) Has been skipped
Build and Release / Build Binaries (arm64, darwin) (push) Has been skipped
Build and Release / Build Binaries (arm64, linux) (push) Has been skipped
Build and Release / Integration Tests (PostgreSQL) (push) Successful in 1m0s
- Add BandwidthTestRequestedAt field to ActionRunner model - Update to actions-proto-go v0.5.7 with RequestBandwidthTest field - Add RunnerRequestBandwidthTest handler and route - Update FetchTask to check and return bandwidth test request flag - Add Check Now button to runner capabilities panel - Add locale strings for bandwidth test feature 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2
go.mod
2
go.mod
@@ -314,7 +314,7 @@ replace github.com/nektos/act => gitea.com/gitea/act v0.261.7-0.20251003180512-a
|
||||
replace git.sr.ht/~mariusor/go-xsd-duration => gitea.com/gitea/go-xsd-duration v0.0.0-20220703122237-02e73435a078
|
||||
|
||||
// Use GitCaddy fork with capability support
|
||||
replace code.gitea.io/actions-proto-go => git.marketally.com/gitcaddy/actions-proto-go v0.5.6
|
||||
replace code.gitea.io/actions-proto-go => git.marketally.com/gitcaddy/actions-proto-go v0.5.7
|
||||
|
||||
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||
|
||||
|
||||
4
go.sum
4
go.sum
@@ -29,8 +29,8 @@ dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
git.marketally.com/gitcaddy/actions-proto-go v0.5.6 h1:G7T0vpx8HyCFWd0YMJ9sp8rCsWtzFrCJK4BMdOFJa1A=
|
||||
git.marketally.com/gitcaddy/actions-proto-go v0.5.6/go.mod h1:RPu21UoRD3zSAujoZR6LJwuVNa2uFRBveadslczCRfQ=
|
||||
git.marketally.com/gitcaddy/actions-proto-go v0.5.7 h1:RUbafr3Vkw2l4WfSwa+oF+Ihakbm05W0FlAmXuQrDJc=
|
||||
git.marketally.com/gitcaddy/actions-proto-go v0.5.7/go.mod h1:RPu21UoRD3zSAujoZR6LJwuVNa2uFRBveadslczCRfQ=
|
||||
gitea.com/gitea/act v0.261.7-0.20251003180512-ac6e4b751763 h1:ohdxegvslDEllZmRNDqpKun6L4Oq81jNdEDtGgHEV2c=
|
||||
gitea.com/gitea/act v0.261.7-0.20251003180512-ac6e4b751763/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
|
||||
gitea.com/gitea/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:BAFmdZpRW7zMQZQDClaCWobRj9uL1MR3MzpCVJvc5s4=
|
||||
|
||||
@@ -64,6 +64,8 @@ type ActionRunner struct {
|
||||
Ephemeral bool `xorm:"ephemeral NOT NULL DEFAULT false"`
|
||||
// CapabilitiesJSON stores structured capability information for AI consumption
|
||||
CapabilitiesJSON string `xorm:"TEXT"`
|
||||
// BandwidthTestRequestedAt tracks when a bandwidth test was requested by admin
|
||||
BandwidthTestRequestedAt timeutil.TimeStamp `xorm:"index"`
|
||||
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
|
||||
@@ -3714,6 +3714,9 @@
|
||||
"actions.runners.capabilities.disk_warning": "Low disk space",
|
||||
"actions.runners.capabilities.disk_critical": "Critical: disk almost full",
|
||||
"actions.runners.capabilities.bandwidth": "Network Bandwidth",
|
||||
"actions.runners.bandwidth_test_requested": "Bandwidth test requested. Results will appear on next poll.",
|
||||
"actions.runners.bandwidth_test_request_failed": "Failed to request bandwidth test.",
|
||||
"actions.runners.check_bandwidth_now": "Check Now",
|
||||
"actions.runs.all_workflows": "All Workflows",
|
||||
"actions.runs.commit": "Commit",
|
||||
"actions.runs.scheduled": "Scheduled",
|
||||
|
||||
@@ -177,9 +177,22 @@ func (s *Service) FetchTask(
|
||||
task = t
|
||||
}
|
||||
}
|
||||
|
||||
// Check if admin requested a bandwidth test
|
||||
requestBandwidthTest := false
|
||||
if runner.BandwidthTestRequestedAt > 0 {
|
||||
requestBandwidthTest = true
|
||||
// Clear the request after sending
|
||||
runner.BandwidthTestRequestedAt = 0
|
||||
if err := actions_model.UpdateRunner(ctx, runner, "bandwidth_test_requested_at"); err != nil {
|
||||
log.Warn("failed to clear bandwidth test request: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
res := connect.NewResponse(&runnerv1.FetchTaskResponse{
|
||||
Task: task,
|
||||
TasksVersion: latestVersion,
|
||||
Task: task,
|
||||
TasksVersion: latestVersion,
|
||||
RequestBandwidthTest: requestBandwidthTest,
|
||||
})
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
shared_user "code.gitea.io/gitea/routers/web/shared/user"
|
||||
@@ -295,6 +296,45 @@ func ResetRunnerRegistrationToken(ctx *context.Context) {
|
||||
ctx.JSONRedirect(redirectTo)
|
||||
}
|
||||
|
||||
// RunnerRequestBandwidthTest handles admin request to trigger a bandwidth test
|
||||
func RunnerRequestBandwidthTest(ctx *context.Context) {
|
||||
rCtx, err := getRunnersCtx(ctx)
|
||||
if err != nil {
|
||||
ctx.ServerError("getRunnersCtx", err)
|
||||
return
|
||||
}
|
||||
|
||||
runnerID := ctx.PathParamInt64("runnerid")
|
||||
ownerID := rCtx.OwnerID
|
||||
repoID := rCtx.RepoID
|
||||
redirectTo := rCtx.RedirectLink + url.PathEscape(ctx.PathParam("runnerid"))
|
||||
|
||||
runner, err := actions_model.GetRunnerByID(ctx, runnerID)
|
||||
if err != nil {
|
||||
log.Warn("RunnerRequestBandwidthTest.GetRunnerByID failed: %v, url: %s", err, ctx.Req.URL)
|
||||
ctx.ServerError("RunnerRequestBandwidthTest.GetRunnerByID", err)
|
||||
return
|
||||
}
|
||||
if !runner.EditableInContext(ownerID, repoID) {
|
||||
ctx.NotFound(util.NewPermissionDeniedErrorf("no permission to edit this runner"))
|
||||
return
|
||||
}
|
||||
|
||||
// Set the bandwidth test request timestamp
|
||||
runner.BandwidthTestRequestedAt = timeutil.TimeStampNow()
|
||||
err = actions_model.UpdateRunner(ctx, runner, "bandwidth_test_requested_at")
|
||||
if err != nil {
|
||||
log.Warn("RunnerRequestBandwidthTest.UpdateRunner failed: %v, url: %s", err, ctx.Req.URL)
|
||||
ctx.Flash.Warning(ctx.Tr("actions.runners.bandwidth_test_request_failed"))
|
||||
ctx.Redirect(redirectTo)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug("RunnerRequestBandwidthTest success: %s", ctx.Req.URL)
|
||||
ctx.Flash.Success(ctx.Tr("actions.runners.bandwidth_test_requested"))
|
||||
ctx.Redirect(redirectTo)
|
||||
}
|
||||
|
||||
// RunnerDeletePost response for deleting runner
|
||||
func RunnerDeletePost(ctx *context.Context) {
|
||||
rCtx, err := getRunnersCtx(ctx)
|
||||
|
||||
@@ -510,6 +510,7 @@ func registerWebRoutes(m *web.Router) {
|
||||
m.Combo("/{runnerid}").Get(shared_actions.RunnersEdit).
|
||||
Post(web.Bind(forms.EditRunnerForm{}), shared_actions.RunnersEditPost)
|
||||
m.Post("/{runnerid}/delete", shared_actions.RunnerDeletePost)
|
||||
m.Post("/{runnerid}/bandwidth-test", shared_actions.RunnerRequestBandwidthTest)
|
||||
m.Post("/reset_registration_token", shared_actions.ResetRunnerRegistrationToken)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -115,9 +115,9 @@
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if .RunnerCapabilities.Bandwidth}}
|
||||
<div class="field tw-mb-3">
|
||||
<label>{{ctx.Locale.Tr "actions.runners.capabilities.bandwidth"}}</label>
|
||||
{{if .RunnerCapabilities.Bandwidth}}
|
||||
<div class="tw-flex tw-items-center tw-gap-2">
|
||||
<span class="ui {{if ge .RunnerCapabilities.Bandwidth.DownloadMbps 100.0}}green{{else if ge .RunnerCapabilities.Bandwidth.DownloadMbps 10.0}}blue{{else}}yellow{{end}} label">
|
||||
{{svg "octicon-arrow-down" 14}} {{printf "%.1f" .RunnerCapabilities.Bandwidth.DownloadMbps}} Mbps
|
||||
@@ -127,14 +127,30 @@
|
||||
{{svg "octicon-clock" 14}} {{printf "%.0f" .RunnerCapabilities.Bandwidth.Latency}} ms
|
||||
</span>
|
||||
{{end}}
|
||||
<form method="post" action="{{.Link}}/bandwidth-test" class="tw-inline">
|
||||
{{.CsrfTokenHtml}}
|
||||
<button class="ui tiny basic button" type="submit">
|
||||
{{svg "octicon-sync" 14}} {{ctx.Locale.Tr "actions.runners.check_bandwidth_now"}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{{if .RunnerCapabilities.Bandwidth.TestedAt}}
|
||||
<div class="tw-text-sm tw-text-secondary tw-mt-1">
|
||||
Tested {{DateUtils.TimeSince .RunnerCapabilities.Bandwidth.TestedAt}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<div class="tw-flex tw-items-center tw-gap-2">
|
||||
<span class="ui basic label">No data yet</span>
|
||||
<form method="post" action="{{.Link}}/bandwidth-test" class="tw-inline">
|
||||
{{.CsrfTokenHtml}}
|
||||
<button class="ui tiny basic button" type="submit">
|
||||
{{svg "octicon-sync" 14}} {{ctx.Locale.Tr "actions.runners.check_bandwidth_now"}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if .RunnerCapabilities.Limitations}}
|
||||
<div class="field tw-mb-3">
|
||||
|
||||
Reference in New Issue
Block a user