From 7a1935795da3bd878a1bcd101329e8e058fdf479 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Fri, 19 Dec 2025 12:43:47 +0100 Subject: [PATCH 001/854] chore: 13.0 is now stable (#10482) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10482 --- release-notes-published/14.0.0.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 release-notes-published/14.0.0.md diff --git a/release-notes-published/14.0.0.md b/release-notes-published/14.0.0.md new file mode 100644 index 0000000000..e69de29bb2 From 5b73467d024dcc8d489709a6ee99d5fdf54136a6 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 19 Dec 2025 15:20:52 +0100 Subject: [PATCH 002/854] feat: allow to add pam source from command line (#10388) The forgejo admin command line allows to deal with all the propose auth mecanism but pam, this PR adds full support for adding and updating pam auth mecanism via the command line without limitation. Co-authored-by: Gusted Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10388 Reviewed-by: Gusted Co-authored-by: Baptiste Daroussin Co-committed-by: Baptiste Daroussin --- cmd/admin.go | 2 + cmd/admin_auth_pam.go | 145 ++++++++++++++++++ cmd/admin_auth_pam_test.go | 293 +++++++++++++++++++++++++++++++++++++ 3 files changed, 440 insertions(+) create mode 100644 cmd/admin_auth_pam.go create mode 100644 cmd/admin_auth_pam_test.go diff --git a/cmd/admin.go b/cmd/admin.go index 90157e2d5a..60b25eb971 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -64,6 +64,8 @@ func subcmdAuth() *cli.Command { microcmdAuthUpdateLdapBindDn(), microcmdAuthAddLdapSimpleAuth(), microcmdAuthUpdateLdapSimpleAuth(), + microcmdAuthAddPAM(), + microcmdAuthUpdatePAM(), microcmdAuthAddSMTP(), microcmdAuthUpdateSMTP(), microcmdAuthList(), diff --git a/cmd/admin_auth_pam.go b/cmd/admin_auth_pam.go new file mode 100644 index 0000000000..25e32503e0 --- /dev/null +++ b/cmd/admin_auth_pam.go @@ -0,0 +1,145 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package cmd + +import ( + "context" + "errors" + + auth_model "forgejo.org/models/auth" + "forgejo.org/services/auth/source/pam" + + "github.com/urfave/cli/v3" +) + +func pamCLIFlags() []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: "name", + Value: "", + Usage: "Application Name", + }, + &cli.StringFlag{ + Name: "service-name", + Value: "PLAIN", + Usage: "PAM service name", + }, + &cli.StringFlag{ + Name: "email-domain", + Value: "", + Usage: "PAM email domain", + }, + &cli.BoolFlag{ + Name: "skip-local-2fa", + Usage: "Skip 2FA to log on.", + Value: true, + }, + &cli.BoolFlag{ + Name: "active", + Usage: "This Authentication Source is Activated.", + Value: true, + }, + } +} + +func microcmdAuthAddPAM() *cli.Command { + return &cli.Command{ + Name: "add-pam", + Usage: "Add new PAM authentication source", + Before: noDanglingArgs, + Action: newAuthService().addPAM, + Flags: pamCLIFlags(), + } +} + +func microcmdAuthUpdatePAM() *cli.Command { + return &cli.Command{ + Name: "update-pam", + Usage: "Update existing PAM authentication source", + Before: noDanglingArgs, + Action: newAuthService().updatePAM, + Flags: append(pamCLIFlags()[:1], append([]cli.Flag{idFlag()}, pamCLIFlags()[1:]...)...), + } +} + +func parsePAMConfig(_ context.Context, c *cli.Command) *pam.Source { + return &pam.Source{ + ServiceName: c.String("service-name"), + EmailDomain: c.String("email-domain"), + SkipLocalTwoFA: c.Bool("skip-local-2fa"), + } +} + +func (a *authService) addPAM(ctx context.Context, c *cli.Command) error { + ctx, cancel := installSignals(ctx) + defer cancel() + + if err := a.initDB(ctx); err != nil { + return err + } + + if !c.IsSet("name") || len(c.String("name")) == 0 { + return errors.New("name must be set") + } + if !c.IsSet("service-name") || len(c.String("service-name")) == 0 { + return errors.New("service-name must be set") + } + active := true + if c.IsSet("active") { + active = c.Bool("active") + } + + config := parsePAMConfig(ctx, c) + + return a.createAuthSource(ctx, &auth_model.Source{ + Type: auth_model.PAM, + Name: c.String("name"), + IsActive: active, + Cfg: config, + }) +} + +func (a *authService) updatePAM(ctx context.Context, c *cli.Command) error { + if !c.IsSet("id") { + return errors.New("--id flag is missing") + } + + ctx, cancel := installSignals(ctx) + defer cancel() + + if err := a.initDB(ctx); err != nil { + return err + } + + source, err := a.getAuthSource(ctx, c, auth_model.PAM) + if err != nil { + return err + } + + pamConfig := source.Cfg.(*pam.Source) + + if c.IsSet("name") { + source.Name = c.String("name") + } + + if c.IsSet("service-name") { + pamConfig.ServiceName = c.String("service-name") + } + + if c.IsSet("email-domain") { + pamConfig.EmailDomain = c.String("email-domain") + } + + if c.IsSet("skip-local-2fa") { + pamConfig.SkipLocalTwoFA = c.Bool("skip-local-2fa") + } + + if c.IsSet("active") { + source.IsActive = c.Bool("active") + } + + source.Cfg = pamConfig + + return a.updateAuthSource(ctx, source) +} diff --git a/cmd/admin_auth_pam_test.go b/cmd/admin_auth_pam_test.go new file mode 100644 index 0000000000..d14dfe790b --- /dev/null +++ b/cmd/admin_auth_pam_test.go @@ -0,0 +1,293 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package cmd + +import ( + "context" + "testing" + + "forgejo.org/models/auth" + "forgejo.org/modules/test" + "forgejo.org/services/auth/source/pam" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/urfave/cli/v3" +) + +func TestPamService(t *testing.T) { + // Mock cli functions to do not exit on error + defer test.MockVariableValue(&cli.OsExiter, func(code int) {})() + + // Test cases + cases := []struct { + args []string + source *auth.Source + errMsg string + }{ + // case 0 + { + args: []string{ + "pam-test", + "--name", "Pam Service", + "--service-name", "myservice", + }, + source: &auth.Source{ + Type: auth.PAM, + Name: "Pam Service", + IsActive: true, + Cfg: &pam.Source{ + ServiceName: "myservice", + EmailDomain: "", + SkipLocalTwoFA: true, + }, + }, + }, + // case 1 + { + args: []string{ + "pam-test", + "--name", "Pam Service", + "--service-name", "myservice", + "--email-domain", "testdomain.org", + "--skip-local-2fa", + }, + source: &auth.Source{ + Type: auth.PAM, + Name: "Pam Service", + IsActive: true, + Cfg: &pam.Source{ + ServiceName: "myservice", + EmailDomain: "testdomain.org", + SkipLocalTwoFA: true, + }, + }, + }, + // case 2 + { + args: []string{ + "pam-test", + "--service-name", "myservice", + "--email-domain", "testdomain.org", + "--skip-local-2fa", "false", + "--active", "true", + }, + errMsg: "name must be set", + }, + // case 3 + { + args: []string{ + "pam-test", + "--name", "Pam Service", + "--email-domain", "testdomain.org", + "--skip-local-2fa", "false", + "--active", "true", + }, + errMsg: "service-name must be set", + }, + } + + for n, c := range cases { + // Mock functions. + var createdAuthSource *auth.Source + service := &authService{ + initDB: func(context.Context) error { + return nil + }, + createAuthSource: func(ctx context.Context, authSource *auth.Source) error { + createdAuthSource = authSource + return nil + }, + updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { + assert.FailNow(t, "should not call updateAuthSource", "case: %d", n) + return nil + }, + getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { + assert.FailNow(t, "should not call getAuthSourceByID", "case: %d", n) + return nil, nil + }, + } + + // Create a copy of command to test + app := cli.Command{} + app.Flags = microcmdAuthAddPAM().Flags + app.Action = service.addPAM + + // Run it + err := app.Run(t.Context(), c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + require.NoError(t, err, "case %d: should have no errors", n) + assert.Equal(t, c.source, createdAuthSource, "case %d: wrong authSource", n) + } + } +} + +func TestUpdatePAM(t *testing.T) { + // Mock cli functions to do not exit on error + defer test.MockVariableValue(&cli.OsExiter, func(code int) {})() + + // Test cases + cases := []struct { + args []string + id int64 + existingAuthSource *auth.Source + authSource *auth.Source + errMsg string + }{ + // case 0 + { + args: []string{ + "pam-test", + "--id", "23", + "--name", "PAM Service", + "--service-name", "myservice", + }, + id: 23, + existingAuthSource: &auth.Source{ + Type: auth.PAM, + IsActive: true, + Cfg: &pam.Source{}, + }, + authSource: &auth.Source{ + Type: auth.PAM, + Name: "PAM Service", + IsActive: true, + Cfg: &pam.Source{ + ServiceName: "myservice", + }, + }, + }, + // case 1 + { + args: []string{ + "pam-test", + "--id", "1", + }, + authSource: &auth.Source{ + Type: auth.PAM, + Cfg: &pam.Source{}, + }, + }, + // case 2 + { + args: []string{ + "pam-test", + "--id", "1", + "--name", "pam service", + }, + authSource: &auth.Source{ + Type: auth.PAM, + Name: "pam service", + Cfg: &pam.Source{}, + }, + }, + // case 3 + { + args: []string{ + "pam-test", + "--id", "1", + "--active=false", + }, + existingAuthSource: &auth.Source{ + Type: auth.PAM, + IsActive: true, + Cfg: &pam.Source{}, + }, + authSource: &auth.Source{ + Type: auth.PAM, + IsActive: false, + Cfg: &pam.Source{}, + }, + }, + // case 4 + { + args: []string{ + "pam-test", + "--id", "1", + "--service-name", "myservice", + }, + authSource: &auth.Source{ + Type: auth.PAM, + Cfg: &pam.Source{ + ServiceName: "myservice", + }, + }, + }, + // case 5 + { + args: []string{ + "pam-test", + "--id", "1", + "--skip-local-2fa=false", + }, + authSource: &auth.Source{ + Type: auth.PAM, + Cfg: &pam.Source{ + SkipLocalTwoFA: false, + }, + }, + }, + // case 6 + { + args: []string{ + "pam-test", + "--id", "1", + "--email-domain", "testdomain.org", + }, + authSource: &auth.Source{ + Type: auth.PAM, + Cfg: &pam.Source{ + EmailDomain: "testdomain.org", + }, + }, + }, + } + + for n, c := range cases { + // Mock functions. + var updatedAuthSource *auth.Source + service := &authService{ + initDB: func(context.Context) error { + return nil + }, + createAuthSource: func(ctx context.Context, authSource *auth.Source) error { + assert.FailNow(t, "should not call createAuthSource", "case: %d", n) + return nil + }, + updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { + updatedAuthSource = authSource + return nil + }, + getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { + if c.id != 0 { + assert.Equal(t, c.id, id, "case %d: wrong id", n) + } + if c.existingAuthSource != nil { + return c.existingAuthSource, nil + } + return &auth.Source{ + Type: auth.PAM, + Cfg: &pam.Source{}, + }, nil + }, + } + + // Create a copy of command to test + app := cli.Command{} + app.Flags = microcmdAuthUpdatePAM().Flags + app.Action = service.updatePAM + + // Run it + err := app.Run(t.Context(), c.args) + if c.errMsg != "" { + assert.EqualError(t, err, c.errMsg, "case %d: error should match", n) + } else { + require.NoError(t, err, "case %d: should have no errors", n) + assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n) + } + } +} From 23e10b2e4250de3e3563d7ee6abed77e90263f75 Mon Sep 17 00:00:00 2001 From: Bram Hagens Date: Sat, 20 Dec 2025 05:15:17 +0100 Subject: [PATCH 003/854] fix(ui): align due date icon in issue list (#10489) Flattened nested `` tags for the calender icon in the issue list, to fix the vertical alignment Before: ![image](/attachments/f5049acb-41dc-438e-9256-ef30542e168d) After: ![image](/attachments/c4d8bc64-0474-4a3e-9061-9e2bca6abff9) ![image](/attachments/0b2c4d9c-7d34-4627-be55-2099ed32dd19) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10489 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Bram Hagens Co-committed-by: Bram Hagens --- templates/shared/issuelist.tmpl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl index 256b5e3e07..ff7aa9c0a4 100644 --- a/templates/shared/issuelist.tmpl +++ b/templates/shared/issuelist.tmpl @@ -108,11 +108,9 @@ {{end}} {{if ne .DeadlineUnix 0}} - - - {{svg "octicon-calendar" 14}} - {{DateUtils.AbsoluteShort .DeadlineUnix}} - + + {{svg "octicon-calendar" 14}} + {{DateUtils.AbsoluteShort .DeadlineUnix}} {{end}} {{if .IsPull}} From 6041598369a49a14268edede6d7d1a96d848fab7 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 05:31:20 +0100 Subject: [PATCH 004/854] chore: update dependency asciinema-player to v3.13.5 (forgejo) (#10491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [asciinema-player](https://github.com/asciinema/asciinema-player) | [`3.13.4` -> `3.13.5`](https://renovatebot.com/diffs/npm/asciinema-player/3.13.4/3.13.5) | ![age](https://developer.mend.io/api/mc/badges/age/npm/asciinema-player/3.13.5?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/asciinema-player/3.13.4/3.13.5?slim=true) | --- ### Release Notes
asciinema/asciinema-player (asciinema-player) ### [`v3.13.5`](https://github.com/asciinema/asciinema-player/releases/tag/v3.13.5): 3.13.5 [Compare Source](https://github.com/asciinema/asciinema-player/compare/v3.13.4...v3.13.5) - Fixed rendering of shaded blocks (u2591, u2592, u2593) and quadrants (u2596, u2597, u2598) ([#​302](https://github.com/asciinema/asciinema-player/issues/302))
--- ### Configuration 📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC), Automerge - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10491 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 357528d355..de73a23fc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", "ansi_up": "6.0.5", - "asciinema-player": "3.13.4", + "asciinema-player": "3.13.5", "chart.js": "4.5.1", "chartjs-adapter-dayjs-4": "1.0.4", "chartjs-plugin-zoom": "2.2.0", @@ -5082,9 +5082,9 @@ } }, "node_modules/asciinema-player": { - "version": "3.13.4", - "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.13.4.tgz", - "integrity": "sha512-qCBqeTTCkF21XrmB5aSomviGDrEMpHGON4/5l9ZzhBCWLSxMiT5Yd0njK0e5qibNRe2pFaHWb326xsRTYmWMBQ==", + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.13.5.tgz", + "integrity": "sha512-mgpJc9g6I+k4Tz5qVUNd0H+GoYlhiUwvlay6vD6IXiuiWOWhBOjxbvqQ1bcI/HPTrOYxhTyxZuzHIXM36Tw60Q==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.21.0", diff --git a/package.json b/package.json index cee576d1ba..5f486327d9 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", "ansi_up": "6.0.5", - "asciinema-player": "3.13.4", + "asciinema-player": "3.13.5", "chart.js": "4.5.1", "chartjs-adapter-dayjs-4": "1.0.4", "chartjs-plugin-zoom": "2.2.0", From 8ef34a56d19fe365b4481356795b30898b7636a9 Mon Sep 17 00:00:00 2001 From: Bram Hagens Date: Sat, 20 Dec 2025 06:08:49 +0100 Subject: [PATCH 005/854] fix: ignore private .profile repo on user profile page (#10486) Fixes #4202 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10486 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Bram Hagens Co-committed-by: Bram Hagens --- routers/web/shared/user/header.go | 4 ++-- tests/integration/user_profile_test.go | 32 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index 745b3c1dca..e37e3cea64 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -97,8 +97,8 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) { func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profileDbRepo *repo_model.Repository, profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) { profileDbRepo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, ".profile") if err == nil { - // Don't show profile content if .profile repository is a fork - if profileDbRepo.IsFork { + // Don't show profile content if .profile repository is a fork or private + if profileDbRepo.IsFork || profileDbRepo.IsPrivate { return nil, nil, nil, func() {} } perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer) diff --git a/tests/integration/user_profile_test.go b/tests/integration/user_profile_test.go index 654ff0c094..10f3ce6be6 100644 --- a/tests/integration/user_profile_test.go +++ b/tests/integration/user_profile_test.go @@ -170,5 +170,37 @@ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequa assert.True(t, forkedRepo.IsFork, "Repository should be marked as a fork") assert.Equal(t, originalRepo.ID, forkedRepo.ForkID, "Fork should reference original repository") }) + + t.Run("private-profile-repo", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + + // Create a private .profile repository + profileRepo, _, f := tests.CreateDeclarativeRepo(t, user2, ".profile", nil, nil, []*files_service.ChangeRepoFile{ + { + Operation: "update", + TreePath: "README.md", + ContentReader: strings.NewReader("# Private Profile Content\nThis should NOT show up on user profile."), + }, + }) + defer f() + + // Make the repository private + profileRepo.IsPrivate = true + err := repo_service.UpdateRepository(git.DefaultContext, profileRepo, true) + require.NoError(t, err) + + // Verify that user2's profile does NOT show the private content + req := NewRequest(t, "GET", "/user2") + resp := MakeRequest(t, req, http.StatusOK) + bodyStr := resp.Body.String() + + assert.NotContains(t, bodyStr, "Private Profile Content", "Private .profile repo should NOT render profile content") + assert.NotContains(t, bodyStr, "This should NOT show up on user profile", "Private .profile repo should NOT render profile content") + + // Verify the repository is actually private + assert.True(t, profileRepo.IsPrivate, "Repository should be marked as private") + }) }) } From 0e6f9439ee2232fbdbfa59609b840a46ea20650b Mon Sep 17 00:00:00 2001 From: Andreas Ahlenstorf Date: Sat, 20 Dec 2025 15:29:40 +0100 Subject: [PATCH 006/854] chore: increase test coverage of runner management (#10490) Ensures that admins, users, etc. see the runners they are allowed to see. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10490 Reviewed-by: Gusted Co-authored-by: Andreas Ahlenstorf Co-committed-by: Andreas Ahlenstorf --- models/actions/runner_test.go | 95 +++++++++++++++++++ .../TestRunnerVisibility/action_runner.yml | 54 +++++++++++ tests/integration/runner_test.go | 70 ++++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 tests/integration/fixtures/TestRunnerVisibility/action_runner.yml diff --git a/models/actions/runner_test.go b/models/actions/runner_test.go index 1916c35a76..f6d6bd5d23 100644 --- a/models/actions/runner_test.go +++ b/models/actions/runner_test.go @@ -140,3 +140,98 @@ func TestDeleteOfflineRunnersErrorOnInvalidOlderThanValue(t *testing.T) { defer timeutil.MockUnset() require.Error(t, DeleteOfflineRunners(db.DefaultContext, timeutil.TimeStampNow(), false)) } + +func TestRunnerEditable(t *testing.T) { + testCases := []struct { + name string + runner *ActionRunner + ownerID int64 + repoID int64 + editable bool + }{ + { + name: "admin-can-edit-global-runner", + runner: &ActionRunner{Name: "global-runner", OwnerID: 0, RepoID: 0}, + ownerID: 0, + repoID: 0, + editable: true, + }, + { + name: "admin-can-edit-user-runner", + runner: &ActionRunner{Name: "user-runner", OwnerID: 36, RepoID: 0}, + ownerID: 0, + repoID: 0, + editable: true, + }, + { + name: "admin-can-edit-repository-runner", + runner: &ActionRunner{Name: "user-runner", OwnerID: 0, RepoID: 110}, + ownerID: 0, + repoID: 0, + editable: true, + }, + { + name: "user-can-edit-its-runner", + runner: &ActionRunner{Name: "user-runner", OwnerID: 469, RepoID: 0}, + ownerID: 469, + repoID: 0, + editable: true, + }, + { + name: "user-cannot-edit-global-runner", + runner: &ActionRunner{Name: "global-runner", OwnerID: 0, RepoID: 0}, + ownerID: 469, + repoID: 0, + editable: false, + }, + { + name: "user-cannot-edit-other-users-runner", + runner: &ActionRunner{Name: "user-runner", OwnerID: 892, RepoID: 0}, + ownerID: 469, + repoID: 0, + editable: false, + }, + { + name: "user-cannot-edit-repo-runner", + runner: &ActionRunner{Name: "repo-runner", OwnerID: 0, RepoID: 151}, + ownerID: 469, + repoID: 0, + editable: false, + }, + { + name: "repo-can-edit-its-runner", + runner: &ActionRunner{Name: "repo-runner", OwnerID: 0, RepoID: 693}, + ownerID: 0, + repoID: 693, + editable: true, + }, + { + name: "repo-cannot-edit-other-repo-runner", + runner: &ActionRunner{Name: "repo-runner", OwnerID: 0, RepoID: 519}, + ownerID: 0, + repoID: 693, + editable: false, + }, + { + name: "repo-cannot-edit-global-runner", + runner: &ActionRunner{Name: "global-runner", OwnerID: 0, RepoID: 0}, + ownerID: 0, + repoID: 693, + editable: false, + }, + { + name: "repo-cannot-edit-user-runner", + runner: &ActionRunner{Name: "user-runner", OwnerID: 6, RepoID: 0}, + ownerID: 0, + repoID: 693, + editable: false, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + result := testCase.runner.Editable(testCase.ownerID, testCase.repoID) + assert.Equal(t, testCase.editable, result) + }) + } +} diff --git a/tests/integration/fixtures/TestRunnerVisibility/action_runner.yml b/tests/integration/fixtures/TestRunnerVisibility/action_runner.yml new file mode 100644 index 0000000000..a20840396a --- /dev/null +++ b/tests/integration/fixtures/TestRunnerVisibility/action_runner.yml @@ -0,0 +1,54 @@ +- id: 719931 + uuid: "8f940b0b-32a2-479a-9d48-06ab8d8a0b90" + name: "runner-1" + version: "dev" + owner_id: 3 + repo_id: 0 + description: "A superb runner" + agent_labels: ["debian", "gpu"] + deleted: 0 +- id: 719932 + uuid: "3a20ad8d-d5d6-4b7b-ba55-841ac8264c17" + name: "runner-2" + version: "11.3.1" + owner_id: 2 + repo_id: 0 + description: "An exclusive runner" + agent_labels: ["docker"] + deleted: 0 +- id: 719933 + uuid: "11c9a6da-0a92-46ea-a4f1-b6c98f8c781c" + name: "runner-3" + version: "11.3.1" + owner_id: 17 + repo_id: 0 + description: "Another fine runner" + agent_labels: ["fedora"] + deleted: 0 +- id: 719934 + uuid: "1ef59b64-93b7-4ad4-ade4-21ca13db49c0" + name: "runner-4" + version: "12.2.0" + owner_id: 0 + repo_id: 0 + description: "A runner for everyone" + agent_labels: ["docker"] + deleted: 0 +- id: 719935 + uuid: "69d29449-1de5-4d17-845d-e3ae11a04a1b" + name: "runner-5" + version: "12.0.0" + owner_id: 1 + repo_id: 0 + description: "" + agent_labels: ["debian"] + deleted: 0 +- id: 719936 + uuid: "9da25fbb-89a5-4520-a35a-d55fc94e4b76" + name: "runner-6" + version: "12.1.0" + owner_id: 0 + repo_id: 62 + description: "" + agent_labels: ["debian"] + deleted: 0 diff --git a/tests/integration/runner_test.go b/tests/integration/runner_test.go index 6ca5a818d4..3379331e84 100644 --- a/tests/integration/runner_test.go +++ b/tests/integration/runner_test.go @@ -121,3 +121,73 @@ func TestRunnerModification(t *testing.T) { }) }) } + +func TestRunnerVisibility(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestRunnerVisibility")() + defer tests.PrepareTestEnv(t)() + + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{IsAdmin: true}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + + runnerOne := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 719931}) + runnerTwo := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 719932}) + runnerThree := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 719933}) + runnerFour := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 719934}) + runnerFive := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 719935}) + runnerSix := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 719936}) + + testCases := []struct { + name string + user *user_model.User + url string + expectedRunners []*actions_model.ActionRunner + unexpectedRunners []*actions_model.ActionRunner + }{ + { + name: "admin-sees-all", + user: admin, + url: "/admin/actions/runners", + expectedRunners: []*actions_model.ActionRunner{runnerOne, runnerTwo, runnerThree, runnerFour, runnerFive, runnerSix}, + unexpectedRunners: []*actions_model.ActionRunner{}, + }, + { + name: "user-sees-own-and-global", + user: user2, + url: "user/settings/actions/runners", + expectedRunners: []*actions_model.ActionRunner{runnerTwo, runnerFour}, + unexpectedRunners: []*actions_model.ActionRunner{runnerOne, runnerThree, runnerFive, runnerSix}, + }, + { + name: "org-sees-own-and-global", + user: user2, + url: "/org/org3/settings/actions/runners", + expectedRunners: []*actions_model.ActionRunner{runnerOne, runnerFour}, + unexpectedRunners: []*actions_model.ActionRunner{runnerTwo, runnerThree, runnerFive, runnerSix}, + }, + { + name: "user-repo-sees-own-and-users-and-global", + user: user2, + url: "/user2/test_workflows/settings/actions/runners", + expectedRunners: []*actions_model.ActionRunner{runnerTwo, runnerFour, runnerSix}, + unexpectedRunners: []*actions_model.ActionRunner{runnerOne, runnerThree, runnerFive}, + }, + } + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + session := loginUser(t, testCase.user.Name) + + request := NewRequest(t, "GET", testCase.url) + response := session.MakeRequest(t, request, http.StatusOK) + + htmlDoc := NewHTMLParser(t, response.Body) + for _, expectedRunner := range testCase.expectedRunners { + selector := fmt.Sprintf("td:contains('%s')", expectedRunner.Name) + assert.Equal(t, 1, htmlDoc.Find(selector).Length(), "runner '%s' could not be found", expectedRunner.Name) + } + for _, unexpectedRunner := range testCase.unexpectedRunners { + selector := fmt.Sprintf("td:contains('%s')", unexpectedRunner.Name) + assert.Zero(t, htmlDoc.Find(selector).Length(), "runner '%s' is unexpectedly present", unexpectedRunner.Name) + } + }) + } +} From 9d824142e4fd2703432550044aebeea25f88d3a8 Mon Sep 17 00:00:00 2001 From: Bram Hagens Date: Sat, 20 Dec 2025 15:37:27 +0100 Subject: [PATCH 007/854] feat: show update time when sorting by recently updated (#10488) Fixes #4712 Fixes #7783 When filtering issues or PRs by "Recently updated" or "Least recently updated", the last updated time is shown. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10488 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Reviewed-by: Gusted Co-authored-by: Bram Hagens Co-committed-by: Bram Hagens --- options/locale_next/locale_en-US.json | 1 + templates/shared/issuelist.tmpl | 6 ++++++ tests/integration/issue_test.go | 30 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json index d9d23653cd..38d7d18e7e 100644 --- a/options/locale_next/locale_en-US.json +++ b/options/locale_next/locale_en-US.json @@ -62,6 +62,7 @@ "repo.issues.filter_mention.hint": "Filter by mentioned user", "repo.issues.filter_modified.hint": "Filter by last modified date", "repo.issues.filter_sort.hint": "Sort by: created/comments/updated/deadline", + "issues.updated": "updated %s", "repo.pulls.poster_manage_approval": "Manage approval", "repo.pulls.poster_requires_approval": "Some workflows are waiting to be reviewed.", "repo.pulls.poster_requires_approval.tooltip": "The author of this pull request is not trusted to run workflows triggered by a pull request created from a forked repository or with AGit. The workflows triggered by a `pull_request` event will not run until they are approved.", diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl index ff7aa9c0a4..3e20cc5080 100644 --- a/templates/shared/issuelist.tmpl +++ b/templates/shared/issuelist.tmpl @@ -142,6 +142,12 @@ {{end}} {{end}} + {{if or (eq $.SortType "recentupdate") (eq $.SortType "leastupdate")}} + + {{svg "octicon-history" 14}} + {{ctx.Locale.Tr "issues.updated" (DateUtils.TimeSince .UpdatedUnix)}} + + {{end}} diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go index 2e7428a1ac..b47f3fd534 100644 --- a/tests/integration/issue_test.go +++ b/tests/integration/issue_test.go @@ -131,6 +131,36 @@ func TestViewIssuesSortByType(t *testing.T) { } } +func TestViewIssuesSortByUpdatedTime(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + + // When sorting by update time, the "updated" text and icon should appear + for _, sort := range []string{"recentupdate", "leastupdate"} { + req := NewRequest(t, "GET", repo.Link()+"/issues?sort="+sort) + resp := MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + + issueList := htmlDoc.doc.Find("#issue-list") + updatedText := issueList.Find(".flex-item-body").First().Text() + assert.Contains(t, updatedText, "updated") + + historyIcon := issueList.Find(".octicon-history") + assert.Positive(t, historyIcon.Length()) + } + + // When sorting by something else, the "updated" text and icon should NOT appear + req := NewRequest(t, "GET", repo.Link()+"/issues?sort=latest") + resp := MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + issueList := htmlDoc.doc.Find("#issue-list") + historyIcon := issueList.Find(".octicon-history") + assert.Empty(t, historyIcon.Length()) +} + func TestViewIssuesKeyword(t *testing.T) { defer tests.PrepareTestEnv(t)() From 42c8470d07409dc6ab3565d4f0c8550f3a841c49 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 15:44:47 +0100 Subject: [PATCH 008/854] Update dependency webpack to v5.104.0 (forgejo) (#10492) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10492 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 29 ++++++++++++++++++----------- package.json | 2 +- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index de73a23fc1..88b452f509 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,7 +56,7 @@ "vue-chartjs": "5.3.3", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.103.0", + "webpack": "5.104.0", "webpack-cli": "6.0.1", "wrap-ansi": "9.0.2" }, @@ -7218,6 +7218,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { @@ -14253,9 +14254,9 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.15", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.15.tgz", - "integrity": "sha512-PGkOdpRFK+rb1TzVz+msVhw4YMRT9txLF4kRqvJhGhCM324xuR3REBSHALN+l+sAhKUmz0aotnjp5D+P83mLhQ==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", @@ -15312,9 +15313,9 @@ "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.103.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", - "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", + "version": "5.104.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.0.tgz", + "integrity": "sha512-5DeICTX8BVgNp6afSPYXAFjskIgWGlygQH58bcozPOXgo2r/6xx39Y1+cULZ3gTxUYQP88jmwLj2anu4Xaq84g==", "license": "MIT", "peer": true, "dependencies": { @@ -15326,10 +15327,10 @@ "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.26.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.3", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.17.4", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -15340,7 +15341,7 @@ "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.11", + "terser-webpack-plugin": "^5.3.16", "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" }, @@ -15442,6 +15443,12 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, + "node_modules/webpack/node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "license": "MIT" + }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", diff --git a/package.json b/package.json index 5f486327d9..7c55fc5884 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "vue-chartjs": "5.3.3", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.103.0", + "webpack": "5.104.0", "webpack-cli": "6.0.1", "wrap-ansi": "9.0.2" }, From 39189baa170cf7692b3533f288874e7edac71282 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 17:13:12 +0100 Subject: [PATCH 009/854] Update module github.com/alecthomas/chroma/v2 to v2.21.1 (forgejo) (#10479) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10479 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 2 +- go.sum | 8 ++++---- modules/indexer/code/search_test.go | 8 ++++---- modules/markup/html_test.go | 26 +++++++++++++------------- modules/markup/orgmode/orgmode_test.go | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 9e1615f9d2..c0605b8fb2 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/ProtonMail/go-crypto v1.3.0 github.com/PuerkitoBio/goquery v1.10.3 github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2 - github.com/alecthomas/chroma/v2 v2.20.0 + github.com/alecthomas/chroma/v2 v2.21.1 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blevesearch/bleve/v2 v2.5.6 github.com/buildkite/terminal-to-html/v3 v3.16.8 diff --git a/go.sum b/go.sum index 17be63a395..39a33681c3 100644 --- a/go.sum +++ b/go.sum @@ -89,11 +89,11 @@ github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2/go.mod h1:JitQWJ8JuV4Y github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= -github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= -github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA= +github.com/alecthomas/chroma/v2 v2.21.1 h1:FaSDrp6N+3pphkNKU6HPCiYLgm8dbe5UXIXcoBhZSWA= +github.com/alecthomas/chroma/v2 v2.21.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= -github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg= -github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= +github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= diff --git a/modules/indexer/code/search_test.go b/modules/indexer/code/search_test.go index 2413ddec0b..b8fe852bb8 100644 --- a/modules/indexer/code/search_test.go +++ b/modules/indexer/code/search_test.go @@ -87,8 +87,8 @@ func TestHighlightSearchResultCode(t *testing.T) { Code: "func main() {\n\tfmt.Println(\"mark this\")\n}", Result: []template.HTML{ "func main() {", - "\tfmt.Println("mark this")", - "}", + "\tfmt.Println("mark this")", + "}", }, }, { @@ -98,8 +98,8 @@ func TestHighlightSearchResultCode(t *testing.T) { Code: "func main() {\n\tfmt.Println(\"mark this 😊\")\n}", Result: []template.HTML{ "func main() {", - "\tfmt.Println("mark this 😊")", - "}", + "\tfmt.Println("mark this 😊")", + "}", }, }, } diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index c7c53e2678..512a7aa02a 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -795,7 +795,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -829,7 +829,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -908,7 +908,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -939,7 +939,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -972,7 +972,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -997,7 +997,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -1028,7 +1028,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -1053,7 +1053,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -1078,7 +1078,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ @@ -1113,7 +1113,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `B`+"\n"+``+ + `B`+"\n"+``+ ``+ ``+ ``+ @@ -1146,7 +1146,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `B`+"\n"+``+ + `B`+"\n"+``+ ``+ ``+ ``+ @@ -1179,7 +1179,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `B`+"\n"+``+ + `B`+"\n"+``+ ``+ ``+ ``+ @@ -1214,7 +1214,7 @@ func TestRender_FilePreview(t *testing.T) { ``+ ``+ ``+ - `C`+"\n"+``+ + `C`+"\n"+``+ ``+ ``+ ``+ diff --git a/modules/markup/orgmode/orgmode_test.go b/modules/markup/orgmode/orgmode_test.go index 71157dc7c7..723d78e745 100644 --- a/modules/markup/orgmode/orgmode_test.go +++ b/modules/markup/orgmode/orgmode_test.go @@ -153,8 +153,8 @@ func HelloWorld() { #+end_src `, `
// HelloWorld prints "Hello World"
-func HelloWorld() {
+func HelloWorld() {
 	fmt.Println("Hello World")
-}
+}
`) } From d0686f4a12fd6ffe48312cb9c973c8efb3ef6576 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 19:56:09 +0100 Subject: [PATCH 010/854] Update dependency @vitejs/plugin-vue to v6.0.3 (forgejo) (#10503) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 88b452f509..fd872c58d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,7 @@ "@stoplight/spectral-cli": "6.15.0", "@stylistic/eslint-plugin": "5.6.1", "@stylistic/stylelint-plugin": "4.0.0", - "@vitejs/plugin-vue": "6.0.2", + "@vitejs/plugin-vue": "6.0.3", "@vitest/coverage-v8": "4.0.14", "@vitest/eslint-plugin": "1.3.16", "@vue/test-utils": "2.4.6", @@ -2333,9 +2333,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.50", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.50.tgz", - "integrity": "sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==", + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", + "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==", "dev": true, "license": "MIT" }, @@ -4276,19 +4276,19 @@ ] }, "node_modules/@vitejs/plugin-vue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.2.tgz", - "integrity": "sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz", + "integrity": "sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==", "dev": true, "license": "MIT", "dependencies": { - "@rolldown/pluginutils": "1.0.0-beta.50" + "@rolldown/pluginutils": "1.0.0-beta.53" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "vue": "^3.2.25" } }, diff --git a/package.json b/package.json index 7c55fc5884..923bf08cea 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@stoplight/spectral-cli": "6.15.0", "@stylistic/eslint-plugin": "5.6.1", "@stylistic/stylelint-plugin": "4.0.0", - "@vitejs/plugin-vue": "6.0.2", + "@vitejs/plugin-vue": "6.0.3", "@vitest/coverage-v8": "4.0.14", "@vitest/eslint-plugin": "1.3.16", "@vue/test-utils": "2.4.6", From 3744b2866d0606b8d5deb0f154feb89aaac9f8cf Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 19:57:19 +0100 Subject: [PATCH 011/854] Update linters (forgejo) (#10506) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 148 ++++++++++++++++++++++------------------------ package.json | 4 +- 2 files changed, 72 insertions(+), 80 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd872c58d4..ae0af220f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,7 +71,7 @@ "@vitest/coverage-v8": "4.0.14", "@vitest/eslint-plugin": "1.3.16", "@vue/test-utils": "2.4.6", - "eslint": "9.39.1", + "eslint": "9.39.2", "eslint-import-resolver-typescript": "4.4.4", "eslint-plugin-array-func": "5.1.0", "eslint-plugin-import-x": "4.16.1", @@ -98,7 +98,7 @@ "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "4.0.0", "typescript": "5.9.3", - "typescript-eslint": "8.48.0", + "typescript-eslint": "8.50.0", "vite-string-plugin": "1.4.9", "vitest": "4.0.14" }, @@ -1271,9 +1271,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", "dev": true, "license": "MIT", "engines": { @@ -3742,18 +3742,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.0.tgz", - "integrity": "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.0.tgz", + "integrity": "sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/type-utils": "8.48.0", - "@typescript-eslint/utils": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", - "graphemer": "^1.4.0", + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/type-utils": "8.50.0", + "@typescript-eslint/utils": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" @@ -3766,7 +3765,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.48.0", + "@typescript-eslint/parser": "^8.50.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -3782,17 +3781,17 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.0.tgz", - "integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.0.tgz", + "integrity": "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", "debug": "^4.3.4" }, "engines": { @@ -3808,14 +3807,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.0.tgz", - "integrity": "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", + "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.48.0", - "@typescript-eslint/types": "^8.48.0", + "@typescript-eslint/tsconfig-utils": "^8.50.0", + "@typescript-eslint/types": "^8.50.0", "debug": "^4.3.4" }, "engines": { @@ -3830,14 +3829,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.0.tgz", - "integrity": "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.0.tgz", + "integrity": "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0" + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3848,9 +3847,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.0.tgz", - "integrity": "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", + "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", "dev": true, "license": "MIT", "engines": { @@ -3865,15 +3864,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.0.tgz", - "integrity": "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.0.tgz", + "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/utils": "8.50.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -3890,9 +3889,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.0.tgz", - "integrity": "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", + "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", "dev": true, "license": "MIT", "engines": { @@ -3904,16 +3903,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.0.tgz", - "integrity": "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", + "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.48.0", - "@typescript-eslint/tsconfig-utils": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/visitor-keys": "8.48.0", + "@typescript-eslint/project-service": "8.50.0", + "@typescript-eslint/tsconfig-utils": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", "debug": "^4.3.4", "minimatch": "^9.0.4", "semver": "^7.6.0", @@ -3965,16 +3964,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.0.tgz", - "integrity": "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", + "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.48.0", - "@typescript-eslint/types": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0" + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3989,13 +3988,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.0.tgz", - "integrity": "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", + "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.48.0", + "@typescript-eslint/types": "8.50.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -7362,9 +7361,9 @@ } }, "node_modules/eslint": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", - "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", "peer": true, @@ -7375,7 +7374,7 @@ "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.1", + "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -8612,13 +8611,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/hachure-fill": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", @@ -14636,16 +14628,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.48.0.tgz", - "integrity": "sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.50.0.tgz", + "integrity": "sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.48.0", - "@typescript-eslint/parser": "8.48.0", - "@typescript-eslint/typescript-estree": "8.48.0", - "@typescript-eslint/utils": "8.48.0" + "@typescript-eslint/eslint-plugin": "8.50.0", + "@typescript-eslint/parser": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/utils": "8.50.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/package.json b/package.json index 923bf08cea..c9e0e6bea9 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@vitest/coverage-v8": "4.0.14", "@vitest/eslint-plugin": "1.3.16", "@vue/test-utils": "2.4.6", - "eslint": "9.39.1", + "eslint": "9.39.2", "eslint-import-resolver-typescript": "4.4.4", "eslint-plugin-array-func": "5.1.0", "eslint-plugin-import-x": "4.16.1", @@ -97,7 +97,7 @@ "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "4.0.0", "typescript": "5.9.3", - "typescript-eslint": "8.48.0", + "typescript-eslint": "8.50.0", "vite-string-plugin": "1.4.9", "vitest": "4.0.14" }, From 22d4103cd0b9382f86284584072fbc3cac269a38 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 19:57:53 +0100 Subject: [PATCH 012/854] Update go-openapi packages (forgejo) (#10505) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10505 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 20 ++++++++++---------- go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index c0605b8fb2..a93c63b73d 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/go-co-op/gocron v1.37.0 github.com/go-enry/go-enry/v2 v2.9.2 github.com/go-ldap/ldap/v3 v3.4.12 - github.com/go-openapi/spec v0.22.1 + github.com/go-openapi/spec v0.22.2 github.com/go-sql-driver/mysql v1.9.3 github.com/go-webauthn/webauthn v0.14.0 github.com/gobwas/glob v0.2.3 @@ -181,15 +181,15 @@ require ( github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-git/go-git/v5 v5.16.3 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/go-openapi/jsonpointer v0.22.3 // indirect - github.com/go-openapi/jsonreference v0.21.3 // indirect - github.com/go-openapi/swag/conv v0.25.3 // indirect - github.com/go-openapi/swag/jsonname v0.25.3 // indirect - github.com/go-openapi/swag/jsonutils v0.25.3 // indirect - github.com/go-openapi/swag/loading v0.25.3 // indirect - github.com/go-openapi/swag/stringutils v0.25.3 // indirect - github.com/go-openapi/swag/typeutils v0.25.3 // indirect - github.com/go-openapi/swag/yamlutils v0.25.3 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-webauthn/x v0.1.25 // indirect github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect github.com/goccy/go-json v0.10.5 // indirect diff --git a/go.sum b/go.sum index 39a33681c3..e33c2388a5 100644 --- a/go.sum +++ b/go.sum @@ -307,28 +307,28 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4= github.com/go-ldap/ldap/v3 v3.4.12/go.mod h1:+SPAGcTtOfmGsCb3h1RFiq4xpp4N636G75OEace8lNo= -github.com/go-openapi/jsonpointer v0.22.3 h1:dKMwfV4fmt6Ah90zloTbUKWMD+0he+12XYAsPotrkn8= -github.com/go-openapi/jsonpointer v0.22.3/go.mod h1:0lBbqeRsQ5lIanv3LHZBrmRGHLHcQoOXQnf88fHlGWo= -github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= -github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= -github.com/go-openapi/spec v0.22.1 h1:beZMa5AVQzRspNjvhe5aG1/XyBSMeX1eEOs7dMoXh/k= -github.com/go-openapi/spec v0.22.1/go.mod h1:c7aeIQT175dVowfp7FeCvXXnjN/MrpaONStibD2WtDA= -github.com/go-openapi/swag/conv v0.25.3 h1:PcB18wwfba7MN5BVlBIV+VxvUUeC2kEuCEyJ2/t2X7E= -github.com/go-openapi/swag/conv v0.25.3/go.mod h1:n4Ibfwhn8NJnPXNRhBO5Cqb9ez7alBR40JS4rbASUPU= -github.com/go-openapi/swag/jsonname v0.25.3 h1:U20VKDS74HiPaLV7UZkztpyVOw3JNVsit+w+gTXRj0A= -github.com/go-openapi/swag/jsonname v0.25.3/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= -github.com/go-openapi/swag/jsonutils v0.25.3 h1:kV7wer79KXUM4Ea4tBdAVTU842Rg6tWstX3QbM4fGdw= -github.com/go-openapi/swag/jsonutils v0.25.3/go.mod h1:ILcKqe4HC1VEZmJx51cVuZQ6MF8QvdfXsQfiaCs0z9o= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.3 h1:/i3E9hBujtXfHy91rjtwJ7Fgv5TuDHgnSrYjhFxwxOw= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.3/go.mod h1:8kYfCR2rHyOj25HVvxL5Nm8wkfzggddgjZm6RgjT8Ao= -github.com/go-openapi/swag/loading v0.25.3 h1:Nn65Zlzf4854MY6Ft0JdNrtnHh2bdcS/tXckpSnOb2Y= -github.com/go-openapi/swag/loading v0.25.3/go.mod h1:xajJ5P4Ang+cwM5gKFrHBgkEDWfLcsAKepIuzTmOb/c= -github.com/go-openapi/swag/stringutils v0.25.3 h1:nAmWq1fUTWl/XiaEPwALjp/8BPZJun70iDHRNq/sH6w= -github.com/go-openapi/swag/stringutils v0.25.3/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= -github.com/go-openapi/swag/typeutils v0.25.3 h1:2w4mEEo7DQt3V4veWMZw0yTPQibiL3ri2fdDV4t2TQc= -github.com/go-openapi/swag/typeutils v0.25.3/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= -github.com/go-openapi/swag/yamlutils v0.25.3 h1:LKTJjCn/W1ZfMec0XDL4Vxh8kyAnv1orH5F2OREDUrg= -github.com/go-openapi/swag/yamlutils v0.25.3/go.mod h1:Y7QN6Wc5DOBXK14/xeo1cQlq0EA0wvLoSv13gDQoCao= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/spec v0.22.2 h1:KEU4Fb+Lp1qg0V4MxrSCPv403ZjBl8Lx1a83gIPU8Qc= +github.com/go-openapi/spec v0.22.2/go.mod h1:iIImLODL2loCh3Vnox8TY2YWYJZjMAKYyLH2Mu8lOZs= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= From 8650f05f316acf3edfdbd329eb0515f562d16056 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 19:58:25 +0100 Subject: [PATCH 013/854] Update dependency markdownlint-cli to v0.47.0 (forgejo) (#10508) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 147 ++++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 57 insertions(+), 92 deletions(-) diff --git a/package-lock.json b/package-lock.json index ae0af220f3..c32246ee81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,7 +89,7 @@ "globals": "16.5.0", "happy-dom": "20.0.11", "license-checker-rseidelsohn": "4.4.2", - "markdownlint-cli": "0.45.0", + "markdownlint-cli": "0.47.0", "postcss-html": "1.8.0", "sharp": "0.34.5", "stylelint": "16.26.1", @@ -10394,9 +10394,9 @@ } }, "node_modules/markdownlint": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", - "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.40.0.tgz", + "integrity": "sha512-UKybllYNheWac61Ia7T6fzuQNDZimFIpCg2w6hHjgV1Qu0w1TV0LlSgryUGzM0bkKQCBhy2FDhEELB73Kb0kAg==", "dev": true, "license": "MIT", "dependencies": { @@ -10407,7 +10407,8 @@ "micromark-extension-gfm-footnote": "2.1.0", "micromark-extension-gfm-table": "2.1.1", "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2" + "micromark-util-types": "2.0.2", + "string-width": "8.1.0" }, "engines": { "node": ">=20" @@ -10417,23 +10418,24 @@ } }, "node_modules/markdownlint-cli": { - "version": "0.45.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.45.0.tgz", - "integrity": "sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==", + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.47.0.tgz", + "integrity": "sha512-HOcxeKFAdDoldvoYDofd85vI8LgNWy8vmYpCwnlLV46PJcodmGzD7COSSBlhHwsfT4o9KrAStGodImVBus31Bg==", "dev": true, "license": "MIT", "dependencies": { - "commander": "~13.1.0", - "glob": "~11.0.2", - "ignore": "~7.0.4", - "js-yaml": "~4.1.0", + "commander": "~14.0.2", + "deep-extend": "~0.6.0", + "ignore": "~7.0.5", + "js-yaml": "~4.1.1", "jsonc-parser": "~3.3.1", "jsonpointer": "~5.0.1", "markdown-it": "~14.1.0", - "markdownlint": "~0.38.0", - "minimatch": "~10.0.1", + "markdownlint": "~0.40.0", + "minimatch": "~10.1.1", "run-con": "~1.3.2", - "smol-toml": "~1.3.4" + "smol-toml": "~1.5.2", + "tinyglobby": "~0.2.15" }, "bin": { "markdownlint": "markdownlint.js" @@ -10443,37 +10445,13 @@ } }, "node_modules/markdownlint-cli/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" - } - }, - "node_modules/markdownlint-cli/node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=20" } }, "node_modules/markdownlint-cli/node_modules/ignore": { @@ -10486,22 +10464,6 @@ "node": ">= 4" } }, - "node_modules/markdownlint-cli/node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/markdownlint-cli/node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", @@ -10509,47 +10471,50 @@ "dev": true, "license": "MIT" }, - "node_modules/markdownlint-cli/node_modules/lru-cache": { - "version": "11.2.4", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", - "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "node_modules/markdownlint/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "engines": { - "node": "20 || >=22" - } - }, - "node_modules/markdownlint-cli/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/markdownlint-cli/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "node_modules/markdownlint/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": "20 || >=22" + "node": ">=20" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/marked": { @@ -13414,9 +13379,9 @@ } }, "node_modules/smol-toml": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.4.tgz", - "integrity": "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.2.tgz", + "integrity": "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==", "dev": true, "license": "BSD-3-Clause", "engines": { diff --git a/package.json b/package.json index c9e0e6bea9..0e4e0cad5c 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "globals": "16.5.0", "happy-dom": "20.0.11", "license-checker-rseidelsohn": "4.4.2", - "markdownlint-cli": "0.45.0", + "markdownlint-cli": "0.47.0", "postcss-html": "1.8.0", "sharp": "0.34.5", "stylelint": "16.26.1", From deafea3612300f91732205ee0c2f506dc0607b1e Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 19:58:28 +0100 Subject: [PATCH 014/854] Update module github.com/golangci/golangci-lint/v2/cmd/golangci-lint to v2.7.2 (forgejo) (#10509) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index db363d216b..37c04a31f6 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ XGO_VERSION := go-1.21.x AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.6.0 # renovate: datasource=go GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.9.2 # renovate: datasource=go -GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6.2 # renovate: datasource=go +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7.2 # renovate: datasource=go GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.15 # renovate: datasource=go SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.33.1 # renovate: datasource=go XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest From 1ef8f33683d9f9a125f1b94a9c843141290c8d40 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 19:58:31 +0100 Subject: [PATCH 015/854] Update module github.com/PuerkitoBio/goquery to v1.11.0 (forgejo) (#10510) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a93c63b73d..690955237b 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920 github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 github.com/ProtonMail/go-crypto v1.3.0 - github.com/PuerkitoBio/goquery v1.10.3 + github.com/PuerkitoBio/goquery v1.11.0 github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2 github.com/alecthomas/chroma/v2 v2.21.1 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb diff --git a/go.sum b/go.sum index e33c2388a5..3c526a8cf0 100644 --- a/go.sum +++ b/go.sum @@ -78,8 +78,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= -github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo= -github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y= +github.com/PuerkitoBio/goquery v1.11.0 h1:jZ7pwMQXIITcUXNH83LLk+txlaEy6NVOfTuP43xxfqw= +github.com/PuerkitoBio/goquery v1.11.0/go.mod h1:wQHgxUOU3JGuj3oD/QFfxUdlzW6xPHfqyHre6VMY4DQ= github.com/RoaringBitmap/roaring/v2 v2.4.5 h1:uGrrMreGjvAtTBobc0g5IrW1D5ldxDQYe2JW2gggRdg= github.com/RoaringBitmap/roaring/v2 v2.4.5/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0= github.com/STARRY-S/zip v0.2.3 h1:luE4dMvRPDOWQdeDdUxUoZkzUIpTccdKdhHHsQJ1fm4= From 925549d521e268105a79aa0bc8bc479c3faac7e4 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 19:58:51 +0100 Subject: [PATCH 016/854] Update x/tools to v0.40.0 (forgejo) (#10511) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- Makefile | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 37c04a31f6..ae66a3e471 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.33.1 # renova XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasource=go GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go -DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.39.0 # renovate: datasource=go +DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.40.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.6.0 # renovate: datasource=go RENOVATE_NPM_PACKAGE ?= renovate@42.39.2 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate diff --git a/go.mod b/go.mod index 690955237b..7516b5a680 100644 --- a/go.mod +++ b/go.mod @@ -104,7 +104,7 @@ require ( go.yaml.in/yaml/v3 v3.0.4 golang.org/x/crypto v0.46.0 golang.org/x/image v0.33.0 - golang.org/x/net v0.47.0 + golang.org/x/net v0.48.0 golang.org/x/oauth2 v0.34.0 golang.org/x/sync v0.19.0 golang.org/x/sys v0.39.0 @@ -267,7 +267,7 @@ require ( go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/mod v0.31.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 3c526a8cf0..6792d6d404 100644 --- a/go.sum +++ b/go.sum @@ -820,8 +820,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -943,8 +943,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From b90eda6ed70ceff415b4d3b856b0eddd8089d721 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 20 Dec 2025 21:36:37 +0100 Subject: [PATCH 017/854] Update vitest monorepo to v4.0.16 (forgejo) (#10507) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 107 ++++++++++++++++++++++------------------------ package.json | 4 +- 2 files changed, 52 insertions(+), 59 deletions(-) diff --git a/package-lock.json b/package-lock.json index c32246ee81..3652561b3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,7 +68,7 @@ "@stylistic/eslint-plugin": "5.6.1", "@stylistic/stylelint-plugin": "4.0.0", "@vitejs/plugin-vue": "6.0.3", - "@vitest/coverage-v8": "4.0.14", + "@vitest/coverage-v8": "4.0.16", "@vitest/eslint-plugin": "1.3.16", "@vue/test-utils": "2.4.6", "eslint": "9.39.2", @@ -100,7 +100,7 @@ "typescript": "5.9.3", "typescript-eslint": "8.50.0", "vite-string-plugin": "1.4.9", - "vitest": "4.0.14" + "vitest": "4.0.16" }, "engines": { "node": ">= 20.0.0" @@ -4292,14 +4292,14 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.14.tgz", - "integrity": "sha512-EYHLqN/BY6b47qHH7gtMxAg++saoGmsjWmAq9MlXxAz4M0NcHh9iOyKhBZyU4yxZqOd8Xnqp80/5saeitz4Cng==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.16.tgz", + "integrity": "sha512-2rNdjEIsPRzsdu6/9Eq0AYAzYdpP6Bx9cje9tL3FE5XzXRQF1fNU9pe/1yE8fCrS0HD+fBtt6gLPh6LI57tX7A==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.0.14", + "@vitest/utils": "4.0.16", "ast-v8-to-istanbul": "^0.3.8", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -4314,8 +4314,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.0.14", - "vitest": "4.0.14" + "@vitest/browser": "4.0.16", + "vitest": "4.0.16" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -4348,16 +4348,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.14.tgz", - "integrity": "sha512-RHk63V3zvRiYOWAV0rGEBRO820ce17hz7cI2kDmEdfQsBjT2luEKB5tCOc91u1oSQoUOZkSv3ZyzkdkSLD7lKw==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.16.tgz", + "integrity": "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.14", - "@vitest/utils": "4.0.14", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", "chai": "^6.2.1", "tinyrainbow": "^3.0.3" }, @@ -4366,13 +4366,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.14.tgz", - "integrity": "sha512-RzS5NujlCzeRPF1MK7MXLiEFpkIXeMdQ+rN3Kk3tDI9j0mtbr7Nmuq67tpkOJQpgyClbOltCXMjLZicJHsH5Cg==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.16.tgz", + "integrity": "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.0.14", + "@vitest/spy": "4.0.16", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -4420,9 +4420,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.14.tgz", - "integrity": "sha512-SOYPgujB6TITcJxgd3wmsLl+wZv+fy3av2PpiPpsWPZ6J1ySUYfScfpIt2Yv56ShJXR2MOA6q2KjKHN4EpdyRQ==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.16.tgz", + "integrity": "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==", "dev": true, "license": "MIT", "dependencies": { @@ -4433,13 +4433,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.14.tgz", - "integrity": "sha512-BsAIk3FAqxICqREbX8SetIteT8PiaUL/tgJjmhxJhCsigmzzH8xeadtp7LRnTpCVzvf0ib9BgAfKJHuhNllKLw==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.16.tgz", + "integrity": "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.14", + "@vitest/utils": "4.0.16", "pathe": "^2.0.3" }, "funding": { @@ -4447,13 +4447,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.14.tgz", - "integrity": "sha512-aQVBfT1PMzDSA16Y3Fp45a0q8nKexx6N5Amw3MX55BeTeZpoC08fGqEZqVmPcqN0ueZsuUQ9rriPMhZ3Mu19Ag==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.16.tgz", + "integrity": "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.14", + "@vitest/pretty-format": "4.0.16", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -4472,9 +4472,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.14.tgz", - "integrity": "sha512-JmAZT1UtZooO0tpY3GRyiC/8W7dCs05UOq9rfsUUgEZEdq+DuHLmWhPsrTt0TiW7WYeL/hXpaE07AZ2RCk44hg==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.16.tgz", + "integrity": "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==", "dev": true, "license": "MIT", "funding": { @@ -4482,13 +4482,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.14.tgz", - "integrity": "sha512-hLqXZKAWNg8pI+SQXyXxWCTOpA3MvsqcbVeNgSi8x/CSN2wi26dSzn1wrOhmCmFjEvN9p8/kLFRHa6PI8jHazw==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.16.tgz", + "integrity": "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.14", + "@vitest/pretty-format": "4.0.16", "tinyrainbow": "^3.0.3" }, "funding": { @@ -14994,20 +14994,20 @@ } }, "node_modules/vitest": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.14.tgz", - "integrity": "sha512-d9B2J9Cm9dN9+6nxMnnNJKJCtcyKfnHj15N6YNJfaFHRLua/d3sRKU9RuKmO9mB0XdFtUizlxfz/VPbd3OxGhw==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.16.tgz", + "integrity": "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/expect": "4.0.14", - "@vitest/mocker": "4.0.14", - "@vitest/pretty-format": "4.0.14", - "@vitest/runner": "4.0.14", - "@vitest/snapshot": "4.0.14", - "@vitest/spy": "4.0.14", - "@vitest/utils": "4.0.14", + "@vitest/expect": "4.0.16", + "@vitest/mocker": "4.0.16", + "@vitest/pretty-format": "4.0.16", + "@vitest/runner": "4.0.16", + "@vitest/snapshot": "4.0.16", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", "es-module-lexer": "^1.7.0", "expect-type": "^1.2.2", "magic-string": "^0.30.21", @@ -15016,7 +15016,7 @@ "picomatch": "^4.0.3", "std-env": "^3.10.0", "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", + "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.0.3", "vite": "^6.0.0 || ^7.0.0", @@ -15035,10 +15035,10 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.0.14", - "@vitest/browser-preview": "4.0.14", - "@vitest/browser-webdriverio": "4.0.14", - "@vitest/ui": "4.0.14", + "@vitest/browser-playwright": "4.0.16", + "@vitest/browser-preview": "4.0.16", + "@vitest/browser-webdriverio": "4.0.16", + "@vitest/ui": "4.0.16", "happy-dom": "*", "jsdom": "*" }, @@ -15095,13 +15095,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/vitest/node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, "node_modules/vscode-jsonrpc": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", diff --git a/package.json b/package.json index 0e4e0cad5c..5509ca1466 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@stylistic/eslint-plugin": "5.6.1", "@stylistic/stylelint-plugin": "4.0.0", "@vitejs/plugin-vue": "6.0.3", - "@vitest/coverage-v8": "4.0.14", + "@vitest/coverage-v8": "4.0.16", "@vitest/eslint-plugin": "1.3.16", "@vue/test-utils": "2.4.6", "eslint": "9.39.2", @@ -99,7 +99,7 @@ "typescript": "5.9.3", "typescript-eslint": "8.50.0", "vite-string-plugin": "1.4.9", - "vitest": "4.0.14" + "vitest": "4.0.16" }, "browserslist": [ "defaults" From ea71a9aa642105986b9ce3e274e1920b39f74e75 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 21 Dec 2025 02:54:23 +0100 Subject: [PATCH 018/854] Update renovate to v42.64.1 (forgejo) (#10514) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- .forgejo/workflows/renovate.yml | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml index cc4801d811..0dcde71310 100644 --- a/.forgejo/workflows/renovate.yml +++ b/.forgejo/workflows/renovate.yml @@ -28,7 +28,7 @@ jobs: runs-on: docker container: - image: data.forgejo.org/renovate/renovate:42.39.2 + image: data.forgejo.org/renovate/renovate:42.64.1 steps: - name: Load renovate repo cache diff --git a/Makefile b/Makefile index ae66a3e471..6baec198c1 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasour GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.40.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.6.0 # renovate: datasource=go -RENOVATE_NPM_PACKAGE ?= renovate@42.39.2 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate +RENOVATE_NPM_PACKAGE ?= renovate@42.64.1 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/ DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... From 1619038085dccaead1fd67e7d1ab811f0d4658dd Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 21 Dec 2025 02:58:37 +0100 Subject: [PATCH 019/854] Lock file maintenance (forgejo) (#10519) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10519 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 764 +++++++++++++++++++++++------ web_src/fomantic/package-lock.json | 30 +- 2 files changed, 639 insertions(+), 155 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3652561b3c..834a012482 100644 --- a/package-lock.json +++ b/package-lock.json @@ -502,9 +502,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.20.tgz", - "integrity": "sha512-8BHsjXfSciZxjmHQOuVdW2b8WLUPts9a+mfL13/PzEviufUEW2xnvQuOlKs9dRBHgRqJ53SF/DUoK9+MZk72oQ==", + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.22.tgz", + "integrity": "sha512-qBcx6zYlhleiFfdtzkRgwNC7VVoAwfK76Vmsw5t+PbvtdknO9StgRk7ROvq9so1iqbdW4uLIDAsXRsTfUrIoOw==", "dev": true, "funding": [ { @@ -2387,9 +2387,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", - "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz", + "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==", "cpu": [ "arm" ], @@ -2401,9 +2401,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", - "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz", + "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==", "cpu": [ "arm64" ], @@ -2415,9 +2415,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", - "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz", + "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==", "cpu": [ "arm64" ], @@ -2429,9 +2429,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", - "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz", + "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==", "cpu": [ "x64" ], @@ -2443,9 +2443,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", - "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz", + "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==", "cpu": [ "arm64" ], @@ -2457,9 +2457,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", - "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz", + "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==", "cpu": [ "x64" ], @@ -2471,9 +2471,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", - "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz", + "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==", "cpu": [ "arm" ], @@ -2485,9 +2485,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", - "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz", + "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==", "cpu": [ "arm" ], @@ -2499,9 +2499,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", - "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz", + "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==", "cpu": [ "arm64" ], @@ -2513,9 +2513,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", - "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz", + "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==", "cpu": [ "arm64" ], @@ -2527,9 +2527,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", - "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz", + "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==", "cpu": [ "loong64" ], @@ -2541,9 +2541,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", - "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz", + "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==", "cpu": [ "ppc64" ], @@ -2555,9 +2555,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", - "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz", + "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==", "cpu": [ "riscv64" ], @@ -2569,9 +2569,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", - "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz", + "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==", "cpu": [ "riscv64" ], @@ -2583,9 +2583,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", - "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz", + "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==", "cpu": [ "s390x" ], @@ -2597,9 +2597,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", - "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz", + "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==", "cpu": [ "x64" ], @@ -2611,9 +2611,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", - "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz", + "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==", "cpu": [ "x64" ], @@ -2625,9 +2625,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", - "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz", + "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==", "cpu": [ "arm64" ], @@ -2639,9 +2639,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", - "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz", + "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==", "cpu": [ "arm64" ], @@ -2653,9 +2653,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", - "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz", + "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==", "cpu": [ "ia32" ], @@ -2667,9 +2667,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", - "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz", + "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==", "cpu": [ "x64" ], @@ -2681,9 +2681,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", - "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz", + "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==", "cpu": [ "x64" ], @@ -2732,9 +2732,9 @@ } }, "node_modules/@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, @@ -3690,9 +3690,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz", - "integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==", + "version": "20.19.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -5115,9 +5115,9 @@ } }, "node_modules/ast-v8-to-istanbul": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.8.tgz", - "integrity": "sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.9.tgz", + "integrity": "sha512-dSC6tJeOJxbZrPzPbv5mMd6CMiQ1ugaVXXPRad2fXUSsy1kstFn9XQWemV9VW7Y7kpxgQ/4WMoZfwdH8XSU48w==", "dev": true, "license": "MIT", "dependencies": { @@ -5240,9 +5240,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.4.tgz", - "integrity": "sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==", + "version": "2.9.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", + "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -5401,17 +5401,17 @@ } }, "node_modules/cacheable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.0.tgz", - "integrity": "sha512-HHiAvOBmlcR2f3SQ7kdlYD8+AUJG+wlFZ/Ze8tl1Vzvz0MdOh8IYA/EFU4ve8t1/sZ0j4MGi7ST5MoTwHessQA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.1.tgz", + "integrity": "sha512-yr+FSHWn1ZUou5LkULX/S+jhfgfnLbuKQjE40tyEd4fxGZVMbBL5ifno0J0OauykS8UiCSgHi+DV/YD+rjFxFg==", "dev": true, "license": "MIT", "dependencies": { "@cacheable/memory": "^2.0.6", "@cacheable/utils": "^2.3.2", - "hookified": "^1.13.0", - "keyv": "^5.5.4", - "qified": "^0.5.2" + "hookified": "^1.14.0", + "keyv": "^5.5.5", + "qified": "^0.5.3" } }, "node_modules/cacheable/node_modules/keyv": { @@ -5493,9 +5493,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001759", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz", - "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==", + "version": "1.0.30001761", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", + "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", "funding": [ { "type": "opencollective", @@ -6904,9 +6904,9 @@ } }, "node_modules/dompurify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz", - "integrity": "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -7025,9 +7025,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.266", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz", - "integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==", + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -7047,9 +7047,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -7102,9 +7102,9 @@ } }, "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", "dev": true, "license": "MIT", "dependencies": { @@ -7983,9 +7983,9 @@ } }, "node_modules/expect-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -8754,9 +8754,9 @@ } }, "node_modules/hookified": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.13.0.tgz", - "integrity": "sha512-6sPYUY8olshgM/1LDNW4QZQN0IqgKhtl/1C8koNZBJrKLBk3AZl6chQtNwpNztvfiApHMEwMHek5rv993PRbWw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.14.0.tgz", + "integrity": "sha512-pi1ynXIMFx/uIIwpWJ/5CEtOHLGtnUB0WhGeeYT+fKcQ+WCQbm3/rrkAXnpfph++PgepNqPdTC2WTj8A6k6zoQ==", "dev": true, "license": "MIT" }, @@ -14712,9 +14712,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", - "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "funding": [ { "type": "opencollective", @@ -14815,14 +14815,14 @@ "license": "MIT" }, "node_modules/vite": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz", - "integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", + "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "esbuild": "^0.25.0", + "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -14897,6 +14897,448 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/vite/node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -14904,6 +15346,48 @@ "dev": true, "license": "MIT" }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, "node_modules/vite/node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -14952,9 +15436,9 @@ } }, "node_modules/vite/node_modules/rollup": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", - "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", + "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==", "dev": true, "license": "MIT", "dependencies": { @@ -14968,28 +15452,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.3", - "@rollup/rollup-android-arm64": "4.53.3", - "@rollup/rollup-darwin-arm64": "4.53.3", - "@rollup/rollup-darwin-x64": "4.53.3", - "@rollup/rollup-freebsd-arm64": "4.53.3", - "@rollup/rollup-freebsd-x64": "4.53.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", - "@rollup/rollup-linux-arm-musleabihf": "4.53.3", - "@rollup/rollup-linux-arm64-gnu": "4.53.3", - "@rollup/rollup-linux-arm64-musl": "4.53.3", - "@rollup/rollup-linux-loong64-gnu": "4.53.3", - "@rollup/rollup-linux-ppc64-gnu": "4.53.3", - "@rollup/rollup-linux-riscv64-gnu": "4.53.3", - "@rollup/rollup-linux-riscv64-musl": "4.53.3", - "@rollup/rollup-linux-s390x-gnu": "4.53.3", - "@rollup/rollup-linux-x64-gnu": "4.53.3", - "@rollup/rollup-linux-x64-musl": "4.53.3", - "@rollup/rollup-openharmony-arm64": "4.53.3", - "@rollup/rollup-win32-arm64-msvc": "4.53.3", - "@rollup/rollup-win32-ia32-msvc": "4.53.3", - "@rollup/rollup-win32-x64-gnu": "4.53.3", - "@rollup/rollup-win32-x64-msvc": "4.53.3", + "@rollup/rollup-android-arm-eabi": "4.54.0", + "@rollup/rollup-android-arm64": "4.54.0", + "@rollup/rollup-darwin-arm64": "4.54.0", + "@rollup/rollup-darwin-x64": "4.54.0", + "@rollup/rollup-freebsd-arm64": "4.54.0", + "@rollup/rollup-freebsd-x64": "4.54.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", + "@rollup/rollup-linux-arm-musleabihf": "4.54.0", + "@rollup/rollup-linux-arm64-gnu": "4.54.0", + "@rollup/rollup-linux-arm64-musl": "4.54.0", + "@rollup/rollup-linux-loong64-gnu": "4.54.0", + "@rollup/rollup-linux-ppc64-gnu": "4.54.0", + "@rollup/rollup-linux-riscv64-gnu": "4.54.0", + "@rollup/rollup-linux-riscv64-musl": "4.54.0", + "@rollup/rollup-linux-s390x-gnu": "4.54.0", + "@rollup/rollup-linux-x64-gnu": "4.54.0", + "@rollup/rollup-linux-x64-musl": "4.54.0", + "@rollup/rollup-openharmony-arm64": "4.54.0", + "@rollup/rollup-win32-arm64-msvc": "4.54.0", + "@rollup/rollup-win32-ia32-msvc": "4.54.0", + "@rollup/rollup-win32-x64-gnu": "4.54.0", + "@rollup/rollup-win32-x64-msvc": "4.54.0", "fsevents": "~2.3.2" } }, diff --git a/web_src/fomantic/package-lock.json b/web_src/fomantic/package-lock.json index db82076265..529437b44f 100644 --- a/web_src/fomantic/package-lock.json +++ b/web_src/fomantic/package-lock.json @@ -478,9 +478,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", "license": "MIT", "dependencies": { "undici-types": "~7.16.0" @@ -1014,9 +1014,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.4.tgz", - "integrity": "sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==", + "version": "2.9.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", + "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -1244,9 +1244,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001759", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz", - "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==", + "version": "1.0.30001761", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", + "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", "funding": [ { "type": "opencollective", @@ -2000,9 +2000,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.266", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.266.tgz", - "integrity": "sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==", + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -8319,9 +8319,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", - "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "funding": [ { "type": "opencollective", From e04ae29d0d7893beac29ad4472f0b54a78a59a17 Mon Sep 17 00:00:00 2001 From: Beowulf Date: Sun, 21 Dec 2025 04:44:40 +0100 Subject: [PATCH 020/854] fix: add missing space before 'Commit' back (#10521) Regression from 8039240c26a40525da364a5a1308726d6cd973f8 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10521 Reviewed-by: Gusted Co-authored-by: Beowulf Co-committed-by: Beowulf --- templates/repo/actions/runs_list.tmpl | 2 +- tests/integration/actions_runs_list_test.go | 26 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/integration/actions_runs_list_test.go diff --git a/templates/repo/actions/runs_list.tmpl b/templates/repo/actions/runs_list.tmpl index 060fc1b66a..3858ae0849 100644 --- a/templates/repo/actions/runs_list.tmpl +++ b/templates/repo/actions/runs_list.tmpl @@ -16,7 +16,7 @@
{{if not $.CurWorkflow}}{{.WorkflowID}} {{end}}#{{.Index}} - - {{- if .ScheduleID -}} + {{if .ScheduleID -}} {{ctx.Locale.Tr "actions.runs.scheduled"}} {{- else -}} {{ctx.Locale.Tr "actions.runs.commit"}} diff --git a/tests/integration/actions_runs_list_test.go b/tests/integration/actions_runs_list_test.go new file mode 100644 index 0000000000..790e19d71a --- /dev/null +++ b/tests/integration/actions_runs_list_test.go @@ -0,0 +1,26 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package integration + +import ( + "net/http" + "testing" + + "forgejo.org/tests" + + "github.com/stretchr/testify/assert" +) + +func TestActionRunsList(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + req := NewRequest(t, "GET", "/user5/repo4/actions") + resp := MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + + runSubLine := htmlDoc.Find(".run-list .flex-item-body").Text() + assert.Contains(t, runSubLine, "Commit") + assert.NotContains(t, runSubLine, "-Commit") +} From d436de90b1f6398a9174997c95046c0307a1f5fb Mon Sep 17 00:00:00 2001 From: Beowulf Date: Sun, 21 Dec 2025 05:21:27 +0100 Subject: [PATCH 021/854] Add to html button in markdown `type="button"` (#10520) This is for preventing that a markdown button is recognized as button for submission in a html form. Buttons can't be stripped from the markdown due to: https://codeberg.org/forgejo/forgejo/pulls/7670#issuecomment-4086608 There is no issue with buttons if they always have `type="button"`, so this should be fine. This is a "follow-up" to !7670. Fixes #7656 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10520 Reviewed-by: Otto Reviewed-by: Gusted Co-authored-by: Beowulf Co-committed-by: Beowulf --- modules/markup/markdown/goldmark.go | 3 ++ modules/markup/markdown/markdown_test.go | 27 +++++++++++++++ modules/markup/markdown/transform_html.go | 28 +++++++++++++++ modules/markup/sanitizer.go | 6 +++- .../issue-comment-file-preview.test.e2e.ts | 34 +++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 modules/markup/markdown/transform_html.go create mode 100644 tests/e2e/issue-comment-file-preview.test.e2e.ts diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go index 8a3da3b08f..1ea3375ab5 100644 --- a/modules/markup/markdown/goldmark.go +++ b/modules/markup/markdown/goldmark.go @@ -1,4 +1,5 @@ // Copyright 2019 The Gitea Authors. All rights reserved. +// Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT package markdown @@ -87,6 +88,8 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa if scope, found := ctx.Metas["scope"]; found { v.Name = fmt.Appendf(v.Name, "-%s", scope) } + case *ast.RawHTML: + g.transformRawHTML(ctx, v, reader) } return ast.WalkContinue, nil }) diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 7c13494a67..82c2c7fe8c 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -1,4 +1,5 @@ // Copyright 2017 The Gitea Authors. All rights reserved. +// Copyright 2025 The Forgejo Authors. All rights reserved. // SPDX-License-Identifier: MIT package markdown_test @@ -125,6 +126,32 @@ func TestRender_Images(t *testing.T) { `

`+title+`

`) } +func TestRender_Buttons(t *testing.T) { + setting.AppURL = AppURL + + test := func(input, expected string) { + buffer, err := markdown.RenderString(&markup.RenderContext{ + Ctx: git.DefaultContext, + Links: markup.Links{ + Base: FullURL, + }, + }, input) + require.NoError(t, err) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) + } + + test( + "", + `

`) + + test( + ``, + `

`) + test( + ``, + `

`) +} + func testAnswers(baseURLContent, baseURLImages string) []string { return []string{ `

Wiki! Enjoy :)

diff --git a/modules/markup/markdown/transform_html.go b/modules/markup/markdown/transform_html.go new file mode 100644 index 0000000000..9bebb45554 --- /dev/null +++ b/modules/markup/markdown/transform_html.go @@ -0,0 +1,28 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package markdown + +import ( + "strings" + + "forgejo.org/modules/markup" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" +) + +func (g *ASTTransformer) addTypeToButton(v *ast.RawHTML, segment string) { + segment = strings.TrimPrefix(segment, " 0 { policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...) diff --git a/tests/e2e/issue-comment-file-preview.test.e2e.ts b/tests/e2e/issue-comment-file-preview.test.e2e.ts new file mode 100644 index 0000000000..03f7557dc0 --- /dev/null +++ b/tests/e2e/issue-comment-file-preview.test.e2e.ts @@ -0,0 +1,34 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +// @watch start +// modules/markup/** +// web_src/js/features/repo-unicode-escape.js +// @watch end + +import {expect} from '@playwright/test'; +import {dynamic_id, test} from './utils_e2e.ts'; + +test.use({user: 'user2'}); + +test('Escape button in file preview', async ({page}) => { + await page.goto('/user2/unicode-escaping/src/branch/main/a-file'); + + const url = await page.getByRole('link', {name: 'Permalink'}).getAttribute('href'); + + const response = await page.goto('/user2/repo1/issues/new'); + expect(response?.status()).toBe(200); + + // Create a new issue + await page.getByPlaceholder('Title').fill(dynamic_id()); + await page.getByPlaceholder('Leave a comment').fill(`http://localhost:3003${url}#L1`); + await page.getByRole('button', {name: 'Create issue'}).click(); + + await expect(page).toHaveURL(/\/user2\/repo1\/issues\/\d+$/); + + await expect(page.locator('table.file-preview.unicode-escaped')).toHaveCount(0); + await expect(async () => { + await page.locator('button.toggle-escape-button').click(); + await expect(page.locator('table.file-preview.unicode-escaped')).toHaveCount(1); + }).toPass(); +}); From b0d6786522101443771eba44ec4bf5872cb91248 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 21 Dec 2025 05:38:37 +0100 Subject: [PATCH 022/854] Update https://data.forgejo.org/actions/checkout action to v6 (forgejo) (#10518) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10518 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- .../workflows/build-release-integration.yml | 2 +- .forgejo/workflows/build-release.yml | 2 +- .../workflows/cascade-setup-end-to-end.yml | 2 +- .forgejo/workflows/coverage.yml | 2 +- .forgejo/workflows/publish-release.yml | 2 +- .../release-notes-assistant-milestones.yml | 2 +- .forgejo/workflows/release-notes-assistant.yml | 2 +- .forgejo/workflows/testing-integration.yml | 6 +++--- .forgejo/workflows/testing.yml | 18 +++++++++--------- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.forgejo/workflows/build-release-integration.yml b/.forgejo/workflows/build-release-integration.yml index aa5e69f64d..e3cbd3b331 100644 --- a/.forgejo/workflows/build-release-integration.yml +++ b/.forgejo/workflows/build-release-integration.yml @@ -26,7 +26,7 @@ jobs: if: vars.ROLE == 'forgejo-coding' runs-on: lxc-bookworm steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - id: forgejo uses: https://data.forgejo.org/actions/setup-forgejo@v3.0.6 diff --git a/.forgejo/workflows/build-release.yml b/.forgejo/workflows/build-release.yml index 042a981881..a3674b3a64 100644 --- a/.forgejo/workflows/build-release.yml +++ b/.forgejo/workflows/build-release.yml @@ -33,7 +33,7 @@ jobs: # root is used for testing, allow it if: vars.ROLE == 'forgejo-integration' || github.repository_owner == 'root' steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 with: fetch-depth: 0 diff --git a/.forgejo/workflows/cascade-setup-end-to-end.yml b/.forgejo/workflows/cascade-setup-end-to-end.yml index 747e41075f..36b464d9f3 100644 --- a/.forgejo/workflows/cascade-setup-end-to-end.yml +++ b/.forgejo/workflows/cascade-setup-end-to-end.yml @@ -37,7 +37,7 @@ jobs: container: image: data.forgejo.org/oci/node:24-bookworm steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 with: fetch-depth: '0' show-progress: 'false' diff --git a/.forgejo/workflows/coverage.yml b/.forgejo/workflows/coverage.yml index f0a27889a1..539527533f 100644 --- a/.forgejo/workflows/coverage.yml +++ b/.forgejo/workflows/coverage.yml @@ -61,7 +61,7 @@ jobs: image: registry.redict.io/redict:7.3.6-scratch options: --tmpfs /data:noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 with: repository: ${{ inputs.repository }} ref: ${{ inputs.ref }} diff --git a/.forgejo/workflows/publish-release.yml b/.forgejo/workflows/publish-release.yml index a583756656..853a730a1a 100644 --- a/.forgejo/workflows/publish-release.yml +++ b/.forgejo/workflows/publish-release.yml @@ -41,7 +41,7 @@ jobs: runs-on: lxc-bookworm if: vars.DOER != '' && vars.FORGEJO != '' && vars.TO_OWNER != '' && vars.FROM_OWNER != '' && secrets.TOKEN != '' steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - name: copy & sign uses: https://data.forgejo.org/forgejo/forgejo-build-publish/publish@v5.4.1 diff --git a/.forgejo/workflows/release-notes-assistant-milestones.yml b/.forgejo/workflows/release-notes-assistant-milestones.yml index 76799b06dc..f63b2cd5d0 100644 --- a/.forgejo/workflows/release-notes-assistant-milestones.yml +++ b/.forgejo/workflows/release-notes-assistant-milestones.yml @@ -15,7 +15,7 @@ jobs: container: image: 'data.forgejo.org/oci/ci:1' steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: https://data.forgejo.org/actions/cache@v4 with: diff --git a/.forgejo/workflows/release-notes-assistant.yml b/.forgejo/workflows/release-notes-assistant.yml index 4640eb37df..4b5ddf15d0 100644 --- a/.forgejo/workflows/release-notes-assistant.yml +++ b/.forgejo/workflows/release-notes-assistant.yml @@ -17,7 +17,7 @@ jobs: container: image: 'data.forgejo.org/oci/node:24-bookworm' steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - name: event run: | diff --git a/.forgejo/workflows/testing-integration.yml b/.forgejo/workflows/testing-integration.yml index 7c74239f1f..85351af08c 100644 --- a/.forgejo/workflows/testing-integration.yml +++ b/.forgejo/workflows/testing-integration.yml @@ -34,7 +34,7 @@ jobs: image: 'data.forgejo.org/oci/node:24-bookworm' options: --tmpfs /tmp:exec,noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install git 2.34.1 and git-lfs 3.0.2 uses: ./.forgejo/workflows-composite/install-minimum-git-version @@ -53,7 +53,7 @@ jobs: image: 'data.forgejo.org/oci/node:24-bookworm' options: --tmpfs /tmp:exec,noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install git 2.34.1 and git-lfs 3.0.2 uses: ./.forgejo/workflows-composite/install-minimum-git-version @@ -85,7 +85,7 @@ jobs: MARIADB_DATABASE: testgitea options: --tmpfs /var/lib/mysql:noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install dependencies & git >= 2.42 uses: ./.forgejo/workflows-composite/apt-install-from diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index 199e616daa..28714c8c1c 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -22,7 +22,7 @@ jobs: cat <<'EOF' ${{ toJSON(github) }} EOF - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - run: su forgejo -c 'make deps-backend deps-tools' - run: su forgejo -c 'make --always-make -j$(nproc) lint-backend tidy-check swagger-check lint-swagger fmt-check swagger-validate' # ensure the "go-licenses" make target runs @@ -34,7 +34,7 @@ jobs: image: 'data.forgejo.org/oci/node:24-bookworm' options: --tmpfs /tmp:exec,noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - run: make deps-frontend - run: make lint-frontend - run: make checks-frontend @@ -78,7 +78,7 @@ jobs: MINIO_ROOT_USER: 123456 MINIO_ROOT_PASSWORD: 12345678 steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install git >= 2.42 uses: ./.forgejo/workflows-composite/apt-install-from @@ -105,7 +105,7 @@ jobs: image: 'data.forgejo.org/oci/playwright:latest' options: --tmpfs /tmp:exec,noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 with: fetch-depth: 20 - uses: ./.forgejo/workflows-composite/setup-env @@ -175,7 +175,7 @@ jobs: env: ALLOW_EMPTY_PASSWORD: "yes" # redis & valkey will immediately shutdown with no defined password unless overridden steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install git >= 2.42 uses: ./.forgejo/workflows-composite/apt-install-from @@ -208,7 +208,7 @@ jobs: MYSQL_EXTRA_FLAGS: --innodb-adaptive-flushing=OFF --innodb-buffer-pool-size=4G --innodb-log-buffer-size=128M --innodb-flush-log-at-trx-commit=0 --innodb-flush-log-at-timeout=30 --innodb-flush-method=nosync --innodb-fsync-threshold=1000000000 --disable-log-bin options: --tmpfs /bitnami/mysql/data:noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install dependencies & git >= 2.42 uses: ./.forgejo/workflows-composite/apt-install-from @@ -246,7 +246,7 @@ jobs: POSTGRESQL_EXTRA_FLAGS: -c full_page_writes=off options: --tmpfs /bitnami/postgresql steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install dependencies & git >= 2.42 uses: ./.forgejo/workflows-composite/apt-install-from @@ -268,7 +268,7 @@ jobs: image: 'data.forgejo.org/oci/node:24-bookworm' options: --tmpfs /tmp:exec,noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - name: install dependencies & git >= 2.42 uses: ./.forgejo/workflows-composite/apt-install-from @@ -296,7 +296,7 @@ jobs: image: 'data.forgejo.org/oci/node:24-bookworm' options: --tmpfs /tmp:exec,noatime steps: - - uses: https://data.forgejo.org/actions/checkout@v5 + - uses: https://data.forgejo.org/actions/checkout@v6 - uses: ./.forgejo/workflows-composite/setup-env - run: su forgejo -c 'make deps-backend deps-tools' - run: su forgejo -c 'make security-check' From 252b7756bca9cb06fc1c7a371521ab02ca5ce3bd Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 21 Dec 2025 07:22:40 +0100 Subject: [PATCH 023/854] Update https://data.forgejo.org/actions/cache action to v5 (forgejo) (#10517) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10517 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- .forgejo/workflows-composite/build-backend/action.yaml | 2 +- .forgejo/workflows-composite/setup-cache-go/action.yaml | 2 +- .forgejo/workflows/build-release.yml | 2 +- .forgejo/workflows/release-notes-assistant-milestones.yml | 2 +- .forgejo/workflows/renovate.yml | 4 ++-- .forgejo/workflows/testing.yml | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.forgejo/workflows-composite/build-backend/action.yaml b/.forgejo/workflows-composite/build-backend/action.yaml index 68a99ffaf9..8c6fdb024b 100644 --- a/.forgejo/workflows-composite/build-backend/action.yaml +++ b/.forgejo/workflows-composite/build-backend/action.yaml @@ -3,7 +3,7 @@ runs: steps: - run: | su forgejo -c 'make deps-backend' - - uses: https://data.forgejo.org/actions/cache@v4 + - uses: https://data.forgejo.org/actions/cache@v5 id: cache-backend with: path: ${{github.workspace}}/gitea diff --git a/.forgejo/workflows-composite/setup-cache-go/action.yaml b/.forgejo/workflows-composite/setup-cache-go/action.yaml index fec166fc35..7543155699 100644 --- a/.forgejo/workflows-composite/setup-cache-go/action.yaml +++ b/.forgejo/workflows-composite/setup-cache-go/action.yaml @@ -50,7 +50,7 @@ runs: - name: "Restore Go dependencies from cache or mark for later caching" id: cache-deps - uses: https://data.forgejo.org/actions/cache@v4 + uses: https://data.forgejo.org/actions/cache@v5 with: key: setup-cache-go-deps-${{ runner.os }}-${{ inputs.username }}-${{ steps.go-version.outputs.go_version }}-${{ hashFiles('go.sum', 'go.mod') }} restore-keys: | diff --git a/.forgejo/workflows/build-release.yml b/.forgejo/workflows/build-release.yml index a3674b3a64..25d93eb6bc 100644 --- a/.forgejo/workflows/build-release.yml +++ b/.forgejo/workflows/build-release.yml @@ -93,7 +93,7 @@ jobs: - name: cache node_modules id: node - uses: https://data.forgejo.org/actions/cache@v4 + uses: https://data.forgejo.org/actions/cache@v5 with: path: | node_modules diff --git a/.forgejo/workflows/release-notes-assistant-milestones.yml b/.forgejo/workflows/release-notes-assistant-milestones.yml index f63b2cd5d0..06de029d88 100644 --- a/.forgejo/workflows/release-notes-assistant-milestones.yml +++ b/.forgejo/workflows/release-notes-assistant-milestones.yml @@ -17,7 +17,7 @@ jobs: steps: - uses: https://data.forgejo.org/actions/checkout@v6 - - uses: https://data.forgejo.org/actions/cache@v4 + - uses: https://data.forgejo.org/actions/cache@v5 with: key: rna-${{ env.RNA_VERSION }} path: ${{ env.RNA_WORKDIR }} diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml index 0dcde71310..5179c4acf4 100644 --- a/.forgejo/workflows/renovate.yml +++ b/.forgejo/workflows/renovate.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Load renovate repo cache - uses: https://data.forgejo.org/actions/cache/restore@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 + uses: https://data.forgejo.org/actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: | .tmp/cache/renovate/repository @@ -70,7 +70,7 @@ jobs: - name: Save renovate repo cache if: always() && env.RENOVATE_DRY_RUN != 'full' - uses: https://data.forgejo.org/actions/cache/save@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 + uses: https://data.forgejo.org/actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: | .tmp/cache/renovate/repository diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index 28714c8c1c..1d5c8dad2f 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -51,7 +51,7 @@ jobs: apt-get update -qq apt-get -q install -qq -y zstd - name: "Cache frontend build for playwright testing" - uses: https://data.forgejo.org/actions/cache/save@v4 + uses: https://data.forgejo.org/actions/cache/save@v5 with: path: ${{github.workspace}}/public/assets key: frontend-build-${{ github.sha }} @@ -110,7 +110,7 @@ jobs: fetch-depth: 20 - uses: ./.forgejo/workflows-composite/setup-env - name: "Restore frontend build" - uses: https://data.forgejo.org/actions/cache/restore@v4 + uses: https://data.forgejo.org/actions/cache/restore@v5 id: cache-frontend with: path: ${{github.workspace}}/public/assets From 81baf756369dad9166f43683925f910b76858fdb Mon Sep 17 00:00:00 2001 From: Beowulf Date: Sun, 21 Dec 2025 17:09:22 +0100 Subject: [PATCH 024/854] feat(ui): show cancel button until all jobs are finished (#9261) Change that the Cancel button is shown until all jobs are finished and do not hide it, when the first job failed. Additionally the wrapping of the header was changed. | Before | After | | :--: | :----: | | ![grafik](/attachments/26ee51ab-9a46-4c91-a866-e01cb0e97b28) | ![grafik](/attachments/eda3769b-e555-4964-9644-06f772046247) | Fixes #8922 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9261 Reviewed-by: Michael Kriese Reviewed-by: Andreas Ahlenstorf Reviewed-by: Mathieu Fenniak Co-authored-by: Beowulf Co-committed-by: Beowulf --- models/fixtures/action_run.yml | 40 +++++++++++ models/fixtures/action_run_job.yml | 60 ++++++++++++++++ models/fixtures/action_task.yml | 80 +++++++++++++++++++++ routers/web/repo/actions/view.go | 2 +- routers/web/repo/actions/view_test.go | 49 +++++++++++++ tests/integration/api_admin_actions_test.go | 6 +- web_src/js/components/RepoActionView.vue | 28 ++++++-- 7 files changed, 255 insertions(+), 10 deletions(-) diff --git a/models/fixtures/action_run.yml b/models/fixtures/action_run.yml index 8fa04b0066..41559ef788 100644 --- a/models/fixtures/action_run.yml +++ b/models/fixtures/action_run.yml @@ -533,3 +533,43 @@ updated: 1683636626 need_approval: false approved_by: 0 + +- + id: 895 + title: "job output" + repo_id: 4 + owner_id: 1 + workflow_id: "test.yaml" + index: 191 + trigger_user_id: 1 + ref: "refs/heads/master" + commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0" + event: "push" + is_fork_pull_request: false + status: 2 + started: 1683636528 + stopped: 1683636626 + created: 1683636108 + updated: 1683636626 + need_approval: false + approved_by: 0 + +- + id: 896 + title: "job output" + repo_id: 4 + owner_id: 1 + workflow_id: "test.yaml" + index: 192 + trigger_user_id: 1 + ref: "refs/heads/master" + commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0" + event: "push" + is_fork_pull_request: false + status: 2 + started: 1683636528 + stopped: 1683636626 + created: 1683636108 + updated: 1683636626 + need_approval: false + approved_by: 0 diff --git a/models/fixtures/action_run_job.yml b/models/fixtures/action_run_job.yml index bb812c1570..2d8ea9ff6f 100644 --- a/models/fixtures/action_run_job.yml +++ b/models/fixtures/action_run_job.yml @@ -69,6 +69,66 @@ status: 5 started: 1683636528 stopped: 1683636626 +- + id: 197 + run_id: 895 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + name: job1 (1) + attempt: 0 + job_id: job1 + task_id: 54 + status: 2 # failure + runs_on: '["postmarketOS"]' + started: 1683636528 + stopped: 1683636626 +- + id: 198 + run_id: 895 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + name: job1 (2) + attempt: 0 + job_id: job1 + task_id: 55 + status: 6 # running + runs_on: '["postmarketOS"]' + started: 1683636528 + stopped: 1683636626 +- + id: 199 + run_id: 896 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + name: job1 (1) + attempt: 0 + job_id: job1 + task_id: 56 + status: 2 # failure + runs_on: '["postmarketOS"]' + started: 1683636528 + stopped: 1683636626 +- + id: 200 + run_id: 896 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + name: job1 (2) + attempt: 0 + job_id: job1 + task_id: 57 + status: 1 # success + runs_on: '["postmarketOS"]' + started: 1683636528 + stopped: 1683636626 - id: 292 run_id: 891 diff --git a/models/fixtures/action_task.yml b/models/fixtures/action_task.yml index 956bc736f9..b931ca0aa8 100644 --- a/models/fixtures/action_task.yml +++ b/models/fixtures/action_task.yml @@ -157,3 +157,83 @@ log_length: 707 log_size: 90179 log_expired: false +- + id: 54 + job_id: 197 + attempt: 0 + runner_id: 1 + status: 2 # failure + started: 1683636528 + stopped: 1683636626 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784225 + token_salt: ffffffffff + token_last_eight: ffffffff + log_filename: artifact-test2/2f/47.log + log_in_storage: true + log_length: 707 + log_size: 90179 + log_expired: false +- + id: 55 + job_id: 198 + attempt: 0 + runner_id: 1 + status: 6 # running + started: 1683636528 + stopped: 1683636626 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784226 + token_salt: ffffffffff + token_last_eight: ffffffff + log_filename: artifact-test2/2f/47.log + log_in_storage: true + log_length: 707 + log_size: 90179 + log_expired: false +- + id: 56 + job_id: 199 + attempt: 0 + runner_id: 1 + status: 2 # failure + started: 1683636528 + stopped: 1683636626 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784227 + token_salt: ffffffffff + token_last_eight: ffffffff + log_filename: artifact-test2/2f/47.log + log_in_storage: true + log_length: 707 + log_size: 90179 + log_expired: false +- + id: 57 + job_id: 200 + attempt: 0 + runner_id: 1 + status: 1 # success + started: 1683636528 + stopped: 1683636626 + repo_id: 4 + owner_id: 1 + commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0 + is_fork_pull_request: false + token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784228 + token_salt: ffffffffff + token_last_eight: ffffffff + log_filename: artifact-test2/2f/47.log + log_in_storage: true + log_length: 707 + log_size: 90179 + log_expired: false diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 9b36f7b8cb..68466ee848 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -282,7 +282,6 @@ func getViewResponse(ctx *app_context.Context, req *ViewRequest, runIndex, jobIn resp.State.Run.Title = run.Title resp.State.Run.TitleHTML = templates.RenderCommitMessage(ctx, run.Title, metas) resp.State.Run.Link = run.Link() - resp.State.Run.CanCancel = !run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions) resp.State.Run.CanApprove = run.NeedApproval && ctx.Repo.CanWrite(unit.TypeActions) resp.State.Run.CanRerun = run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions) resp.State.Run.CanDeleteArtifact = run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions) @@ -310,6 +309,7 @@ func getViewResponse(ctx *app_context.Context, req *ViewRequest, runIndex, jobIn }) } resp.State.Run.Done = done + resp.State.Run.CanCancel = !done && ctx.Repo.CanWrite(unit.TypeActions) pusher := ViewUser{ DisplayName: run.TriggerUser.GetDisplayName(), diff --git a/routers/web/repo/actions/view_test.go b/routers/web/repo/actions/view_test.go index 61579b3208..48ebdf4cdc 100644 --- a/routers/web/repo/actions/view_test.go +++ b/routers/web/repo/actions/view_test.go @@ -382,6 +382,55 @@ func TestActionsViewViewPost(t *testing.T) { } } +func TestActionsViewCancelableUntilAllJobsFinished(t *testing.T) { + unittest.PrepareTestEnv(t) + + tests := []struct { + name string + runIndex int64 + assert func(*testing.T, *ViewResponse) + }{ + { + name: "failed and running", + runIndex: 191, + assert: func(t *testing.T, actual *ViewResponse) { + assert.Equal(t, "failure", actual.State.Run.Jobs[0].Status) + assert.Equal(t, "running", actual.State.Run.Jobs[1].Status) + assert.True(t, actual.State.Run.CanCancel) + }, + }, + { + name: "failed and success", + runIndex: 192, + assert: func(t *testing.T, actual *ViewResponse) { + assert.Equal(t, "failure", actual.State.Run.Jobs[0].Status) + assert.Equal(t, "success", actual.State.Run.Jobs[1].Status) + assert.False(t, actual.State.Run.CanCancel) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx, resp := contexttest.MockContext(t, "user2/repo1/actions/runs/0") + contexttest.LoadUser(t, ctx, 1) + contexttest.LoadRepo(t, ctx, 4) + ctx.SetParams(":run", fmt.Sprintf("%d", tt.runIndex)) + ctx.SetParams(":attempt", fmt.Sprintf("%d", 0)) + web.SetForm(ctx, &ViewRequest{}) + + ViewPost(ctx) + require.Equal(t, http.StatusOK, resp.Result().StatusCode, "failure in ViewPost(): %q", resp.Body.String()) + + var actual ViewResponse + err := json.Unmarshal(resp.Body.Bytes(), &actual) + require.NoError(t, err) + + tt.assert(t, &actual) + }) + } +} + func TestActionsViewRedirectToLatestAttempt(t *testing.T) { unittest.PrepareTestEnv(t) diff --git a/tests/integration/api_admin_actions_test.go b/tests/integration/api_admin_actions_test.go index 702e68b1b7..52c68098a4 100644 --- a/tests/integration/api_admin_actions_test.go +++ b/tests/integration/api_admin_actions_test.go @@ -62,6 +62,7 @@ func TestActionsAPISearchActionJobs_GlobalRunnerAllPendingJobs(t *testing.T) { defer tests.PrepareTestEnv(t)() job196 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 196}) + job198 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 198}) job393 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 393}) job394 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 394}) job395 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 395}) @@ -81,11 +82,12 @@ func TestActionsAPISearchActionJobs_GlobalRunnerAllPendingJobs(t *testing.T) { var jobs []*api.ActionRunJob DecodeJSON(t, res, &jobs) - assert.Len(t, jobs, 6) + assert.Len(t, jobs, 7) assert.Equal(t, job397.ID, jobs[0].ID) assert.Equal(t, job396.ID, jobs[1].ID) assert.Equal(t, job395.ID, jobs[2].ID) assert.Equal(t, job394.ID, jobs[3].ID) assert.Equal(t, job393.ID, jobs[4].ID) - assert.Equal(t, job196.ID, jobs[5].ID) + assert.Equal(t, job198.ID, jobs[5].ID) + assert.Equal(t, job196.ID, jobs[6].ID) } diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue index e80b6475c9..0bdce36995 100644 --- a/web_src/js/components/RepoActionView.vue +++ b/web_src/js/components/RepoActionView.vue @@ -472,12 +472,14 @@ export default { - - +
+ + +
{{ run.commit.localeCommit }} @@ -629,9 +631,10 @@ export default { .action-info-summary { display: flex; + flex-wrap: wrap; align-items: center; - justify-content: space-between; gap: 8px; + margin-bottom: 8px; } .action-info-summary-title { @@ -640,6 +643,17 @@ export default { gap: 0.5em; } +.action-info-summary-actions { + display: flex; + align-items: center; + gap: var(--button-spacing); + margin-left: auto; +} + +.action-info-summary-actions > button { + margin: 0; +} + .action-info-summary-title-text { font-size: 20px; margin: 0; From ddd4cf0d28d9b770eff3da2083f88382c244bd98 Mon Sep 17 00:00:00 2001 From: Andreas Ahlenstorf Date: Sun, 21 Dec 2025 17:21:02 +0100 Subject: [PATCH 025/854] chore: revise runner REST API endpoints (#10450) In https://codeberg.org/forgejo/forgejo/pulls/9409, REST API endpoints were added to manage runners. The REST API endpoints were modelled after GitHub's REST API. That comes at the cost of introducing methods and fields that Forgejo does not and is unlikely to support in the future, like label IDs or label types. But Forgejo would have to maintain them for a very long time. The introduced endpoints have been revised and aligned with existing Forgejo REST API endpoints: * POST for `/registration-token` has been removed because it was only an alias of GET. * `/runners` returns a list of `ActionRunner` instead of a wrapper object. `total_count` was replaced with the header `x-total-count` that is used throughout Forgejo. * `status` in `ActionRunner` was converted to an enum that is documented. * `busy` in `ActionRunner` was combined with `status`. A single enum is easier to extend and consume. * `labels` in `ActionRunner` was converted to a list of strings to match existing Forgejo REST API endpoints. * `ephemeral` has been removed from `ActionRunner` because ephemeral runners have not been merged, yet. * `ActionRunner` received a number of new fields: `uuid`, `version`, `description`, `owner_id`, and `repo_id`. In addition to those structural changes, the test coverage was enhanced and the API documentation polished. ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10450 Reviewed-by: Mathieu Fenniak Co-authored-by: Andreas Ahlenstorf Co-committed-by: Andreas Ahlenstorf --- modules/structs/repo_actions.go | 61 +++-- routers/api/v1/admin/runners.go | 41 +-- routers/api/v1/api.go | 4 +- routers/api/v1/org/action.go | 46 +--- routers/api/v1/repo/action.go | 49 +--- routers/api/v1/shared/runners.go | 23 +- routers/api/v1/swagger/action.go | 12 +- routers/api/v1/user/runners.go | 43 +--- services/actions/interface.go | 2 - services/convert/convert.go | 46 ++-- services/convert/convert_test.go | 76 ++++++ templates/swagger/v1_json.tmpl | 243 ++++++------------ tests/integration/actions_job_test.go | 30 --- tests/integration/actions_runner_test.go | 56 ---- tests/integration/api_admin_actions_test.go | 164 ++++++++++++ tests/integration/api_org_actions_test.go | 110 ++++++++ tests/integration/api_repo_actions_test.go | 108 ++++++++ tests/integration/api_user_actions_test.go | 110 ++++++++ .../action_runner.yml | 36 +++ .../action_runner_token.yml | 12 + .../action_runner.yml | 36 +++ .../action_runner_token.yml | 12 + .../action_runner.yml | 36 +++ .../action_runner_token.yml | 12 + .../action_runner.yml | 36 +++ .../action_runner_token.yml | 12 + 26 files changed, 971 insertions(+), 445 deletions(-) create mode 100644 tests/integration/fixtures/TestAPIGlobalActionsRunnerOperations/action_runner.yml create mode 100644 tests/integration/fixtures/TestAPIGlobalActionsRunnerRegistrationTokenOperations/action_runner_token.yml create mode 100644 tests/integration/fixtures/TestAPIOrgActionsRunnerOperations/action_runner.yml create mode 100644 tests/integration/fixtures/TestAPIOrgActionsRunnerRegistrationTokenOperations/action_runner_token.yml create mode 100644 tests/integration/fixtures/TestAPIRepoActionsRunnerOperations/action_runner.yml create mode 100644 tests/integration/fixtures/TestAPIRepoActionsRunnerRegistrationTokenOperations/action_runner_token.yml create mode 100644 tests/integration/fixtures/TestAPIUserActionsRunnerOperations/action_runner.yml create mode 100644 tests/integration/fixtures/TestAPIUserActionsRunnerRegistrationTokenOperations/action_runner_token.yml diff --git a/modules/structs/repo_actions.go b/modules/structs/repo_actions.go index eada2db09f..69e616eed9 100644 --- a/modules/structs/repo_actions.go +++ b/modules/structs/repo_actions.go @@ -33,26 +33,51 @@ type ActionTaskResponse struct { TotalCount int64 `json:"total_count"` } -// ActionRunnerLabel represents a Runner Label -type ActionRunnerLabel struct { - ID int64 `json:"id"` - Name string `json:"name"` - Type string `json:"type"` +type RunnerStatus int + +const ( + // RunnerStatusOffline signals that the runner is not connected to Forgejo. + RunnerStatusOffline RunnerStatus = iota + + // RunnerStatusIdle means that the runner is connected to Forgejo and waiting for jobs to run. + RunnerStatusIdle + + // RunnerStatusActive signifies that the runner is connected to Forgejo and running a job. + RunnerStatusActive +) + +var statusName = map[RunnerStatus]string{ + RunnerStatusOffline: "offline", + RunnerStatusIdle: "idle", + RunnerStatusActive: "active", } -// ActionRunner represents a Runner +func (status RunnerStatus) String() string { + return statusName[status] +} + +// ActionRunner represents a runner +// swagger:model type ActionRunner struct { - ID int64 `json:"id"` - Name string `json:"name"` + // ID uniquely identifies this runner. + ID int64 `json:"id"` + // UUID uniquely identifies this runner. + UUID string `json:"uuid"` + // OwnerID is the identifier of the user or organization this runner belongs to. O if the runner is owned by a + // repository. + OwnerID int64 `json:"owner_id"` + // RepoID is the identifier of the repository this runner belongs to. 0 if the runner belongs to a user or + // organization. + RepoID int64 `json:"repo_id"` + // Name of the runner; not unique. + Name string `json:"name"` + // Status indicates whether this runner is offline, or active, for example. + // enum: ["offline", "idle", "active"] Status string `json:"status"` - Busy bool `json:"busy"` - // currently unused as forgejo does not support ephemeral runners, but they are defined in gh api spec - Ephemeral bool `json:"ephemeral"` - Labels []*ActionRunnerLabel `json:"labels"` -} - -// ActionRunnersResponse returns Runners -type ActionRunnersResponse struct { - Entries []*ActionRunner `json:"runners"` - TotalCount int64 `json:"total_count"` + // Version is the self-reported version string of Forgejo Runner. + Version string `json:"version"` + // Labels is a list of labels attached to this runner. + Labels []string `json:"labels"` + // Description provides optional details about this runner. + Description string `json:"description"` } diff --git a/routers/api/v1/admin/runners.go b/routers/api/v1/admin/runners.go index 7c53a717a9..1a7abe2b12 100644 --- a/routers/api/v1/admin/runners.go +++ b/routers/api/v1/admin/runners.go @@ -8,13 +8,11 @@ import ( "forgejo.org/services/context" ) -// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization - // GetRegistrationToken returns the token to register global runners func GetRegistrationToken(ctx *context.APIContext) { // swagger:operation GET /admin/runners/registration-token admin adminGetRunnerRegistrationToken // --- - // summary: Get a global actions runner registration token + // summary: Get a runner registration token for registering global runners // produces: // - application/json // parameters: @@ -29,7 +27,7 @@ func GetRegistrationToken(ctx *context.APIContext) { func SearchActionRunJobs(ctx *context.APIContext) { // swagger:operation GET /admin/runners/jobs admin adminSearchRunJobs // --- - // summary: Search action jobs according filter conditions + // summary: Search action jobs according to filter conditions // produces: // - application/json // parameters: @@ -45,31 +43,16 @@ func SearchActionRunJobs(ctx *context.APIContext) { shared.GetActionRunJobs(ctx, 0, 0) } -// CreateRegistrationToken returns the token to register global runners -func CreateRegistrationToken(ctx *context.APIContext) { - // swagger:operation POST /admin/actions/runners/registration-token admin adminCreateRunnerRegistrationToken - // --- - // summary: Get a global actions runner registration token - // produces: - // - application/json - // parameters: - // responses: - // "200": - // "$ref": "#/responses/RegistrationToken" - - shared.GetRegistrationToken(ctx, 0, 0) -} - -// ListRunners get all runners +// ListRunners returns all runners, no matter whether they are global runners or scoped to an organization, user, or repository func ListRunners(ctx *context.APIContext) { // swagger:operation GET /admin/actions/runners admin getAdminRunners // --- - // summary: Get all runners + // summary: Get all runners, no matter whether they are global runners or scoped to an organization, user, or repository // produces: // - application/json // responses: // "200": - // "$ref": "#/definitions/ActionRunnersResponse" + // "$ref": "#/responses/ActionRunnerList" // "400": // "$ref": "#/responses/error" // "404": @@ -77,22 +60,22 @@ func ListRunners(ctx *context.APIContext) { shared.ListRunners(ctx, 0, 0) } -// GetRunner get a global runner +// GetRunner returns a particular runner, no matter whether it is a global runner or scoped to an organization, user, or repository func GetRunner(ctx *context.APIContext) { // swagger:operation GET /admin/actions/runners/{runner_id} admin getAdminRunner // --- - // summary: Get a global runner + // summary: Get a particular runner, no matter whether it is a global runner or scoped to an organization, user, or repository // produces: // - application/json // parameters: // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/ActionRunner" // "400": // "$ref": "#/responses/error" // "404": @@ -100,17 +83,17 @@ func GetRunner(ctx *context.APIContext) { shared.GetRunner(ctx, 0, 0, ctx.ParamsInt64("runner_id")) } -// DeleteRunner delete a global runner +// DeleteRunner removes a particular runner, no matter whether it is a global runner or scoped to an organization, user, or repository func DeleteRunner(ctx *context.APIContext) { // swagger:operation DELETE /admin/actions/runners/{runner_id} admin deleteAdminRunner // --- - // summary: Delete a global runner + // summary: Delete a particular runner, no matter whether it is a global runner or scoped to an organization, user, or repository // produces: // - application/json // parameters: // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 1206d653c1..f3589094b2 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -858,7 +858,6 @@ func Routes() *web.Route { m.Group("/runners", func() { m.Get("", reqToken(), reqChecker, act.ListRunners) m.Get("/registration-token", reqToken(), reqChecker, act.GetRegistrationToken) - m.Post("/registration-token", reqToken(), reqChecker, act.CreateRegistrationToken) m.Get("/{runner_id}", reqToken(), reqChecker, act.GetRunner) m.Delete("/{runner_id}", reqToken(), reqChecker, act.DeleteRunner) m.Get("/jobs", reqToken(), reqChecker, act.SearchActionRunJobs) @@ -1022,7 +1021,6 @@ func Routes() *web.Route { m.Group("/runners", func() { m.Get("", reqToken(), user.ListRunners) m.Get("/registration-token", reqToken(), user.GetRegistrationToken) - m.Post("/registration-token", reqToken(), user.CreateRegistrationToken) m.Get("/{runner_id}", reqToken(), user.GetRunner) m.Delete("/{runner_id}", reqToken(), user.DeleteRunner) m.Get("/jobs", reqToken(), user.SearchActionRunJobs) @@ -1704,7 +1702,7 @@ func Routes() *web.Route { }) m.Group("/actions/runners", func() { m.Get("", admin.ListRunners) - m.Post("/registration-token", admin.CreateRegistrationToken) + m.Get("/registration-token", admin.GetRegistrationToken) m.Get("/{runner_id}", admin.GetRunner) m.Delete("/{runner_id}", admin.DeleteRunner) }) diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index b3fcbca6b1..92921a3328 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -168,12 +168,11 @@ func (Action) DeleteSecret(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } -// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization -// GetRegistrationToken returns the token to register org runners +// GetRegistrationToken returns the organization's runner registration token func (Action) GetRegistrationToken(ctx *context.APIContext) { // swagger:operation GET /orgs/{org}/actions/runners/registration-token organization orgGetRunnerRegistrationToken // --- - // summary: Get an organization's actions runner registration token + // summary: Get the organization's runner registration token // produces: // - application/json // parameters: @@ -214,27 +213,6 @@ func (Action) SearchActionRunJobs(ctx *context.APIContext) { shared.GetActionRunJobs(ctx, ctx.Org.Organization.ID, 0) } -// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization -// CreateRegistrationToken returns the token to register org runners -func (Action) CreateRegistrationToken(ctx *context.APIContext) { - // swagger:operation POST /orgs/{org}/actions/runners/registration-token organization orgCreateRunnerRegistrationToken - // --- - // summary: Get an organization's actions runner registration token - // produces: - // - application/json - // parameters: - // - name: org - // in: path - // description: name of the organization - // type: string - // required: true - // responses: - // "200": - // "$ref": "#/responses/RegistrationToken" - - shared.GetRegistrationToken(ctx, ctx.Org.Organization.ID, 0) -} - // ListVariables list org-level variables func (Action) ListVariables(ctx *context.APIContext) { // swagger:operation GET /orgs/{org}/actions/variables organization getOrgVariablesList @@ -287,11 +265,11 @@ func (Action) ListVariables(ctx *context.APIContext) { ctx.JSON(http.StatusOK, variables) } -// ListRunners get org-level runners +// ListRunners returns the organization's runners func (Action) ListRunners(ctx *context.APIContext) { // swagger:operation GET /orgs/{org}/actions/runners organization getOrgRunners // --- - // summary: Get org-level runners + // summary: Get the organization's runners // produces: // - application/json // parameters: @@ -302,7 +280,7 @@ func (Action) ListRunners(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunnersResponse" + // "$ref": "#/responses/ActionRunnerList" // "400": // "$ref": "#/responses/error" // "404": @@ -310,11 +288,11 @@ func (Action) ListRunners(ctx *context.APIContext) { shared.ListRunners(ctx, ctx.Org.Organization.ID, 0) } -// GetRunner get an org-level runner +// GetRunner gets a particular runner that belongs to the organization func (Action) GetRunner(ctx *context.APIContext) { // swagger:operation GET /orgs/{org}/actions/runners/{runner_id} organization getOrgRunner // --- - // summary: Get an org-level runner + // summary: Get a particular runner that belongs to the organization // produces: // - application/json // parameters: @@ -325,12 +303,12 @@ func (Action) GetRunner(ctx *context.APIContext) { // required: true // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/ActionRunner" // "400": // "$ref": "#/responses/error" // "404": @@ -338,11 +316,11 @@ func (Action) GetRunner(ctx *context.APIContext) { shared.GetRunner(ctx, ctx.Org.Organization.ID, 0, ctx.ParamsInt64("runner_id")) } -// DeleteRunner delete an org-level runner +// DeleteRunner removes a particular runner that belongs to the organization func (Action) DeleteRunner(ctx *context.APIContext) { // swagger:operation DELETE /orgs/{org}/actions/runners/{runner_id} organization deleteOrgRunner // --- - // summary: Delete an org-level runner + // summary: Delete a particular runner that belongs to the organization // produces: // - application/json // parameters: @@ -353,7 +331,7 @@ func (Action) DeleteRunner(ctx *context.APIContext) { // required: true // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 9085ee8e70..f413dc4925 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -480,11 +480,11 @@ func (Action) ListVariables(ctx *context.APIContext) { ctx.JSON(http.StatusOK, variables) } -// GetRegistrationToken returns the token to register repo runners +// GetRegistrationToken returns the runner registration token to register runners for the repository func (Action) GetRegistrationToken(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/actions/runners/registration-token repository repoGetRunnerRegistrationToken // --- - // summary: Get a repository's actions runner registration token + // summary: Get a repository's runner registration token // produces: // - application/json // parameters: @@ -505,36 +505,11 @@ func (Action) GetRegistrationToken(ctx *context.APIContext) { shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID) } -// CreateRegistrationToken returns the token to register repo runners -func (Action) CreateRegistrationToken(ctx *context.APIContext) { - // swagger:operation POST /repos/{owner}/{repo}/actions/runners/registration-token repository repoCreateRunnerRegistrationToken - // --- - // summary: Get a repository's actions runner registration token - // produces: - // - application/json - // parameters: - // - name: owner - // in: path - // description: owner of the repo - // type: string - // required: true - // - name: repo - // in: path - // description: name of the repo - // type: string - // required: true - // responses: - // "200": - // "$ref": "#/responses/RegistrationToken" - - shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID) -} - -// ListRunners get repo-level runners +// ListRunners returns runners that belong to the repository func (Action) ListRunners(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/actions/runners repository getRepoRunners // --- - // summary: Get repo-level runners + // summary: Get runners belonging to the repository // produces: // - application/json // parameters: @@ -550,7 +525,7 @@ func (Action) ListRunners(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunnersResponse" + // "$ref": "#/responses/ActionRunnerList" // "400": // "$ref": "#/responses/error" // "404": @@ -558,11 +533,11 @@ func (Action) ListRunners(ctx *context.APIContext) { shared.ListRunners(ctx, 0, ctx.Repo.Repository.ID) } -// GetRunner get a repo-level runner +// GetRunner returns a particular runner that belongs to the repository func (Action) GetRunner(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/actions/runners/{runner_id} repository getRepoRunner // --- - // summary: Get a repo-level runner + // summary: Get a particular runner that belongs to the repository // produces: // - application/json // parameters: @@ -578,12 +553,12 @@ func (Action) GetRunner(ctx *context.APIContext) { // required: true // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/ActionRunner" // "400": // "$ref": "#/responses/error" // "404": @@ -591,11 +566,11 @@ func (Action) GetRunner(ctx *context.APIContext) { shared.GetRunner(ctx, 0, ctx.Repo.Repository.ID, ctx.ParamsInt64("runner_id")) } -// DeleteRunner delete a repo-level runner +// DeleteRunner removes a particular runner that belongs to a repository func (Action) DeleteRunner(ctx *context.APIContext) { // swagger:operation DELETE /repos/{owner}/{repo}/actions/runners/{runner_id} repository deleteRepoRunner // --- - // summary: Delete a repo-level runner + // summary: Delete a particular runner that belongs to a repository // produces: // - application/json // parameters: @@ -611,7 +586,7 @@ func (Action) DeleteRunner(ctx *context.APIContext) { // required: true // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: diff --git a/routers/api/v1/shared/runners.go b/routers/api/v1/shared/runners.go index feb47dacaa..4c4f1de00e 100644 --- a/routers/api/v1/shared/runners.go +++ b/routers/api/v1/shared/runners.go @@ -97,15 +97,17 @@ func ListRunners(ctx *context.APIContext, ownerID, repoID int64) { return } - res := new(structs.ActionRunnersResponse) - res.TotalCount = total - - res.Entries = make([]*structs.ActionRunner, len(runners)) + runnerList := make([]structs.ActionRunner, len(runners)) for i, runner := range runners { - res.Entries[i] = convert.ToActionRunner(ctx, runner) + actionRunner, err := convert.ToActionRunner(runner) + if err != nil { + ctx.Error(http.StatusInternalServerError, "ToActionRunner", err) + return + } + runnerList[i] = actionRunner } - - ctx.JSON(http.StatusOK, &res) + ctx.SetTotalCountHeader(total) + ctx.JSON(http.StatusOK, &runnerList) } // GetRunner get the runner for api route validated ownerID and repoID @@ -132,7 +134,12 @@ func GetRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) { ctx.Error(http.StatusNotFound, "RunnerEdit", "No permission to get this runner") return } - ctx.JSON(http.StatusOK, convert.ToActionRunner(ctx, runner)) + + actionRunner, err := convert.ToActionRunner(runner) + if err != nil { + ctx.Error(http.StatusInternalServerError, "ToActionRunner", err) + } + ctx.JSON(http.StatusOK, actionRunner) } // DeleteRunner deletes the runner for api route validated ownerID and repoID diff --git a/routers/api/v1/swagger/action.go b/routers/api/v1/swagger/action.go index cf853c986f..17181be250 100644 --- a/routers/api/v1/swagger/action.go +++ b/routers/api/v1/swagger/action.go @@ -57,16 +57,16 @@ type swaggerRegistrationToken struct { Body shared.RegistrationToken `json:"body"` } -// ActionRunner represents a Runner +// ActionRunner represents a runner // swagger:response ActionRunner type swaggerActionRunner struct { // in: body Body api.ActionRunner `json:"body"` } -// ActionRunnersResponse returns Runners -// swagger:response ActionRunnersResponse -type swaggerActionRunnerResponse struct { - // in: body - Body api.ActionRunnersResponse `json:"body"` +// ActionRunnerList is a list of Forgejo Action runners +// swagger:response ActionRunnerList +type swaggerActionRunnerListResponse struct { + // in:body + Body []api.ActionRunner `json:"body"` } diff --git a/routers/api/v1/user/runners.go b/routers/api/v1/user/runners.go index 2cfdd8a03a..dfeb49dcb6 100644 --- a/routers/api/v1/user/runners.go +++ b/routers/api/v1/user/runners.go @@ -8,13 +8,11 @@ import ( "forgejo.org/services/context" ) -// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization - -// GetRegistrationToken returns the token to register user runners +// GetRegistrationToken returns a token to register user-level runners func GetRegistrationToken(ctx *context.APIContext) { // swagger:operation GET /user/actions/runners/registration-token user userGetRunnerRegistrationToken // --- - // summary: Get an user's actions runner registration token + // summary: Get the user's runner registration token // produces: // - application/json // parameters: @@ -29,7 +27,7 @@ func GetRegistrationToken(ctx *context.APIContext) { shared.GetRegistrationToken(ctx, ctx.Doer.ID, 0) } -// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters +// SearchActionRunJobs returns a list of actions jobs filtered by the provided parameters func SearchActionRunJobs(ctx *context.APIContext) { // swagger:operation GET /user/actions/runners/jobs user userSearchRunJobs // --- @@ -51,33 +49,16 @@ func SearchActionRunJobs(ctx *context.APIContext) { shared.GetActionRunJobs(ctx, ctx.Doer.ID, 0) } -// CreateRegistrationToken returns the token to register user runners -func CreateRegistrationToken(ctx *context.APIContext) { - // swagger:operation POST /user/actions/runners/registration-token user userCreateRunnerRegistrationToken - // --- - // summary: Get an user's actions runner registration token - // produces: - // - application/json - // parameters: - // responses: - // "200": - // "$ref": "#/responses/RegistrationToken" - // "401": - // "$ref": "#/responses/unauthorized" - - shared.GetRegistrationToken(ctx, ctx.Doer.ID, 0) -} - -// ListRunners get user-level runners +// ListRunners returns the user's runners func ListRunners(ctx *context.APIContext) { // swagger:operation GET /user/actions/runners user getUserRunners // --- - // summary: Get user-level runners + // summary: Get the user's runners // produces: // - application/json // responses: // "200": - // "$ref": "#/responses/ActionRunnersResponse" + // "$ref": "#/responses/ActionRunnerList" // "400": // "$ref": "#/responses/error" // "401": @@ -87,17 +68,17 @@ func ListRunners(ctx *context.APIContext) { shared.ListRunners(ctx, ctx.Doer.ID, 0) } -// GetRunner get an user-level runner +// GetRunner gets a particular runner that belongs to the user func GetRunner(ctx *context.APIContext) { // swagger:operation GET /user/actions/runners/{runner_id} user getUserRunner // --- - // summary: Get an user-level runner + // summary: Get a particular runner that belongs to the user // produces: // - application/json // parameters: // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: @@ -112,17 +93,17 @@ func GetRunner(ctx *context.APIContext) { shared.GetRunner(ctx, ctx.Doer.ID, 0, ctx.ParamsInt64("runner_id")) } -// DeleteRunner delete an user-level runner +// DeleteRunner deletes a particular user-level runner func DeleteRunner(ctx *context.APIContext) { // swagger:operation DELETE /user/actions/runners/{runner_id} user deleteUserRunner // --- - // summary: Delete an user-level runner + // summary: Delete a particular user-level runner // produces: // - application/json // parameters: // - name: runner_id // in: path - // description: id of the runner + // description: ID of the runner // type: string // required: true // responses: diff --git a/services/actions/interface.go b/services/actions/interface.go index a5e0543594..466f8ef857 100644 --- a/services/actions/interface.go +++ b/services/actions/interface.go @@ -27,8 +27,6 @@ type API interface { GetRegistrationToken(*context.APIContext) // SearchActionRunJobs get pending Action run jobs SearchActionRunJobs(*context.APIContext) - // CreateRegistrationToken get registration token - CreateRegistrationToken(*context.APIContext) // ListRunners list runners ListRunners(*context.APIContext) // GetRunner get a runner diff --git a/services/convert/convert.go b/services/convert/convert.go index eaf6459cfd..00e1742178 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -522,26 +522,32 @@ func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit stri return file } -func ToActionRunner(ctx context.Context, runner *actions_model.ActionRunner) *api.ActionRunner { - status := runner.Status() - apiStatus := "offline" - if runner.IsOnline() { - apiStatus = "online" +func ToActionRunner(runner *actions_model.ActionRunner) (api.ActionRunner, error) { + runnerStatus := runner.Status() + + var status api.RunnerStatus + switch runnerStatus { + case runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE: + status = api.RunnerStatusOffline + case runnerv1.RunnerStatus_RUNNER_STATUS_IDLE: + status = api.RunnerStatusIdle + case runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE: + status = api.RunnerStatusActive + default: + return api.ActionRunner{}, fmt.Errorf("unexpected runner status: %s", runnerStatus) } - labels := make([]*api.ActionRunnerLabel, len(runner.AgentLabels)) - for i, label := range runner.AgentLabels { - labels[i] = &api.ActionRunnerLabel{ - ID: int64(i), - Name: label, - Type: "custom", - } - } - return &api.ActionRunner{ - ID: runner.ID, - Name: runner.Name, - Status: apiStatus, - Busy: status == runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE, - // Ephemeral: runner.Ephemeral, - Labels: labels, + + actionRunner := api.ActionRunner{ + ID: runner.ID, + Name: runner.Name, + UUID: runner.UUID, + OwnerID: runner.OwnerID, + RepoID: runner.RepoID, + Description: runner.Description, + Version: runner.Version, + Status: status.String(), + Labels: runner.AgentLabels, } + + return actionRunner, nil } diff --git a/services/convert/convert_test.go b/services/convert/convert_test.go index 04425bf9c3..6b870e0540 100644 --- a/services/convert/convert_test.go +++ b/services/convert/convert_test.go @@ -6,11 +6,13 @@ package convert import ( "testing" + actions_model "forgejo.org/models/actions" "forgejo.org/models/db" "forgejo.org/models/unittest" user_model "forgejo.org/models/user" "forgejo.org/modules/git" api "forgejo.org/modules/structs" + "forgejo.org/modules/timeutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -103,3 +105,77 @@ uf51WIBywxztet6vi+jYJK1jFoY4iA== }, commitVerification) }) } + +func TestToActionRunner(t *testing.T) { + testCases := []struct { + name string + runner actions_model.ActionRunner + expectedStatus api.RunnerStatus + }{ + { + name: "active-runner", + runner: actions_model.ActionRunner{ + ID: 846, + UUID: "0bf6d33b-9be8-4bb3-a210-351ae7f3d48e", + OwnerID: 204958, + RepoID: 0, + Name: "active-example", + Version: "12.1.2", + Description: "A very busy runner", + AgentLabels: []string{"debian", "gpu"}, + LastOnline: timeutil.TimeStampNow(), + LastActive: timeutil.TimeStampNow(), + }, + expectedStatus: api.RunnerStatusActive, + }, + { + name: "offline-runner", + runner: actions_model.ActionRunner{ + ID: 731, + UUID: "29b075f8-cd54-4dc2-b1e2-db303b32b0ce", + OwnerID: 0, + RepoID: 255289, + Name: "offline-example", + Version: "dev", + Description: "", + AgentLabels: []string{}, + LastOnline: 0, + LastActive: 0, + }, + expectedStatus: api.RunnerStatusOffline, + }, + { + name: "idle-runner", + runner: actions_model.ActionRunner{ + ID: 117, + UUID: "865ca613-f258-49bc-a986-1037ace1ca35", + OwnerID: 39115, + RepoID: 0, + Name: "idle-example", + Version: "11.3.1", + Description: "A runner twiddling its thumbs", + AgentLabels: []string{"docker"}, + LastOnline: timeutil.TimeStampNow(), + LastActive: timeutil.TimeStampNow().AddDuration(-actions_model.RunnerIdleTime), + }, + expectedStatus: api.RunnerStatusIdle, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + actionRunner, err := ToActionRunner(&testCase.runner) + + require.NoError(t, err) + assert.Equal(t, testCase.runner.ID, actionRunner.ID) + assert.Equal(t, testCase.runner.Name, actionRunner.Name) + assert.Equal(t, testCase.runner.UUID, actionRunner.UUID) + assert.Equal(t, testCase.runner.OwnerID, actionRunner.OwnerID) + assert.Equal(t, testCase.runner.RepoID, actionRunner.RepoID) + assert.Equal(t, testCase.runner.Version, actionRunner.Version) + assert.Equal(t, testCase.runner.Description, actionRunner.Description) + assert.Equal(t, testCase.expectedStatus.String(), actionRunner.Status) + assert.Equal(t, testCase.runner.AgentLabels, actionRunner.Labels) + }) + } +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 3a75d53ba1..1e81d03469 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -319,11 +319,11 @@ "tags": [ "admin" ], - "summary": "Get all runners", + "summary": "Get all runners, no matter whether they are global runners or scoped to an organization, user, or repository", "operationId": "getAdminRunners", "responses": { "200": { - "$ref": "#/definitions/ActionRunnersResponse" + "$ref": "#/responses/ActionRunnerList" }, "400": { "$ref": "#/responses/error" @@ -334,23 +334,6 @@ } } }, - "/admin/actions/runners/registration-token": { - "post": { - "produces": [ - "application/json" - ], - "tags": [ - "admin" - ], - "summary": "Get a global actions runner registration token", - "operationId": "adminCreateRunnerRegistrationToken", - "responses": { - "200": { - "$ref": "#/responses/RegistrationToken" - } - } - } - }, "/admin/actions/runners/{runner_id}": { "get": { "produces": [ @@ -359,12 +342,12 @@ "tags": [ "admin" ], - "summary": "Get a global runner", + "summary": "Get a particular runner, no matter whether it is a global runner or scoped to an organization, user, or repository", "operationId": "getAdminRunner", "parameters": [ { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -372,7 +355,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/ActionRunner" }, "400": { "$ref": "#/responses/error" @@ -389,12 +372,12 @@ "tags": [ "admin" ], - "summary": "Delete a global runner", + "summary": "Delete a particular runner, no matter whether it is a global runner or scoped to an organization, user, or repository", "operationId": "deleteAdminRunner", "parameters": [ { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -1245,7 +1228,7 @@ "tags": [ "admin" ], - "summary": "Search action jobs according filter conditions", + "summary": "Search action jobs according to filter conditions", "operationId": "adminSearchRunJobs", "parameters": [ { @@ -1273,7 +1256,7 @@ "tags": [ "admin" ], - "summary": "Get a global actions runner registration token", + "summary": "Get a runner registration token for registering global runners", "operationId": "adminGetRunnerRegistrationToken", "responses": { "200": { @@ -2635,7 +2618,7 @@ "tags": [ "organization" ], - "summary": "Get org-level runners", + "summary": "Get the organization's runners", "operationId": "getOrgRunners", "parameters": [ { @@ -2648,7 +2631,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunnersResponse" + "$ref": "#/responses/ActionRunnerList" }, "400": { "$ref": "#/responses/error" @@ -2702,7 +2685,7 @@ "tags": [ "organization" ], - "summary": "Get an organization's actions runner registration token", + "summary": "Get the organization's runner registration token", "operationId": "orgGetRunnerRegistrationToken", "parameters": [ { @@ -2718,30 +2701,6 @@ "$ref": "#/responses/RegistrationToken" } } - }, - "post": { - "produces": [ - "application/json" - ], - "tags": [ - "organization" - ], - "summary": "Get an organization's actions runner registration token", - "operationId": "orgCreateRunnerRegistrationToken", - "parameters": [ - { - "type": "string", - "description": "name of the organization", - "name": "org", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "$ref": "#/responses/RegistrationToken" - } - } } }, "/orgs/{org}/actions/runners/{runner_id}": { @@ -2752,7 +2711,7 @@ "tags": [ "organization" ], - "summary": "Get an org-level runner", + "summary": "Get a particular runner that belongs to the organization", "operationId": "getOrgRunner", "parameters": [ { @@ -2764,7 +2723,7 @@ }, { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -2772,7 +2731,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/ActionRunner" }, "400": { "$ref": "#/responses/error" @@ -2789,7 +2748,7 @@ "tags": [ "organization" ], - "summary": "Delete an org-level runner", + "summary": "Delete a particular runner that belongs to the organization", "operationId": "deleteOrgRunner", "parameters": [ { @@ -2801,7 +2760,7 @@ }, { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -5333,7 +5292,7 @@ "tags": [ "repository" ], - "summary": "Get repo-level runners", + "summary": "Get runners belonging to the repository", "operationId": "getRepoRunners", "parameters": [ { @@ -5353,7 +5312,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunnersResponse" + "$ref": "#/responses/ActionRunnerList" }, "400": { "$ref": "#/responses/error" @@ -5414,7 +5373,7 @@ "tags": [ "repository" ], - "summary": "Get a repository's actions runner registration token", + "summary": "Get a repository's runner registration token", "operationId": "repoGetRunnerRegistrationToken", "parameters": [ { @@ -5437,37 +5396,6 @@ "$ref": "#/responses/RegistrationToken" } } - }, - "post": { - "produces": [ - "application/json" - ], - "tags": [ - "repository" - ], - "summary": "Get a repository's actions runner registration token", - "operationId": "repoCreateRunnerRegistrationToken", - "parameters": [ - { - "type": "string", - "description": "owner of the repo", - "name": "owner", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "name of the repo", - "name": "repo", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "$ref": "#/responses/RegistrationToken" - } - } } }, "/repos/{owner}/{repo}/actions/runners/{runner_id}": { @@ -5478,7 +5406,7 @@ "tags": [ "repository" ], - "summary": "Get a repo-level runner", + "summary": "Get a particular runner that belongs to the repository", "operationId": "getRepoRunner", "parameters": [ { @@ -5497,7 +5425,7 @@ }, { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -5505,7 +5433,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/ActionRunner" }, "400": { "$ref": "#/responses/error" @@ -5522,7 +5450,7 @@ "tags": [ "repository" ], - "summary": "Delete a repo-level runner", + "summary": "Delete a particular runner that belongs to a repository", "operationId": "deleteRepoRunner", "parameters": [ { @@ -5541,7 +5469,7 @@ }, { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -18807,11 +18735,11 @@ "tags": [ "user" ], - "summary": "Get user-level runners", + "summary": "Get the user's runners", "operationId": "getUserRunners", "responses": { "200": { - "$ref": "#/responses/ActionRunnersResponse" + "$ref": "#/responses/ActionRunnerList" }, "400": { "$ref": "#/responses/error" @@ -18864,7 +18792,7 @@ "tags": [ "user" ], - "summary": "Get an user's actions runner registration token", + "summary": "Get the user's runner registration token", "operationId": "userGetRunnerRegistrationToken", "responses": { "200": { @@ -18877,24 +18805,6 @@ "$ref": "#/responses/forbidden" } } - }, - "post": { - "produces": [ - "application/json" - ], - "tags": [ - "user" - ], - "summary": "Get an user's actions runner registration token", - "operationId": "userCreateRunnerRegistrationToken", - "responses": { - "200": { - "$ref": "#/responses/RegistrationToken" - }, - "401": { - "$ref": "#/responses/unauthorized" - } - } } }, "/user/actions/runners/{runner_id}": { @@ -18905,12 +18815,12 @@ "tags": [ "user" ], - "summary": "Get an user-level runner", + "summary": "Get a particular runner that belongs to the user", "operationId": "getUserRunner", "parameters": [ { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -18938,12 +18848,12 @@ "tags": [ "user" ], - "summary": "Delete an user-level runner", + "summary": "Delete a particular user-level runner", "operationId": "deleteUserRunner", "parameters": [ { "type": "string", - "description": "id of the runner", + "description": "ID of the runner", "name": "runner_id", "in": "path", "required": true @@ -22181,76 +22091,64 @@ "x-go-package": "forgejo.org/modules/structs" }, "ActionRunner": { - "description": "ActionRunner represents a Runner", + "description": "ActionRunner represents a runner", "type": "object", "properties": { - "busy": { - "type": "boolean", - "x-go-name": "Busy" - }, - "ephemeral": { - "description": "currently unused as forgejo does not support ephemeral runners, but they are defined in gh api spec", - "type": "boolean", - "x-go-name": "Ephemeral" + "description": { + "description": "Description provides optional details about this runner.", + "type": "string", + "x-go-name": "Description" }, "id": { + "description": "ID uniquely identifies this runner.", "type": "integer", "format": "int64", "x-go-name": "ID" }, "labels": { + "description": "Labels is a list of labels attached to this runner.", "type": "array", "items": { - "$ref": "#/definitions/ActionRunnerLabel" + "type": "string" }, "x-go-name": "Labels" }, "name": { + "description": "Name of the runner; not unique.", "type": "string", "x-go-name": "Name" }, + "owner_id": { + "description": "OwnerID is the identifier of the user or organization this runner belongs to. O if the runner is owned by a\nrepository.", + "type": "integer", + "format": "int64", + "x-go-name": "OwnerID" + }, + "repo_id": { + "description": "RepoID is the identifier of the repository this runner belongs to. 0 if the runner belongs to a user or\norganization.", + "type": "integer", + "format": "int64", + "x-go-name": "RepoID" + }, "status": { + "description": "Status indicates whether this runner is offline, or active, for example.", "type": "string", + "enum": [ + "offline", + "idle", + "active" + ], "x-go-name": "Status" - } - }, - "x-go-package": "forgejo.org/modules/structs" - }, - "ActionRunnerLabel": { - "description": "ActionRunnerLabel represents a Runner Label", - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64", - "x-go-name": "ID" }, - "name": { + "uuid": { + "description": "UUID uniquely identifies this runner.", "type": "string", - "x-go-name": "Name" + "x-go-name": "UUID" }, - "type": { + "version": { + "description": "Version is the self-reported version string of Forgejo Runner.", "type": "string", - "x-go-name": "Type" - } - }, - "x-go-package": "forgejo.org/modules/structs" - }, - "ActionRunnersResponse": { - "description": "ActionRunnersResponse returns Runners", - "type": "object", - "properties": { - "runners": { - "type": "array", - "items": { - "$ref": "#/definitions/ActionRunner" - }, - "x-go-name": "Entries" - }, - "total_count": { - "type": "integer", - "format": "int64", - "x-go-name": "TotalCount" + "x-go-name": "Version" } }, "x-go-package": "forgejo.org/modules/structs" @@ -29939,15 +29837,18 @@ } }, "ActionRunner": { - "description": "ActionRunner represents a Runner", + "description": "ActionRunner represents a runner", "schema": { "$ref": "#/definitions/ActionRunner" } }, - "ActionRunnersResponse": { - "description": "ActionRunnersResponse returns Runners", + "ActionRunnerList": { + "description": "ActionRunnerList is a list of Forgejo Action runners", "schema": { - "$ref": "#/definitions/ActionRunnersResponse" + "type": "array", + "items": { + "$ref": "#/definitions/ActionRunner" + } } }, "ActionVariable": { diff --git a/tests/integration/actions_job_test.go b/tests/integration/actions_job_test.go index 262358ab9f..baa1420bdd 100644 --- a/tests/integration/actions_job_test.go +++ b/tests/integration/actions_job_test.go @@ -175,36 +175,6 @@ jobs: }) } -func TestRunnerLifecycleGithubEndpoints(t *testing.T) { - if !setting.Database.Type.IsSQLite3() { - // registering a mock runner when using a database other than SQLite leaves leftovers - t.Skip() - } - onApplicationRun(t, func(t *testing.T, u *url.URL) { - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - session := loginUser(t, user2.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) - - apiRepo := createActionsTestRepo(t, token, "actions-runner-registration-with-get", false) - runner := newMockRunner() - runner.registerAsRepoRunnerWithPost(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}) - runnersList := runner.listRunners(t, user2.Name, apiRepo.Name) - - assert.NotNil(t, runnersList) - assert.Len(t, runnersList.Entries, 1) - assert.Equal(t, "mock-runner", runnersList.Entries[0].Name) - - runnerDetails := runner.getRunner(t, user2.Name, apiRepo.Name, runnersList.Entries[0].ID) - assert.Equal(t, "mock-runner", runnerDetails.Name) - assert.Equal(t, runnersList.Entries[0].ID, runnerDetails.ID) - - runner.deleteRunner(t, user2.Name, apiRepo.Name, runnersList.Entries[0].ID) - - httpContext := NewAPITestContext(t, user2.Name, apiRepo.Name, auth_model.AccessTokenScopeWriteRepository) - doAPIDeleteRepository(httpContext)(t) - }) -} - func TestActionsJobNeedsMatrix(t *testing.T) { if !setting.Database.Type.IsSQLite3() { t.Skip() diff --git a/tests/integration/actions_runner_test.go b/tests/integration/actions_runner_test.go index 0eb2117325..6cedaf6def 100644 --- a/tests/integration/actions_runner_test.go +++ b/tests/integration/actions_runner_test.go @@ -12,7 +12,6 @@ import ( auth_model "forgejo.org/models/auth" "forgejo.org/modules/setting" - "forgejo.org/modules/structs" pingv1 "code.forgejo.org/forgejo/actions-proto/ping/v1" "code.forgejo.org/forgejo/actions-proto/ping/v1/pingv1connect" @@ -97,61 +96,6 @@ func (r *mockRunner) registerAsRepoRunner(t *testing.T, ownerName, repoName, run r.doRegister(t, runnerName, registrationToken.Token, labels) } -func (r *mockRunner) registerAsRepoRunnerWithPost(t *testing.T, ownerName, repoName, runnerName string, labels []string) { - if !setting.Database.Type.IsSQLite3() { - // registering a mock runner when using a database other than SQLite leaves leftovers - t.FailNow() - } - session := loginUser(t, ownerName) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runners/registration-token", ownerName, repoName)).AddTokenAuth(token) - resp := MakeRequest(t, req, http.StatusOK) - var registrationToken struct { - Token string `json:"token"` - } - DecodeJSON(t, resp, ®istrationToken) - r.doRegister(t, runnerName, registrationToken.Token, labels) -} - -func (r *mockRunner) listRunners(t *testing.T, ownerName, repoName string) structs.ActionRunnersResponse { - if !setting.Database.Type.IsSQLite3() { - // registering a mock runner when using a database other than SQLite leaves leftovers - t.FailNow() - } - session := loginUser(t, ownerName) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runners", ownerName, repoName)).AddTokenAuth(token) - resp := MakeRequest(t, req, http.StatusOK) - var runnersList structs.ActionRunnersResponse - DecodeJSON(t, resp, &runnersList) - return runnersList -} - -func (r *mockRunner) getRunner(t *testing.T, ownerName, repoName string, runnerID int64) structs.ActionRunner { - if !setting.Database.Type.IsSQLite3() { - // registering a mock runner when using a database other than SQLite leaves leftovers - t.FailNow() - } - session := loginUser(t, ownerName) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runners/%d", ownerName, repoName, runnerID)).AddTokenAuth(token) - resp := MakeRequest(t, req, http.StatusOK) - var runner structs.ActionRunner - DecodeJSON(t, resp, &runner) - return runner -} - -func (r *mockRunner) deleteRunner(t *testing.T, ownerName, repoName string, runnerID int64) { - if !setting.Database.Type.IsSQLite3() { - // registering a mock runner when using a database other than SQLite leaves leftovers - t.FailNow() - } - session := loginUser(t, ownerName) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runners/%d", ownerName, repoName, runnerID)).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNoContent) -} - func (r *mockRunner) maybeFetchTask(t *testing.T) *runnerv1.Task { resp, err := r.client.runnerServiceClient.FetchTask(t.Context(), connect.NewRequest(&runnerv1.FetchTaskRequest{ TasksVersion: r.lastTasksVersion, diff --git a/tests/integration/api_admin_actions_test.go b/tests/integration/api_admin_actions_test.go index 52c68098a4..1c03d66b7a 100644 --- a/tests/integration/api_admin_actions_test.go +++ b/tests/integration/api_admin_actions_test.go @@ -11,10 +11,13 @@ import ( actions_model "forgejo.org/models/actions" auth_model "forgejo.org/models/auth" "forgejo.org/models/unittest" + user_model "forgejo.org/models/user" api "forgejo.org/modules/structs" + "forgejo.org/routers/api/v1/shared" "forgejo.org/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestActionsAPISearchActionJobs_GlobalRunner(t *testing.T) { @@ -91,3 +94,164 @@ func TestActionsAPISearchActionJobs_GlobalRunnerAllPendingJobs(t *testing.T) { assert.Equal(t, job198.ID, jobs[5].ID) assert.Equal(t, job196.ID, jobs[6].ID) } + +func TestAPIGlobalActionsRunnerRegistrationTokenOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIGlobalActionsRunnerRegistrationTokenOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + session := loginUser(t, user1.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadAdmin) + + t.Run("GetRegistrationToken", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/admin/actions/runners/registration-token") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var registrationToken shared.RegistrationToken + DecodeJSON(t, response, ®istrationToken) + + expected := shared.RegistrationToken{Token: "BzcgyhjWhLeKGA4ihJIigeRDrcxrFESd0yizEpb7xZJ"} + + assert.Equal(t, expected, registrationToken) + }) +} + +func TestAPIGlobalActionsRunnerOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIGlobalActionsRunnerOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + session := loginUser(t, user1.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadAdmin) + writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) + + t.Run("GetRunners", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/admin/actions/runners") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + assert.NotEmpty(t, response.Header().Get("X-Total-Count")) + + var runners []*api.ActionRunner + DecodeJSON(t, response, &runners) + + runnerOne := &api.ActionRunner{ + ID: 130791, + UUID: "8b0f6b98-fef8-430e-bfdc-dcbeeb58f3c8", + Name: "runner-1-global", + Version: "dev", + OwnerID: 0, + RepoID: 0, + Description: "A superb runner", + Labels: []string{"debian", "gpu"}, + Status: "offline", + } + runnerTwo := &api.ActionRunner{ + ID: 130792, + UUID: "61c48447-6e7d-42da-9dbe-d659ade77a56", + Name: "runner-2-user", + Version: "11.3.1", + OwnerID: 1, + RepoID: 0, + Description: "A splendid runner", + Labels: []string{"docker"}, + Status: "offline", + } + runnerThree := &api.ActionRunner{ + ID: 130793, + UUID: "9b92be13-b002-4fc0-b182-5e7cdbef0b8d", + Name: "runner-3-global", + Version: "11.3.1", + OwnerID: 0, + RepoID: 0, + Description: "Another fine runner", + Labels: []string{"fedora"}, + Status: "offline", + } + + // There are more runners in the result that originate from the global fixtures. The test ignores them to limit + // the impact of unrelated changes. + assert.Contains(t, runners, runnerOne) + assert.Contains(t, runners, runnerTwo) + assert.Contains(t, runners, runnerThree) + }) + + t.Run("GetGlobalRunner", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/admin/actions/runners/130793") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var runner *api.ActionRunner + DecodeJSON(t, response, &runner) + + runnerOne := &api.ActionRunner{ + ID: 130793, + UUID: "9b92be13-b002-4fc0-b182-5e7cdbef0b8d", + Name: "runner-3-global", + Version: "11.3.1", + OwnerID: 0, + RepoID: 0, + Description: "Another fine runner", + Labels: []string{"fedora"}, + Status: "offline", + } + + assert.Equal(t, runnerOne, runner) + }) + + t.Run("GetRepositoryScopedRunner", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/admin/actions/runners/130794") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var runner *api.ActionRunner + DecodeJSON(t, response, &runner) + + runnerFour := &api.ActionRunner{ + ID: 130794, + UUID: "44d595e9-b47d-42ef-b1b9-5869f8b8d501", + Name: "runner-4-repository", + Version: "12.2.0", + OwnerID: 0, + RepoID: 62, + Description: "", + Labels: []string{"nixos"}, + Status: "offline", + } + + assert.Equal(t, runnerFour, runner) + }) + + t.Run("DeleteGlobalRunner", func(t *testing.T) { + url := "/api/v1/admin/actions/runners/130791" + + request := NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusOK) + + deleteRequest := NewRequest(t, "DELETE", url) + deleteRequest.AddTokenAuth(writeToken) + MakeRequest(t, deleteRequest, http.StatusNoContent) + + request = NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusNotFound) + }) + + t.Run("DeleteRepositoryScopedRunner", func(t *testing.T) { + url := "/api/v1/admin/actions/runners/130794" + + request := NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusOK) + + deleteRequest := NewRequest(t, "DELETE", url) + deleteRequest.AddTokenAuth(writeToken) + MakeRequest(t, deleteRequest, http.StatusNoContent) + + request = NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusNotFound) + }) +} diff --git a/tests/integration/api_org_actions_test.go b/tests/integration/api_org_actions_test.go index 9a5eabc81a..3d5fb3e50c 100644 --- a/tests/integration/api_org_actions_test.go +++ b/tests/integration/api_org_actions_test.go @@ -11,10 +11,13 @@ import ( actions_model "forgejo.org/models/actions" auth_model "forgejo.org/models/auth" "forgejo.org/models/unittest" + user_model "forgejo.org/models/user" api "forgejo.org/modules/structs" + "forgejo.org/routers/api/v1/shared" "forgejo.org/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestActionsAPISearchActionJobs_OrgRunner(t *testing.T) { @@ -76,3 +79,110 @@ func TestActionsAPISearchActionJobs_OrgRunnerAllPendingJobs(t *testing.T) { assert.Equal(t, job397.ID, jobs[0].ID) assert.Equal(t, job395.ID, jobs[1].ID) } + +func TestAPIOrgActionsRunnerRegistrationTokenOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIOrgActionsRunnerRegistrationTokenOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) + + t.Run("GetRegistrationToken", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/orgs/org3/actions/runners/registration-token") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var registrationToken shared.RegistrationToken + DecodeJSON(t, response, ®istrationToken) + + expected := shared.RegistrationToken{Token: "Sk9wHjBHelH4n1ckQy-mo3KVYRdoaPZ_aaH1ATfgI05"} + + assert.Equal(t, expected, registrationToken) + }) +} + +func TestAPIOrgActionsRunnerOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIOrgActionsRunnerOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) + writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + + t.Run("GetRunners", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/orgs/org3/actions/runners") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + assert.Equal(t, "2", response.Header().Get("X-Total-Count")) + + var runners []*api.ActionRunner + DecodeJSON(t, response, &runners) + + runnerOne := &api.ActionRunner{ + ID: 655691, + UUID: "a3297f3a-ba5c-4a0f-878e-6cc8b8ac79ec", + Name: "runner-1-organization", + Version: "dev", + OwnerID: 3, + RepoID: 0, + Description: "A superb runner", + Labels: []string{"debian", "gpu"}, + Status: "offline", + } + runnerThree := &api.ActionRunner{ + ID: 655693, + UUID: "0a7e5e05-2da4-44d5-a72a-615da120cef6", + Name: "runner-3-organization", + Version: "11.3.1", + OwnerID: 3, + RepoID: 0, + Description: "Another fine runner", + Labels: []string{"fedora"}, + Status: "offline", + } + + assert.ElementsMatch(t, []*api.ActionRunner{runnerOne, runnerThree}, runners) + }) + + t.Run("GetRunner", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/orgs/org3/actions/runners/655691") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var runner *api.ActionRunner + DecodeJSON(t, response, &runner) + + runnerOne := &api.ActionRunner{ + ID: 655691, + UUID: "a3297f3a-ba5c-4a0f-878e-6cc8b8ac79ec", + Name: "runner-1-organization", + Version: "dev", + OwnerID: 3, + RepoID: 0, + Description: "A superb runner", + Labels: []string{"debian", "gpu"}, + Status: "offline", + } + + assert.Equal(t, runnerOne, runner) + }) + + t.Run("DeleteRunner", func(t *testing.T) { + url := "/api/v1/orgs/org3/actions/runners/655691" + + request := NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusOK) + + deleteRequest := NewRequest(t, "DELETE", url) + deleteRequest.AddTokenAuth(writeToken) + MakeRequest(t, deleteRequest, http.StatusNoContent) + + request = NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusNotFound) + }) +} diff --git a/tests/integration/api_repo_actions_test.go b/tests/integration/api_repo_actions_test.go index ae2591c0a8..9c8be4156a 100644 --- a/tests/integration/api_repo_actions_test.go +++ b/tests/integration/api_repo_actions_test.go @@ -19,6 +19,7 @@ import ( user_model "forgejo.org/models/user" api "forgejo.org/modules/structs" "forgejo.org/modules/webhook" + "forgejo.org/routers/api/v1/shared" files_service "forgejo.org/services/repository/files" "forgejo.org/tests" @@ -351,3 +352,110 @@ func TestActionsAPIGetActionRun(t *testing.T) { }) } } + +func TestAPIRepoActionsRunnerRegistrationTokenOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIRepoActionsRunnerRegistrationTokenOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) + + t.Run("GetRegistrationToken", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/repos/user2/test_workflows/actions/runners/registration-token") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var registrationToken shared.RegistrationToken + DecodeJSON(t, response, ®istrationToken) + + expected := shared.RegistrationToken{Token: "BzcgyhjWhLeKGA4ihJIigeRDrcxrFESd0yizEpb7xZJ"} + + assert.Equal(t, expected, registrationToken) + }) +} + +func TestAPIRepoActionsRunnerOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIRepoActionsRunnerOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) + writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + t.Run("GetRunners", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/repos/user2/test_workflows/actions/runners") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + assert.Equal(t, "2", response.Header().Get("X-Total-Count")) + + var runners []*api.ActionRunner + DecodeJSON(t, response, &runners) + + runnerOne := &api.ActionRunner{ + ID: 899251, + UUID: "a3297f3a-ba5c-4a0f-878e-6cc8b8ac79ec", + Name: "runner-1-repository", + Version: "dev", + OwnerID: 0, + RepoID: 62, + Description: "A superb runner", + Labels: []string{"debian", "gpu"}, + Status: "offline", + } + runnerThree := &api.ActionRunner{ + ID: 899253, + UUID: "0a7e5e05-2da4-44d5-a72a-615da120cef6", + Name: "runner-3-repository", + Version: "11.3.1", + OwnerID: 0, + RepoID: 62, + Description: "Another fine runner", + Labels: []string{"fedora"}, + Status: "offline", + } + + assert.ElementsMatch(t, []*api.ActionRunner{runnerOne, runnerThree}, runners) + }) + + t.Run("GetRunner", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/repos/user2/test_workflows/actions/runners/899251") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var runner *api.ActionRunner + DecodeJSON(t, response, &runner) + + runnerOne := &api.ActionRunner{ + ID: 899251, + UUID: "a3297f3a-ba5c-4a0f-878e-6cc8b8ac79ec", + Name: "runner-1-repository", + Version: "dev", + OwnerID: 0, + RepoID: 62, + Description: "A superb runner", + Labels: []string{"debian", "gpu"}, + Status: "offline", + } + + assert.Equal(t, runnerOne, runner) + }) + + t.Run("DeleteRunner", func(t *testing.T) { + url := "/api/v1/repos/user2/test_workflows/actions/runners/899253" + + request := NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusOK) + + deleteRequest := NewRequest(t, "DELETE", url) + deleteRequest.AddTokenAuth(writeToken) + MakeRequest(t, deleteRequest, http.StatusNoContent) + + request = NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusNotFound) + }) +} diff --git a/tests/integration/api_user_actions_test.go b/tests/integration/api_user_actions_test.go index 40cf39b2d7..876fd14bbf 100644 --- a/tests/integration/api_user_actions_test.go +++ b/tests/integration/api_user_actions_test.go @@ -11,10 +11,13 @@ import ( actions_model "forgejo.org/models/actions" auth_model "forgejo.org/models/auth" "forgejo.org/models/unittest" + user_model "forgejo.org/models/user" api "forgejo.org/modules/structs" + "forgejo.org/routers/api/v1/shared" "forgejo.org/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestActionsAPISearchActionJobs_UserRunner(t *testing.T) { @@ -74,3 +77,110 @@ func TestActionsAPISearchActionJobs_UserRunnerAllPendingJobs(t *testing.T) { assert.Len(t, jobs, 1) assert.Equal(t, job.ID, jobs[0].ID) } + +func TestAPIUserActionsRunnerRegistrationTokenOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIUserActionsRunnerRegistrationTokenOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) + + t.Run("GetRegistrationToken", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/user/actions/runners/registration-token") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var registrationToken shared.RegistrationToken + DecodeJSON(t, response, ®istrationToken) + + expected := shared.RegistrationToken{Token: "Xb3WmQBum2S0-WwFY399A0DhnPkgRdXzpEOJaMmL5UT"} + + assert.Equal(t, expected, registrationToken) + }) +} + +func TestAPIUserActionsRunnerOperations(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestAPIUserActionsRunnerOperations")() + require.NoError(t, unittest.PrepareTestDatabase()) + + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) + readToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) + writeToken := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + + t.Run("GetRunners", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/user/actions/runners") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + assert.Equal(t, "2", response.Header().Get("X-Total-Count")) + + var runners []*api.ActionRunner + DecodeJSON(t, response, &runners) + + runnerOne := &api.ActionRunner{ + ID: 71301, + UUID: "99fc4a58-a25e-4dbe-b6ea-3d55dddcd216", + Name: "runner-1-user", + Version: "dev", + OwnerID: 2, + RepoID: 0, + Description: "A superb runner", + Labels: []string{"debian", "gpu"}, + Status: "offline", + } + runnerThree := &api.ActionRunner{ + ID: 71303, + UUID: "70bc0da3-35b2-4129-bbc9-4679dfdda4d0", + Name: "runner-3-user", + Version: "11.3.1", + OwnerID: 2, + RepoID: 0, + Description: "Another fine runner", + Labels: []string{"fedora"}, + Status: "offline", + } + + assert.ElementsMatch(t, []*api.ActionRunner{runnerOne, runnerThree}, runners) + }) + + t.Run("GetRunner", func(t *testing.T) { + request := NewRequest(t, "GET", "/api/v1/user/actions/runners/71303") + request.AddTokenAuth(readToken) + response := MakeRequest(t, request, http.StatusOK) + + var runner *api.ActionRunner + DecodeJSON(t, response, &runner) + + runnerThree := &api.ActionRunner{ + ID: 71303, + UUID: "70bc0da3-35b2-4129-bbc9-4679dfdda4d0", + Name: "runner-3-user", + Version: "11.3.1", + OwnerID: 2, + RepoID: 0, + Description: "Another fine runner", + Labels: []string{"fedora"}, + Status: "offline", + } + + assert.Equal(t, runnerThree, runner) + }) + + t.Run("DeleteRunner", func(t *testing.T) { + url := "/api/v1/user/actions/runners/71303" + + request := NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusOK) + + deleteRequest := NewRequest(t, "DELETE", url) + deleteRequest.AddTokenAuth(writeToken) + MakeRequest(t, deleteRequest, http.StatusNoContent) + + request = NewRequest(t, "GET", url) + request.AddTokenAuth(readToken) + MakeRequest(t, request, http.StatusNotFound) + }) +} diff --git a/tests/integration/fixtures/TestAPIGlobalActionsRunnerOperations/action_runner.yml b/tests/integration/fixtures/TestAPIGlobalActionsRunnerOperations/action_runner.yml new file mode 100644 index 0000000000..ef16984be0 --- /dev/null +++ b/tests/integration/fixtures/TestAPIGlobalActionsRunnerOperations/action_runner.yml @@ -0,0 +1,36 @@ +- id: 130791 + uuid: "8b0f6b98-fef8-430e-bfdc-dcbeeb58f3c8" + name: "runner-1-global" + version: "dev" + owner_id: 0 + repo_id: 0 + description: "A superb runner" + agent_labels: ["debian", "gpu"] + deleted: 0 +- id: 130792 + uuid: "61c48447-6e7d-42da-9dbe-d659ade77a56" + name: "runner-2-user" + version: "11.3.1" + owner_id: 1 + repo_id: 0 + description: "A splendid runner" + agent_labels: ["docker"] + deleted: 0 +- id: 130793 + uuid: "9b92be13-b002-4fc0-b182-5e7cdbef0b8d" + name: "runner-3-global" + version: "11.3.1" + owner_id: 0 + repo_id: 0 + description: "Another fine runner" + agent_labels: ["fedora"] + deleted: 0 +- id: 130794 + uuid: "44d595e9-b47d-42ef-b1b9-5869f8b8d501" + name: "runner-4-repository" + version: "12.2.0" + owner_id: 0 + repo_id: 62 + description: "" + agent_labels: ["nixos"] + deleted: 0 \ No newline at end of file diff --git a/tests/integration/fixtures/TestAPIGlobalActionsRunnerRegistrationTokenOperations/action_runner_token.yml b/tests/integration/fixtures/TestAPIGlobalActionsRunnerRegistrationTokenOperations/action_runner_token.yml new file mode 100644 index 0000000000..c0b5007417 --- /dev/null +++ b/tests/integration/fixtures/TestAPIGlobalActionsRunnerRegistrationTokenOperations/action_runner_token.yml @@ -0,0 +1,12 @@ +- id: 4691 + token: "BzcgyhjWhLeKGA4ihJIigeRDrcxrFESd0yizEpb7xZJ" + owner_id: 0 + repo_id: 0 + is_active: true + deleted: 0 +- id: 4692 + token: "Sk9wHjBHelH4n1ckQy-mo3KVYRdoaPZ_aaH1ATfgI05" + owner_id: 1 + repo_id: 0 + is_active: true + deleted: 0 diff --git a/tests/integration/fixtures/TestAPIOrgActionsRunnerOperations/action_runner.yml b/tests/integration/fixtures/TestAPIOrgActionsRunnerOperations/action_runner.yml new file mode 100644 index 0000000000..f39cac24be --- /dev/null +++ b/tests/integration/fixtures/TestAPIOrgActionsRunnerOperations/action_runner.yml @@ -0,0 +1,36 @@ +- id: 655691 + uuid: "a3297f3a-ba5c-4a0f-878e-6cc8b8ac79ec" + name: "runner-1-organization" + version: "dev" + owner_id: 3 + repo_id: 0 + description: "A superb runner" + agent_labels: ["debian", "gpu"] + deleted: 0 +- id: 655692 + uuid: "6d2d13ef-b19f-47a8-85ad-e82e51f606c5" + name: "runner-2-user" + version: "11.3.1" + owner_id: 1 + repo_id: 0 + description: "A splendid runner" + agent_labels: ["docker"] + deleted: 0 +- id: 655693 + uuid: "0a7e5e05-2da4-44d5-a72a-615da120cef6" + name: "runner-3-organization" + version: "11.3.1" + owner_id: 3 + repo_id: 0 + description: "Another fine runner" + agent_labels: ["fedora"] + deleted: 0 +- id: 655694 + uuid: "166c596c-5016-488d-bd55-b84e5a0460ea" + name: "runner-4-global" + version: "11.3.1" + owner_id: 0 + repo_id: 0 + description: "" + agent_labels: [] + deleted: 0 diff --git a/tests/integration/fixtures/TestAPIOrgActionsRunnerRegistrationTokenOperations/action_runner_token.yml b/tests/integration/fixtures/TestAPIOrgActionsRunnerRegistrationTokenOperations/action_runner_token.yml new file mode 100644 index 0000000000..2bd52feb31 --- /dev/null +++ b/tests/integration/fixtures/TestAPIOrgActionsRunnerRegistrationTokenOperations/action_runner_token.yml @@ -0,0 +1,12 @@ +- id: 3621 + token: "BzcgyhjWhLeKGA4ihJIigeRDrcxrFESd0yizEpb7xZJ" + owner_id: 1 + repo_id: 0 + is_active: true + deleted: 0 +- id: 3622 + token: "Sk9wHjBHelH4n1ckQy-mo3KVYRdoaPZ_aaH1ATfgI05" + owner_id: 3 + repo_id: 0 + is_active: true + deleted: 0 diff --git a/tests/integration/fixtures/TestAPIRepoActionsRunnerOperations/action_runner.yml b/tests/integration/fixtures/TestAPIRepoActionsRunnerOperations/action_runner.yml new file mode 100644 index 0000000000..1f1edb919e --- /dev/null +++ b/tests/integration/fixtures/TestAPIRepoActionsRunnerOperations/action_runner.yml @@ -0,0 +1,36 @@ +- id: 899251 + uuid: "a3297f3a-ba5c-4a0f-878e-6cc8b8ac79ec" + name: "runner-1-repository" + version: "dev" + owner_id: 0 + repo_id: 62 + description: "A superb runner" + agent_labels: ["debian", "gpu"] + deleted: 0 +- id: 899252 + uuid: "6d2d13ef-b19f-47a8-85ad-e82e51f606c5" + name: "runner-2-user" + version: "11.3.1" + owner_id: 1 + repo_id: 0 + description: "A splendid runner" + agent_labels: ["docker"] + deleted: 0 +- id: 899253 + uuid: "0a7e5e05-2da4-44d5-a72a-615da120cef6" + name: "runner-3-repository" + version: "11.3.1" + owner_id: 0 + repo_id: 62 + description: "Another fine runner" + agent_labels: ["fedora"] + deleted: 0 +- id: 899254 + uuid: "6456ac1f-70ec-4e8f-9ab7-bf117ee23d47" + name: "runner-4-global" + version: "11.3.1" + owner_id: 0 + repo_id: 0 + description: "" + agent_labels: [] + deleted: 0 diff --git a/tests/integration/fixtures/TestAPIRepoActionsRunnerRegistrationTokenOperations/action_runner_token.yml b/tests/integration/fixtures/TestAPIRepoActionsRunnerRegistrationTokenOperations/action_runner_token.yml new file mode 100644 index 0000000000..ec32b16bc6 --- /dev/null +++ b/tests/integration/fixtures/TestAPIRepoActionsRunnerRegistrationTokenOperations/action_runner_token.yml @@ -0,0 +1,12 @@ +- id: 3621 + token: "BzcgyhjWhLeKGA4ihJIigeRDrcxrFESd0yizEpb7xZJ" + owner_id: 0 + repo_id: 62 + is_active: true + deleted: 0 +- id: 3622 + token: "Sk9wHjBHelH4n1ckQy-mo3KVYRdoaPZ_aaH1ATfgI05" + owner_id: 0 + repo_id: 1 + is_active: true + deleted: 0 diff --git a/tests/integration/fixtures/TestAPIUserActionsRunnerOperations/action_runner.yml b/tests/integration/fixtures/TestAPIUserActionsRunnerOperations/action_runner.yml new file mode 100644 index 0000000000..be6ace174f --- /dev/null +++ b/tests/integration/fixtures/TestAPIUserActionsRunnerOperations/action_runner.yml @@ -0,0 +1,36 @@ +- id: 71301 + uuid: "99fc4a58-a25e-4dbe-b6ea-3d55dddcd216" + name: "runner-1-user" + version: "dev" + owner_id: 2 + repo_id: 0 + description: "A superb runner" + agent_labels: ["debian", "gpu"] + deleted: 0 +- id: 71302 + uuid: "9d32fe29-be59-4cd6-a97b-b6abb6937d47" + name: "runner-2-user" + version: "11.3.1" + owner_id: 1 + repo_id: 0 + description: "A splendid runner" + agent_labels: ["docker"] + deleted: 0 +- id: 71303 + uuid: "70bc0da3-35b2-4129-bbc9-4679dfdda4d0" + name: "runner-3-user" + version: "11.3.1" + owner_id: 2 + repo_id: 0 + description: "Another fine runner" + agent_labels: ["fedora"] + deleted: 0 +- id: 71304 + uuid: "3873c473-47b8-4559-9fa5-843277419780" + name: "runner-4-global" + version: "11.3.1" + owner_id: 0 + repo_id: 0 + description: "" + agent_labels: [] + deleted: 0 diff --git a/tests/integration/fixtures/TestAPIUserActionsRunnerRegistrationTokenOperations/action_runner_token.yml b/tests/integration/fixtures/TestAPIUserActionsRunnerRegistrationTokenOperations/action_runner_token.yml new file mode 100644 index 0000000000..dc0167cb77 --- /dev/null +++ b/tests/integration/fixtures/TestAPIUserActionsRunnerRegistrationTokenOperations/action_runner_token.yml @@ -0,0 +1,12 @@ +- id: 383951 + token: "xVkXTYaIFUdkTxgqnLaO4X4c-Mg2OKBBcaEo6S1hkZo" + owner_id: 1 + repo_id: 0 + is_active: true + deleted: 0 +- id: 383952 + token: "Xb3WmQBum2S0-WwFY399A0DhnPkgRdXzpEOJaMmL5UT" + owner_id: 2 + repo_id: 0 + is_active: true + deleted: 0 From a34275dd844205aa91b74beb302429306fe133d3 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 21 Dec 2025 19:21:27 +0100 Subject: [PATCH 026/854] Update module code.forgejo.org/forgejo/runner/v12 to v12.3.0 (forgejo) (#10535) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [code.forgejo.org/forgejo/runner/v12](https://code.forgejo.org/forgejo/runner) | `v12.2.0` -> `v12.3.0` | ![age](https://developer.mend.io/api/mc/badges/age/go/code.forgejo.org%2fforgejo%2frunner%2fv12/v12.3.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/code.forgejo.org%2fforgejo%2frunner%2fv12/v12.2.0/v12.3.0?slim=true) | --- ### Release Notes
forgejo/runner (code.forgejo.org/forgejo/runner/v12) ### [`v12.3.0`](https://code.forgejo.org/forgejo/runner/releases/tag/v12.3.0) [Compare Source](https://code.forgejo.org/forgejo/runner/compare/v12.2.0...v12.3.0) - [User guide](https://forgejo.org/docs/next/user/actions/overview/) - [Administrator guide](https://forgejo.org/docs/next/admin/actions/) - [Container images](https://code.forgejo.org/forgejo/-/packages/container/runner/versions) Release Notes *** - features - [PR](https://code.forgejo.org/forgejo/runner/pulls/1234): feat(jobparser): expose Job to reusable workflow fetchers - [PR](https://code.forgejo.org/forgejo/runner/pulls/1227): feat(jobparser): add tracking IDs for outer/inner jobs in reusable workflows - [PR](https://code.forgejo.org/forgejo/runner/pulls/1228): feat(jobparser): ignore `__metadata` in workflow schema validation - [PR](https://code.forgejo.org/forgejo/runner/pulls/1229): feat(jobparser): expose API for `EvaluateWorkflowCallSecrets` - [PR](https://code.forgejo.org/forgejo/runner/pulls/1210): feat(runner): skip service containers with empty image after interpolation - bug fixes - [PR](https://code.forgejo.org/forgejo/runner/pulls/1235): fix(jobparser): preserve workflow\_parent\_id on reparsing incomplete workflows - [PR](https://code.forgejo.org/forgejo/runner/pulls/1230): fix: accept env references in service definitions
--- ### Configuration 📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC), Automerge - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10535 Reviewed-by: Mathieu Fenniak Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7516b5a680..252b8eaeaf 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( code.forgejo.org/forgejo/go-rpmutils v1.0.0 code.forgejo.org/forgejo/levelqueue v1.0.0 code.forgejo.org/forgejo/reply v1.0.2 - code.forgejo.org/forgejo/runner/v12 v12.2.0 + code.forgejo.org/forgejo/runner/v12 v12.3.0 code.forgejo.org/go-chi/binding v1.0.1 code.forgejo.org/go-chi/cache v1.0.1 code.forgejo.org/go-chi/captcha v1.0.2 diff --git a/go.sum b/go.sum index 6792d6d404..df61d469f4 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ code.forgejo.org/forgejo/levelqueue v1.0.0 h1:9krYpU6BM+j/1Ntj6m+VCAIu0UNnne1/Uf code.forgejo.org/forgejo/levelqueue v1.0.0/go.mod h1:fmG6zhVuqim2rxSFOoasgXO8V2W/k9U31VVYqLIRLhQ= code.forgejo.org/forgejo/reply v1.0.2 h1:dMhQCHV6/O3L5CLWNTol+dNzDAuyCK88z4J/lCdgFuQ= code.forgejo.org/forgejo/reply v1.0.2/go.mod h1:RyZUfzQLc+fuLIGjTSQWDAJWPiL4WtKXB/FifT5fM7U= -code.forgejo.org/forgejo/runner/v12 v12.2.0 h1:CNRdZqXD32xZOdlQe154c+rIY6VcQ3avEyBqKcAy9SU= -code.forgejo.org/forgejo/runner/v12 v12.2.0/go.mod h1:m6i/RnHQObdagTZUUPR+Nb2Th3VBLOHzjZ6tVw7F0qs= +code.forgejo.org/forgejo/runner/v12 v12.3.0 h1:1I171DOnzibl/zuzARLdslp71mVbnFnjsdVCEWD+Mdg= +code.forgejo.org/forgejo/runner/v12 v12.3.0/go.mod h1:m6i/RnHQObdagTZUUPR+Nb2Th3VBLOHzjZ6tVw7F0qs= code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616 h1:kEZL84+02jY9RxXM4zHBWZ3Fml0B09cmP1LGkDsCfIA= code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= code.forgejo.org/go-chi/binding v1.0.1 h1:coKNI+X1NzRN7X85LlrpvBRqk0TXpJ+ja28vusQWEuY= From a0d54c8366a058b47fb86091ba83230cf8572170 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 22 Dec 2025 00:26:52 +0100 Subject: [PATCH 027/854] Update dependency vue to v3.5.26 (forgejo) (#10504) Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 125 +++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 70 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index 834a012482..83b7d8f06e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.5.25", + "vue": "3.5.26", "vue-chartjs": "5.3.3", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", @@ -4496,39 +4496,51 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz", - "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", + "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", - "@vue/shared": "3.5.25", - "entities": "^4.5.0", + "@vue/shared": "3.5.26", + "entities": "^7.0.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, + "node_modules/@vue/compiler-core/node_modules/entities": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", + "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/@vue/compiler-dom": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz", - "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", + "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.25", - "@vue/shared": "3.5.25" + "@vue/compiler-core": "3.5.26", + "@vue/shared": "3.5.26" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz", - "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz", + "integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==", "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", - "@vue/compiler-core": "3.5.25", - "@vue/compiler-dom": "3.5.25", - "@vue/compiler-ssr": "3.5.25", - "@vue/shared": "3.5.25", + "@vue/compiler-core": "3.5.26", + "@vue/compiler-dom": "3.5.26", + "@vue/compiler-ssr": "3.5.26", + "@vue/shared": "3.5.26", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", @@ -4545,63 +4557,63 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz", - "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz", + "integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.25", - "@vue/shared": "3.5.25" + "@vue/compiler-dom": "3.5.26", + "@vue/shared": "3.5.26" } }, "node_modules/@vue/reactivity": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.25.tgz", - "integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz", + "integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.25" + "@vue/shared": "3.5.26" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.25.tgz", - "integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.26.tgz", + "integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.25", - "@vue/shared": "3.5.25" + "@vue/reactivity": "3.5.26", + "@vue/shared": "3.5.26" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz", - "integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz", + "integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.25", - "@vue/runtime-core": "3.5.25", - "@vue/shared": "3.5.25", - "csstype": "^3.1.3" + "@vue/reactivity": "3.5.26", + "@vue/runtime-core": "3.5.26", + "@vue/shared": "3.5.26", + "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.25.tgz", - "integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.26.tgz", + "integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.25", - "@vue/shared": "3.5.25" + "@vue/compiler-ssr": "3.5.26", + "@vue/shared": "3.5.26" }, "peerDependencies": { - "vue": "3.5.25" + "vue": "3.5.26" } }, "node_modules/@vue/shared": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz", - "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", + "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", "license": "MIT" }, "node_modules/@vue/test-utils": { @@ -7063,6 +7075,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -15629,17 +15642,17 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.5.25", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.25.tgz", - "integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", + "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", "license": "MIT", "peer": true, "dependencies": { - "@vue/compiler-dom": "3.5.25", - "@vue/compiler-sfc": "3.5.25", - "@vue/runtime-dom": "3.5.25", - "@vue/server-renderer": "3.5.25", - "@vue/shared": "3.5.25" + "@vue/compiler-dom": "3.5.26", + "@vue/compiler-sfc": "3.5.26", + "@vue/runtime-dom": "3.5.26", + "@vue/server-renderer": "3.5.26", + "@vue/shared": "3.5.26" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index 5509ca1466..bb3af6cb11 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.5.25", + "vue": "3.5.26", "vue-chartjs": "5.3.3", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", From 5244253fb98beb0544a73c8d33e06d05c57058a0 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 22 Dec 2025 02:14:23 +0100 Subject: [PATCH 028/854] Update dependency webpack to v5.104.1 (forgejo) (#10538) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10538 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 83b7d8f06e..7b7e72226e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,7 +56,7 @@ "vue-chartjs": "5.3.3", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.104.0", + "webpack": "5.104.1", "webpack-cli": "6.0.1", "wrap-ansi": "9.0.2" }, @@ -15760,9 +15760,9 @@ "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.104.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.0.tgz", - "integrity": "sha512-5DeICTX8BVgNp6afSPYXAFjskIgWGlygQH58bcozPOXgo2r/6xx39Y1+cULZ3gTxUYQP88jmwLj2anu4Xaq84g==", + "version": "5.104.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", + "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "license": "MIT", "peer": true, "dependencies": { diff --git a/package.json b/package.json index bb3af6cb11..4a1e32cd45 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "vue-chartjs": "5.3.3", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.104.0", + "webpack": "5.104.1", "webpack-cli": "6.0.1", "wrap-ansi": "9.0.2" }, From 50b007526609a391186709b874c0b8fe76b08b3b Mon Sep 17 00:00:00 2001 From: James Anderson Date: Mon, 22 Dec 2025 02:32:40 +0100 Subject: [PATCH 029/854] fix: linking commit hashes with leading or trailing punctuation (#8643) Recognize commit hashes if they have leading or trailing punctuation, `ccc33dd2dfcd8e9d81c7e91f74acf92114a61ea0...` will not be recognized properly. The restriction of two punctuation characters on either side has been lifted. Resolves #8602 Co-Authored-By: Beowulf Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8643 Reviewed-by: Gusted Co-authored-by: James Anderson Co-committed-by: James Anderson --- modules/markup/html.go | 2 +- modules/markup/html_internal_test.go | 4 ++++ modules/markup/html_test.go | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 2fe0caa5b6..0ac0463493 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -49,7 +49,7 @@ var ( // hashCurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae // Although SHA1 hashes are 40 chars long, SHA256 are 64, the regex matches the hash from 7 to 64 chars in length // so that abbreviated hash links can be used as well. This matches git and GitHub usability. - hashCurrentPattern = regexp.MustCompile(`(?:^|\s)[^\w\d]{0,2}([0-9a-f]{7,64})[^\w\d]{0,2}(?:\s|$)`) + hashCurrentPattern = regexp.MustCompile(`(?:^|\s)[^\w\d]*([0-9a-f]{7,64})[^\w\d]*(?:\s|$)`) // shortLinkPattern matches short but difficult to parse [[name|link|arg=test]] syntax shortLinkPattern = regexp.MustCompile(`\[\[(.*?)\]\](\w*)`) diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 1f717a78ed..21572bdda3 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -475,6 +475,9 @@ func TestRegExp_hashCurrentPattern(t *testing.T) { ":abcd3ef", ".abcd3ef", " (abcd3ef). ", + "abcd3ef...", + "...abcd3ef", + "(!...abcd3ef", } falseTestCases := []string{ "test", @@ -484,6 +487,7 @@ func TestRegExp_hashCurrentPattern(t *testing.T) { "abcdefghijklmnopqrstuvwxyzabcdefghijklmO", "commit/abcdefd", "abcd3ef...defabcd", + "f..defabcd", } for _, testCase := range trueTestCases { diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index 512a7aa02a..6c6658748a 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -57,8 +57,10 @@ func TestRender_Commits(t *testing.T) { } sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d" + shaWithExtra := "65f1bf27bc3bf70f64657658635e66094edbcb4d..." repo := markup.TestRepoURL commit := util.URLJoin(repo, "commit", sha) + commitWithExtra := util.URLJoin(repo, "commit", shaWithExtra) tree := util.URLJoin(repo, "tree", sha, "src") file := util.URLJoin(repo, "commit", sha, "example.txt") @@ -69,9 +71,11 @@ func TestRender_Commits(t *testing.T) { commitCompareWithHash := commitCompare + "#L2" test(sha, `

65f1bf27bc

`) + test(shaWithExtra, `

65f1bf27bc...

`) test(sha[:7], `

65f1bf2

`) test(sha[:39], `

65f1bf27bc

`) test(commit, `

65f1bf27bc

`) + test(commitWithExtra, `

65f1bf27bc...

`) test(tree, `

65f1bf27bc/src

`) test(file, `

65f1bf27bc/example.txt

`) From 34af1330c22172cf0cda2003903da4526e1436b6 Mon Sep 17 00:00:00 2001 From: Mathieu Fenniak Date: Mon, 22 Dec 2025 04:14:11 +0100 Subject: [PATCH 030/854] refactor: split `ActionJobStepList` out of `RepoActionView` (#10537) Continuing refactor work to split functionality out of `RepoActionView` and into more testable, more manageable sub-components. #9768 will eventually result in some updates to this view for new functionality, and before more complexity is added I'd like to clean it up to a more maintainable state. Previous refactor step: #10366 ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [ ] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [x] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [x] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10537 Reviewed-by: Gusted Co-authored-by: Mathieu Fenniak Co-committed-by: Mathieu Fenniak --- web_src/js/components/ActionJobStep.test.js | 21 +++ web_src/js/components/ActionJobStep.vue | 66 +++++++ .../js/components/ActionJobStepList.test.js | 175 ++++++++++++++++++ web_src/js/components/ActionJobStepList.vue | 108 +++++++++++ web_src/js/components/RepoActionView.vue | 106 ++--------- 5 files changed, 385 insertions(+), 91 deletions(-) create mode 100644 web_src/js/components/ActionJobStepList.test.js create mode 100644 web_src/js/components/ActionJobStepList.vue diff --git a/web_src/js/components/ActionJobStep.test.js b/web_src/js/components/ActionJobStep.test.js index ae52fd7bcc..5ecb0005a5 100644 --- a/web_src/js/components/ActionJobStep.test.js +++ b/web_src/js/components/ActionJobStep.test.js @@ -1,3 +1,6 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + import {describe, expect, test, vi} from 'vitest'; import {mount} from '@vue/test-utils'; import ActionJobStep from './ActionJobStep.vue'; @@ -262,4 +265,22 @@ describe('ActionJobStep', () => { // Check if after the log list exists another log line expect(wrapper.get('.job-log-list + .job-log-line > .log-msg').text()).toEqual('A line outside the group'); }); + + test('scrollIntoView focuses on a line from the log', () => { + const wrapper = createWrapper(); + const logLines = [ + {index: 1, timestamp: 1765163618, message: 'Starting build'}, + {index: 2, timestamp: 1765163619, message: 'Running tests'}, + {index: 3, timestamp: 1765163620, message: 'Build complete'}, + ]; + wrapper.vm.appendLogs(logLines, 1765163618); + + const scrollIntoViewMock = vi.fn(); + const targetElement = wrapper.find('#jobstep-12321-1 .line-num').element; + targetElement.scrollIntoView = scrollIntoViewMock; + + wrapper.vm.scrollIntoView('#jobstep-12321-1'); + + expect(scrollIntoViewMock).toHaveBeenCalled(); + }); }); diff --git a/web_src/js/components/ActionJobStep.vue b/web_src/js/components/ActionJobStep.vue index 5d9dd64ea4..600f1ce344 100644 --- a/web_src/js/components/ActionJobStep.vue +++ b/web_src/js/components/ActionJobStep.vue @@ -1,3 +1,8 @@ + + @@ -231,8 +244,61 @@ export default { position: sticky; top: 60px; } + +.job-step-logs { + font-family: var(--fonts-monospace); + margin: 8px 0; + font-size: 12px; +} + diff --git a/web_src/js/components/ActionJobStepList.test.js b/web_src/js/components/ActionJobStepList.test.js new file mode 100644 index 0000000000..617529f852 --- /dev/null +++ b/web_src/js/components/ActionJobStepList.test.js @@ -0,0 +1,175 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +import {describe, expect, test, vi} from 'vitest'; +import {mount} from '@vue/test-utils'; +import ActionJobStepList from './ActionJobStepList.vue'; +import ActionJobStep from './ActionJobStep.vue'; + +vi.mock('../utils/time.js', () => ({ + formatDatetime: vi.fn((date) => date.toISOString()), +})); + +describe('ActionJobStepList', () => { + const mockIsExpandable = vi.fn(() => true); + const mockIsDone = vi.fn(() => true); + + const defaultProps = { + steps: [ + {status: 'success', summary: 'step 1 - go grocery shopping', duration: '3601s'}, + {status: 'running', summary: 'step 2 - cook food', duration: '301s'}, + {status: 'waiting', summary: 'step 3 - eat food', duration: ''}, + ], + stepStates: [ + {cursor: null, expanded: false}, + {cursor: null, expanded: false}, + {cursor: null, expanded: false}, + ], + runStatus: 'running', + isExpandable: mockIsExpandable, + isDone: mockIsDone, + timeVisibleTimestamp: false, + timeVisibleSeconds: false, + }; + + function createWrapper(props = {}) { + return mount(ActionJobStepList, { + props: { + ...defaultProps, + ...props, + }, + }); + } + + test('pass-through to ActionJobStep', () => { + // ActionJobStepList's tests don't need to validate the functionality of ActionJobStep -- that is the responsibility + // of its own tests. But we should validate that ActionJobStepList invokes the child element and passes in relevant + // data. + const wrapper = createWrapper(); + const jobSteps = wrapper.findAllComponents(ActionJobStep); + expect(jobSteps).toHaveLength(3); + expect(jobSteps[0].props()).toEqual({ + runStatus: 'running', + isExpandable: mockIsExpandable, + isDone: mockIsDone, + stepId: 0, + status: 'success', + summary: 'step 1 - go grocery shopping', + duration: '3601s', + expanded: false, + cursor: null, + timeVisibleTimestamp: false, + timeVisibleSeconds: false, + }); + }); + + test('render list elements', () => { + const wrapper = createWrapper(); + expect(wrapper.findAll('.job-step-container')).toHaveLength(1); + expect(wrapper.findAll('.job-step-section')).toHaveLength(3); + }); + + test('render empty', () => { + const wrapper = createWrapper({steps: []}); + expect(wrapper.findAll('.job-step-container')).toHaveLength(0); + expect(wrapper.findAll('.job-step-section')).toHaveLength(0); + }); + + test('pass-through appendLogs', () => { + const wrapper = createWrapper({ + stepStates: [ + {cursor: 0, expanded: true}, + {cursor: null, expanded: false}, + {cursor: null, expanded: false}, + ], + }); + + expect(wrapper.findAll('.job-log-line').length).toEqual(0); + + const logLines = [ + {index: 1, timestamp: 1765163618, message: 'Starting build'}, + {index: 2, timestamp: 1765163619, message: 'Running tests'}, + {index: 3, timestamp: 1765163620, message: 'Build complete'}, + ]; + wrapper.vm.appendLogs(0, logLines, 1765163618); + + expect(wrapper.findAll('.job-log-line').length).toEqual(3); + }); + + test('toggle visibility of timestamp', async () => { + const wrapper = createWrapper({ + stepStates: [ + {cursor: 0, expanded: true}, + {cursor: null, expanded: false}, + {cursor: null, expanded: false}, + ], + }); + const logLines = [ + {index: 1, timestamp: 1765163618, message: 'Starting build'}, + ]; + wrapper.vm.appendLogs(0, logLines, 1765163618); + + // pre-condition - expect log timestamps are hidden + expect(wrapper.find('.log-time-stamp').exists()).toBe(true); + expect(wrapper.find('.log-time-stamp').classes()).toContain('tw-hidden'); + + await wrapper.setProps({timeVisibleTimestamp: true}); + + expect(wrapper.find('.log-time-stamp').exists()).toBe(true); + expect(wrapper.find('.log-time-stamp').classes()).not.toContain('tw-hidden'); + }); + + test('toggle visibility of duration seconds', async () => { + const wrapper = createWrapper({ + stepStates: [ + {cursor: 0, expanded: true}, + {cursor: null, expanded: false}, + {cursor: null, expanded: false}, + ], + }); + const logLines = [ + {index: 1, timestamp: 1765163618, message: 'Starting build'}, + ]; + wrapper.vm.appendLogs(0, logLines, 1765163618); + + // pre-condition - expect log time seconds are hidden + expect(wrapper.find('.log-time-seconds').exists()).toBe(true); + expect(wrapper.find('.log-time-seconds').classes()).toContain('tw-hidden'); + + await wrapper.setProps({timeVisibleSeconds: true}); + + expect(wrapper.find('.log-time-seconds').exists()).toBe(true); + expect(wrapper.find('.log-time-seconds').classes()).not.toContain('tw-hidden'); + }); + + test('emits toggle event on click when expandable', async () => { + const wrapper = createWrapper(); + await wrapper.find('.job-step-summary').trigger('click'); + expect(wrapper.emitted('toggleStepLogs')).toBeTruthy(); + expect(wrapper.emitted('toggleStepLogs')).toHaveLength(1); + expect(wrapper.emitted('toggleStepLogs')).toStrictEqual([[0]]); // step index that was toggled + }); + + test('scrollIntoView focuses on a line from the log', () => { + const wrapper = createWrapper({ + stepStates: [ + {cursor: 0, expanded: true}, + {cursor: null, expanded: false}, + {cursor: null, expanded: false}, + ], + }); + const logLines = []; + for (let i = 0; i < 1000; i++) { + logLines.push({index: 1 + i, timestamp: 1765163618 + i, message: `Line ${i}`}); + } + wrapper.vm.appendLogs(0, logLines, 1765163618); + + const scrollIntoViewMock = vi.fn(); + const targetElement = wrapper.find('#jobstep-0-999 .line-num').element; + targetElement.scrollIntoView = scrollIntoViewMock; + + wrapper.vm.scrollIntoView(0, '#jobstep-0-999'); + + expect(scrollIntoViewMock).toHaveBeenCalled(); + }); +}); diff --git a/web_src/js/components/ActionJobStepList.vue b/web_src/js/components/ActionJobStepList.vue new file mode 100644 index 0000000000..8cb052b02c --- /dev/null +++ b/web_src/js/components/ActionJobStepList.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue index 0bdce36995..aa2c4f6d2a 100644 --- a/web_src/js/components/RepoActionView.vue +++ b/web_src/js/components/RepoActionView.vue @@ -1,7 +1,7 @@ From 82624a2a8c704f6a573f80a4a4ebbb62cc93a7f7 Mon Sep 17 00:00:00 2001 From: Beowulf Date: Mon, 29 Dec 2025 20:54:49 +0100 Subject: [PATCH 068/854] fix: process dynamically added content via htmx (#10572) When new content is added via JS and htmx is not used for this change, htmx need to be informed that DOM changes happened and that it needs to reprocess the DOM (or at least the changed parts). When a diff is really large, it is hidden by default. The user can press a button to load the diff, which then will be added via JS. The diff contains buttons to expand it, which are using htmx behind the scenes. Therefore a reprocessing via htmx needs to be triggered after adding the large diff. Fixes #10570 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10572 Reviewed-by: Gusted Co-authored-by: Beowulf Co-committed-by: Beowulf --- tests/e2e/declare_repos_test.go | 29 ++++++++++++++++++++++ tests/e2e/file-diff.test.e2e.ts | 41 ++++++++++++++++++++++++++++++++ web_src/js/features/repo-diff.js | 2 ++ 3 files changed, 72 insertions(+) create mode 100644 tests/e2e/file-diff.test.e2e.ts diff --git a/tests/e2e/declare_repos_test.go b/tests/e2e/declare_repos_test.go index 23bc023b70..85e3fcbda8 100644 --- a/tests/e2e/declare_repos_test.go +++ b/tests/e2e/declare_repos_test.go @@ -6,6 +6,7 @@ package e2e import ( "fmt" "os" + "strconv" "strings" "testing" "time" @@ -144,6 +145,34 @@ body: addCommitToBranch(t, user, repo, "test-branch", "test-branch", "test-README.md", commit2Sha, readStringFile(t, "tests/e2e/declarative-repo/long-diff-test/3-README.md")) }), + newRepo(t, 2, "huge-diff-test", nil, []FileChanges{{ + Filename: "glossary.po", + Versions: []string{ + func() string { + var sb strings.Builder + sb.Write([]byte("0")) + for i := 1; i < 2000; i++ { + sb.WriteString(strconv.Itoa(i)) + sb.WriteByte('\n') + } + return sb.String() + }(), + }, + }}, func(user *user_model.User, repo *repo_model.Repository) { + addCommitToBranch(t, user, repo, "main", "main-2", "glossary.po", "", + func() string { + var sb strings.Builder + sb.Write([]byte("0")) + for i := 1; i < 2000; i++ { + sb.WriteString(strconv.Itoa(i)) + if i%12 == 0 { + sb.WriteString("Blub") + } + sb.WriteByte('\n') + } + return sb.String() + }()) + }), // add your repo declarations here } diff --git a/tests/e2e/file-diff.test.e2e.ts b/tests/e2e/file-diff.test.e2e.ts new file mode 100644 index 0000000000..f6c398e009 --- /dev/null +++ b/tests/e2e/file-diff.test.e2e.ts @@ -0,0 +1,41 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +// @watch start +// templates/repo/diff/** +// web_src/css/review.css +// web_src/js/features/repo-diff.js +// @watch end + +import {expect} from '@playwright/test'; +import {test} from './utils_e2e.ts'; + +test.use({user: 'user2'}); + +test('Expand Large diff', async ({page}) => { + let response = await page.goto('/user2/huge-diff-test/src/branch/main-2', {waitUntil: 'domcontentloaded'}); + expect(response?.status()).toBe(200); + + const commitUrl = await page.locator('.commit-summary a').getAttribute('href'); + + response = await page.goto(commitUrl, {waitUntil: 'domcontentloaded'}); + expect(response?.status()).toBe(200); + + const loadDiff = page.locator('.diff-load-button'); + const expandDiff = page.locator('.code-expander-button'); + const diffLines = page.locator('.file-body tbody > tr'); + + await expect(loadDiff).toBeVisible(); + + loadDiff.click(); + await page.waitForLoadState('load'); + + await expect(expandDiff).toHaveCount(167); + await expect(diffLines).toHaveCount(1495); + + await expandDiff.first().click(); + await page.waitForLoadState('load'); + + await expect(expandDiff).toHaveCount(166); + await expect(diffLines).toHaveCount(1502); +}); diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js index 9b62b9f94f..02481be853 100644 --- a/web_src/js/features/repo-diff.js +++ b/web_src/js/features/repo-diff.js @@ -1,4 +1,5 @@ import $ from 'jquery'; +import htmx from 'htmx.org'; import {initCompReactionSelector} from './comp/ReactionSelector.js'; import {initRepoIssueContentHistory} from './repo-issue-content.js'; import {initDiffFileTree} from './repo-diff-filetree.js'; @@ -151,6 +152,7 @@ function onShowMoreFiles() { initViewedCheckboxListenerFor(); countAndUpdateViewedFiles(); initImageDiff(); + htmx.process(document.body); } export async function loadMoreFiles(url) { From 42114d262701c65c3b012b7b2d6141359fdcfa06 Mon Sep 17 00:00:00 2001 From: Mathieu Fenniak Date: Tue, 30 Dec 2025 02:31:23 +0100 Subject: [PATCH 069/854] fix: build-release workflow stops its own end-to-end checks when run concurrently (#10632) `build-release.yml` attempts to run an end-to-end check with a cascading PR, but it doesn't target the currently building branch. When two releases build simultaneously (eg. `forgejo/v14.0` and `forgejo`), whichever one starts the end-to-end test first is then "cancelled" by the second one as it pushes an update to the same branch. This will be a bit of an experimental change due to the difficulty in setting up a test environment. After merge, I intend to watch a v14 and forgejo build and verify that they are independent, and, that both are actually tested with the correct target build. This introduces a need to backport any changes to `.forgejo/cascading-release-end-to-end` in the future to maintain cascading functionality in all active releases. ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [ ] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [x] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10632 Reviewed-by: Michael Kriese Co-authored-by: Mathieu Fenniak Co-committed-by: Mathieu Fenniak --- .forgejo/cascading-release-end-to-end | 3 +++ .forgejo/workflows/build-release.yml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.forgejo/cascading-release-end-to-end b/.forgejo/cascading-release-end-to-end index 9be0737b0f..f78c3aeedb 100755 --- a/.forgejo/cascading-release-end-to-end +++ b/.forgejo/cascading-release-end-to-end @@ -2,6 +2,9 @@ set -ex +# WARNING: Changes to the behaviour of this file should be backported to all active releases, as it is used in +# `build-release.yml` from release branches. + end_to_end=$1 end_to_end_pr=$2 forgejo=$3 diff --git a/.forgejo/workflows/build-release.yml b/.forgejo/workflows/build-release.yml index 4a17e30174..7b38c27c83 100644 --- a/.forgejo/workflows/build-release.yml +++ b/.forgejo/workflows/build-release.yml @@ -206,7 +206,7 @@ jobs: origin-url: ${{ env.GITHUB_SERVER_URL }} origin-repo: ${{ github.repository }} origin-token: ${{ secrets.CASCADE_ORIGIN_TOKEN }} - origin-ref: refs/heads/forgejo + origin-ref: ${{ github.ref }} destination-url: https://code.forgejo.org destination-fork-repo: ${{ vars.CASCADE_DESTINATION_DOER }}/end-to-end destination-repo: forgejo/end-to-end From d8a5ee81fbb228bc44b3938988c7e43621e4831f Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Tue, 30 Dec 2025 10:00:22 +0100 Subject: [PATCH 070/854] chore(release-notes): teach release-notes-assistant that v11.0 is LTS (#10638) This needs to be updated every time a LTS is published because the release-notes-assistant has no notion of what a LTS is. ## Tests - After it is merged - Trigger https://codeberg.org/forgejo/forgejo/actions?workflow=release-notes-assistant-milestones.yml - See that v11.0.9 milestone contains only the relevant pull requests https://codeberg.org/forgejo/forgejo/milestone/35400 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10638 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Earl Warren Co-committed-by: Earl Warren --- .release-notes-assistant.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.release-notes-assistant.yaml b/.release-notes-assistant.yaml index f8264c0897..fe65dc3241 100644 --- a/.release-notes-assistant.yaml +++ b/.release-notes-assistant.yaml @@ -7,7 +7,7 @@ branch-from-version: 'v%[1]d.%[2]d/forgejo' tag-from-version: 'v%[1]d.%[2]d.%[3]d' supported-release-count: 3 branch-known: - - 'v7.0/forgejo' + - 'v11.0/forgejo' cleanup-line: 'sed -Ee "s/^(feat|fix):\s*//g" -e "s/^\[WIP\] //" -e "s/^WIP: //" -e "s;\[(UI|BUG|FEAT|v.*?/forgejo)\]\s*;;g"' render-header: | From 9b2f7c557bb917bb6bc7c1e2f2ea1487fd1b92a6 Mon Sep 17 00:00:00 2001 From: Mathieu Fenniak Date: Tue, 30 Dec 2025 17:33:21 +0100 Subject: [PATCH 071/854] feat: support jobs..secrets with reusable workflow expansion (#10627) Follow-up to #10525; adds support for `jobs..secrets` to expanded reusable workflows (when no `runs-on` is specified in a job that `uses: ...` another workflow). ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). - **end-to-end testing**: [prepared, PR n](https://code.forgejo.org/forgejo/end-to-end/pulls/1351) ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [ ] Doc to be created - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [x] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10627 Reviewed-by: Andreas Ahlenstorf Co-authored-by: Mathieu Fenniak Co-committed-by: Mathieu Fenniak --- models/actions/run.go | 24 +++ models/actions/run_test.go | 55 +++++ models/secret/secret.go | 23 +-- models/secret/secret_test.go | 15 +- .../TestGetSecretsOfJob/action_run.yml | 94 +++++++++ .../TestGetSecretsOfJob/action_run_job.yml | 192 ++++++++++++++++++ .../action_task_output.yml | 6 + .../TestGetSecretsOfJob/action_variable.yml | 22 ++ services/actions/secret.go | 145 +++++++++++++ services/actions/secret_test.go | 108 ++++++++++ services/actions/task.go | 3 +- 11 files changed, 654 insertions(+), 33 deletions(-) create mode 100644 services/actions/TestGetSecretsOfJob/action_run.yml create mode 100644 services/actions/TestGetSecretsOfJob/action_run_job.yml create mode 100644 services/actions/TestGetSecretsOfJob/action_task_output.yml create mode 100644 services/actions/TestGetSecretsOfJob/action_variable.yml create mode 100644 services/actions/secret.go create mode 100644 services/actions/secret_test.go diff --git a/models/actions/run.go b/models/actions/run.go index 8194c07940..1551032f07 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -208,6 +208,30 @@ func (run *ActionRun) SetDefaultConcurrencyGroup() { )) } +func (run *ActionRun) FindOuterWorkflowCall(ctx context.Context, innerCall *ActionRunJob) (*ActionRunJob, error) { + allJobs, err := GetRunJobsByRunID(ctx, run.ID) + if err != nil { + return nil, fmt.Errorf("failure to get run jobs: %w", err) + } + if innerCall.workflowPayloadDecoded == nil || innerCall.workflowPayloadDecoded.Metadata.WorkflowCallParent == "" { + return nil, errors.New("invalid state for FindOuterWorkflowCall") + } + parent := innerCall.workflowPayloadDecoded.Metadata.WorkflowCallParent + for _, job := range allJobs { + if job.ID == innerCall.ID { + continue + } + swf, err := job.DecodeWorkflowPayload() + if err != nil { + return nil, err + } + if swf.Metadata.WorkflowCallID == parent { + return job, nil + } + } + return nil, fmt.Errorf("no workflow call with ID %s found in run %d", parent, run.ID) +} + func actionsCountOpenCacheKey(repoID int64) string { return fmt.Sprintf("Actions:CountOpenActionRuns:%d", repoID) } diff --git a/models/actions/run_test.go b/models/actions/run_test.go index 3a169dd56a..a0fdfddbd6 100644 --- a/models/actions/run_test.go +++ b/models/actions/run_test.go @@ -272,3 +272,58 @@ jobs: // Expect job with an incomplete runs-on to be StatusBlocked: assert.Equal(t, StatusBlocked, job.Status) } + +func TestActionRun_FindOuterWorkflowCall(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + + pullRequestPosterID := int64(4) + repoID := int64(10) + pullRequestID := int64(2) + run := &ActionRun{ + RepoID: repoID, + PullRequestID: pullRequestID, + PullRequestPosterID: pullRequestPosterID, + } + + workflowRaw := []byte(` +jobs: + outer-job: + uses: ./.forgejo/workflows/reusable.yml +`) + workflows, err := jobparser.Parse(workflowRaw, false, + jobparser.WithJobOutputs(map[string]map[string]string{}), + jobparser.ExpandLocalReusableWorkflows(func(job *jobparser.Job, path string) ([]byte, error) { + return []byte(` +on: + workflow_call: +jobs: + inner-job-1: + runs-on: debian + steps: [] + inner-job-2: + runs-on: debian + steps: [] +`), nil + })) + require.NoError(t, err) + require.NoError(t, InsertRun(t.Context(), run, workflows)) + + jobs, err := db.Find[ActionRunJob](t.Context(), FindRunJobOptions{RunID: run.ID}) + require.NoError(t, err) + require.Len(t, jobs, 3) + + for _, j := range jobs { + t.Run(j.Name, func(t *testing.T) { + _, err := j.DecodeWorkflowPayload() + require.NoError(t, err) + outer, err := run.FindOuterWorkflowCall(t.Context(), j) + if j.Name == "outer-job" { + require.ErrorContains(t, err, "invalid state for FindOuterWorkflowCall") + } else { + require.NoError(t, err) + require.NotNil(t, outer) + assert.Equal(t, "outer-job", outer.Name) + } + }) + } +} diff --git a/models/secret/secret.go b/models/secret/secret.go index 0a5db17690..b19199c177 100644 --- a/models/secret/secret.go +++ b/models/secret/secret.go @@ -8,9 +8,7 @@ import ( "fmt" "strings" - actions_model "forgejo.org/models/actions" "forgejo.org/models/db" - actions_module "forgejo.org/modules/actions" "forgejo.org/modules/keying" "forgejo.org/modules/log" "forgejo.org/modules/timeutil" @@ -120,28 +118,17 @@ func (s *Secret) SetSecret(data string) { s.Data = keying.ActionSecret.Encrypt([]byte(data), keying.ColumnAndID("data", s.ID)) } -func GetSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[string]string, error) { +func FetchActionSecrets(ctx context.Context, ownerID, repoID int64) (map[string]string, error) { secrets := map[string]string{} - secrets["GITHUB_TOKEN"] = task.Token - secrets["GITEA_TOKEN"] = task.Token - secrets["FORGEJO_TOKEN"] = task.Token - - if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { - // ignore secrets for fork pull request, except GITHUB_TOKEN, GITEA_TOKEN and FORGEJO_TOKEN which are automatically generated. - // for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch - // see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target - return secrets, nil - } - - ownerSecrets, err := db.Find[Secret](ctx, FindSecretsOptions{OwnerID: task.Job.Run.Repo.OwnerID}) + ownerSecrets, err := db.Find[Secret](ctx, FindSecretsOptions{OwnerID: ownerID}) if err != nil { - log.Error("find secrets of owner %v: %v", task.Job.Run.Repo.OwnerID, err) + log.Error("find secrets of owner %v: %v", ownerID, err) return nil, err } - repoSecrets, err := db.Find[Secret](ctx, FindSecretsOptions{RepoID: task.Job.Run.RepoID}) + repoSecrets, err := db.Find[Secret](ctx, FindSecretsOptions{RepoID: repoID}) if err != nil { - log.Error("find secrets of repo %v: %v", task.Job.Run.RepoID, err) + log.Error("find secrets of repo %v: %v", repoID, err) return nil, err } diff --git a/models/secret/secret_test.go b/models/secret/secret_test.go index 76b673f2fe..50120ecfa3 100644 --- a/models/secret/secret_test.go +++ b/models/secret/secret_test.go @@ -6,8 +6,6 @@ package secret import ( "testing" - "forgejo.org/models/actions" - "forgejo.org/models/repo" "forgejo.org/models/unittest" "forgejo.org/modules/keying" "forgejo.org/modules/util" @@ -85,17 +83,8 @@ func TestInsertEncryptedSecret(t *testing.T) { }) }) - t.Run("Get secrets", func(t *testing.T) { - secrets, err := GetSecretsOfTask(t.Context(), &actions.ActionTask{ - Job: &actions.ActionRunJob{ - Run: &actions.ActionRun{ - RepoID: 1, - Repo: &repo.Repository{ - OwnerID: 2, - }, - }, - }, - }) + t.Run("FetchActionSecrets", func(t *testing.T) { + secrets, err := FetchActionSecrets(t.Context(), 2, 1) require.NoError(t, err) assert.Equal(t, "some owner secret", secrets["OWNER_SECRET"]) assert.Equal(t, "some repository secret", secrets["REPO_SECRET"]) diff --git a/services/actions/TestGetSecretsOfJob/action_run.yml b/services/actions/TestGetSecretsOfJob/action_run.yml new file mode 100644 index 0000000000..0bf311292f --- /dev/null +++ b/services/actions/TestGetSecretsOfJob/action_run.yml @@ -0,0 +1,94 @@ +# Supporting data for Case 600 +- + id: 900 + title: "running" + owner_id: 2 + repo_id: 63 + workflow_id: "running.yaml" + index: 4 + trigger_event: "push" + is_fork_pull_request: false + +# Supporting data for Case 601 +- + id: 901 + title: "running" + owner_id: 2 + repo_id: 63 + workflow_id: "running.yaml" + index: 5 + trigger_event: "pull_request_target" + is_fork_pull_request: false + +# Supporting data for Case 602 +- + id: 902 + title: "running" + owner_id: 2 + repo_id: 63 + workflow_id: "running.yaml" + index: 6 + trigger_event: "pull_request_target" + is_fork_pull_request: true + +# Supporting data for Case 603 +- + id: 903 + title: "running" + owner_id: 2 + repo_id: 63 + workflow_id: "running.yaml" + index: 7 + trigger_event: "pull_request" + is_fork_pull_request: false + +# Supporting data for Case 604 +- + id: 904 + title: "running" + owner_id: 2 + repo_id: 63 + workflow_id: "running.yaml" + index: 8 + trigger_event: "pull_request" + is_fork_pull_request: true + +# Supporting data for Case 605 +- + id: 905 + title: "running" + owner_id: 2 + repo_id: 63 + workflow_id: "running.yaml" + index: 9 + trigger_event: "pull_request" + is_fork_pull_request: false + +# Supporting data for Case 607 +- + id: 906 + title: "running" + owner_id: 2 + repo_id: 63 + workflow_id: "running.yaml" + index: 10 + trigger_event: "pull_request" + is_fork_pull_request: false + +# Supporting data for Case 610 +- + id: 907 + title: "running" + owner_id: 2 + repo_id: 63 + ref: "refs/heads/main" + workflow_id: "running.yaml" + index: 11 + trigger_event: "workflow_dispatch" + is_fork_pull_request: false + event_payload: | + { + "inputs": { + "some_wd_input": "some_wd_input_value" + } + } diff --git a/services/actions/TestGetSecretsOfJob/action_run_job.yml b/services/actions/TestGetSecretsOfJob/action_run_job.yml new file mode 100644 index 0000000000..a1bad9fe98 --- /dev/null +++ b/services/actions/TestGetSecretsOfJob/action_run_job.yml @@ -0,0 +1,192 @@ +# Case 600 -- on:push workflow with some secrets +- + id: 600 + run_id: 900 + workflow_payload: | + "on": + push: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + +# Case 601 -- on: pull_request_target workflow, local PR (not fork) +- + id: 601 + run_id: 901 + workflow_payload: | + "on": + pull_request_target: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + +# Case 602 -- on: pull_request_target workflow, fork PR +- + id: 602 + run_id: 902 + workflow_payload: | + "on": + pull_request_target: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + +# Case 603 -- on: pull_request workflow, local PR (not fork) +- + id: 603 + run_id: 903 + workflow_payload: | + "on": + pull_request: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + +# Case 604 -- on: pull_request workflow, fork PR +- + id: 604 + run_id: 904 + workflow_payload: | + "on": + pull_request: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + +# Case 605 -- workflow call inner job, inherit secrets, 606 is the outer job +- + id: 605 + run_id: 905 + workflow_payload: | + "on": + pull_request_target: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + __metadata: + workflow_call_parent: b5a9f46f1f2513d7777fde50b169d323a6519e349cc175484c947ac315a209ed +- + id: 606 + run_id: 905 + workflow_payload: | + "on": + pull_request_target: + jobs: + invoke-reusable: + uses: ./.forgejo/workflows/produce.yml + secrets: inherit + __metadata: + workflow_call_id: b5a9f46f1f2513d7777fde50b169d323a6519e349cc175484c947ac315a209ed + +# Case 607 -- workflow call two layer inner job, inherit secrets, 607->608->609 +- + id: 607 + run_id: 906 + workflow_payload: | + "on": + workflow_call: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + __metadata: + workflow_call_parent: b5a9f46f1f2513d7777fde50b169d323a6519e349cc175484c947ac315a209ed +- + id: 608 + run_id: 906 + workflow_payload: | + "on": + workflow_call: + jobs: + invoke-reusable: + uses: ./.forgejo/workflows/produce-specific.yml + secrets: inherit + __metadata: + workflow_call_id: b5a9f46f1f2513d7777fde50b169d323a6519e349cc175484c947ac315a209ed + workflow_call_parent: 1976193ec4c48a92ba58816b34116272f5b3a612b91494956e5b53ee70b8714f +- + id: 609 + run_id: 906 + workflow_payload: | + "on": + pull_request: + jobs: + invoke-reusable: + uses: ./.forgejo/workflows/produce.yml + secrets: + secret_1: ${{ secrets.secret_1 }} -- but are you sure? + __metadata: + workflow_call_id: 1976193ec4c48a92ba58816b34116272f5b3a612b91494956e5b53ee70b8714f + +# Case 610 -- workflow call specifically defined secrets, 611 is the outer job, 612 is another job in the same workflow +- + id: 610 + run_id: 907 + workflow_payload: | + "on": + workflow_call: + jobs: + produce-artifacts: + name: produce-artifacts + runs-on: docker + steps: + - run: echo "OK!" + __metadata: + workflow_call_parent: b5a9f46f1f2513d7777fde50b169d323a6519e349cc175484c947ac315a209ed +- + id: 611 + run_id: 907 + needs: '["provide-outputs"]' + workflow_payload: | + "on": + workflow_dispatch: + jobs: + invoke-reusable: + uses: ./.forgejo/workflows/produce-specific.yml + secrets: + forgejo: context forgejo = ${{ forgejo.ref }} + inputs: context inputs = ${{ inputs.some_wd_input }} + matrix: context matrix = ${{ matrix.some-dimension }} + needs: context needs = ${{ needs.provide-outputs.outputs.some-output }} + secrets: context secrets = ${{ secrets.secret_1 }} + strategy: context strategy = ${{ strategy.fail-fast }} + vars: context vars = ${{ vars.repo_var }} + strategy: + fail-fast: false + matrix: + some-dimension: + - some-dimension-value + __metadata: + workflow_call_id: b5a9f46f1f2513d7777fde50b169d323a6519e349cc175484c947ac315a209ed +- + id: 612 + run_id: 907 + job_id: provide-outputs + status: 1 # success + workflow_payload: | + "on": + workflow_dispatch: + jobs: + provide-outputs: + steps: [] + task_id: 100 diff --git a/services/actions/TestGetSecretsOfJob/action_task_output.yml b/services/actions/TestGetSecretsOfJob/action_task_output.yml new file mode 100644 index 0000000000..6f33d22d29 --- /dev/null +++ b/services/actions/TestGetSecretsOfJob/action_task_output.yml @@ -0,0 +1,6 @@ +# Supporting data for Case 610 +- + id: 100 + task_id: 100 + output_key: some-output + output_value: 'abcdefghijklmnopqrstuvwxyz' diff --git a/services/actions/TestGetSecretsOfJob/action_variable.yml b/services/actions/TestGetSecretsOfJob/action_variable.yml new file mode 100644 index 0000000000..859f90ae34 --- /dev/null +++ b/services/actions/TestGetSecretsOfJob/action_variable.yml @@ -0,0 +1,22 @@ +# Case w/ action_run_job.id = 601 +- + id: 1001 + name: REPO_VAR + owner_id: 0 + repo_id: 63 + data: "this is a repo variable" + created_unix: 1737000000 +- + id: 1002 + name: ORG_VAR + owner_id: 2 + repo_id: 0 + data: "this is an org variable" + created_unix: 1737000000 +- + id: 1003 + name: GLOBAL_VAR + owner_id: 0 + repo_id: 0 + data: "this is a global variable" + created_unix: 1737000000 diff --git a/services/actions/secret.go b/services/actions/secret.go new file mode 100644 index 0000000000..b62547ce70 --- /dev/null +++ b/services/actions/secret.go @@ -0,0 +1,145 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package actions + +import ( + "context" + "errors" + "fmt" + + actions_model "forgejo.org/models/actions" + secret_model "forgejo.org/models/secret" + actions_module "forgejo.org/modules/actions" + "forgejo.org/modules/json" + "forgejo.org/modules/structs" + + "code.forgejo.org/forgejo/runner/v12/act/jobparser" +) + +func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[string]string, error) { + secrets, err := getSecretsOfJob(ctx, task.Job) + secrets["GITHUB_TOKEN"] = task.Token + secrets["GITEA_TOKEN"] = task.Token + secrets["FORGEJO_TOKEN"] = task.Token + return secrets, err +} + +func getSecretsOfJob(ctx context.Context, job *actions_model.ActionRunJob) (map[string]string, error) { + isInnerWorkflowCall, err := job.IsWorkflowCallInnerJob() + if err != nil { + return nil, err + } + + err = job.LoadRun(ctx) + if err != nil { + return nil, fmt.Errorf("failure to load job run: %w", err) + } + + if isInnerWorkflowCall { + return getSecretsOfInnerWorkflowCall(ctx, job) + } + + if job.Run.IsForkPullRequest && job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { + // ignore secrets for fork pull request, except GITHUB_TOKEN, GITEA_TOKEN and FORGEJO_TOKEN which are automatically generated. + // for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch + // see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target + return map[string]string{}, nil + } + + err = job.Run.LoadRepo(ctx) + if err != nil { + return nil, err + } + + jobSecrets, err := secret_model.FetchActionSecrets(ctx, job.Run.Repo.OwnerID, job.Run.RepoID) + if err != nil { + // Don't return error details, just in case they contain confidential details and error reaches a user; + // FetchActionSecrets logs all errors to the server log. + return nil, errors.New("failure to fetch secrets") + } + return jobSecrets, nil +} + +func getSecretsOfInnerWorkflowCall(ctx context.Context, job *actions_model.ActionRunJob) (map[string]string, error) { + // Workflow calls can have two different behaviours -- they can either have `secrets: inherit` in which case we get + // the secrets of the caller and pass them in, or, they can have `secrets: { ... }` with key-values that need to be + // evaluated in the context of the parent (that is, `${{ secret.example_secret }}` would reference `example_secret` + // from the caller's secrets). + // + // In either case, we need the caller job's secrets, and we need the caller job's workflow definition to find out + // how they wanted secrets defined for this workflow call. + outerWorkflowCall, err := job.Run.FindOuterWorkflowCall(ctx, job) + if err != nil { + return nil, fmt.Errorf("failure to find outer workflow call: %w", err) + } + outerSecrets, err := getSecretsOfJob(ctx, outerWorkflowCall) + if err != nil { + return nil, err + } + + outerWorkflowPayload, err := outerWorkflowCall.DecodeWorkflowPayload() + if err != nil { + return nil, err + } + _, outerJob := outerWorkflowPayload.Job() + if outerJob.InheritSecrets() { + return outerSecrets, nil + } + + // Gather all the data that is needed to perform an expression evaluation of the parent job's secrets context: + err = outerWorkflowCall.LoadRun(ctx) + if err != nil { + return nil, fmt.Errorf("failure to load job's run: %w", err) + } + err = outerWorkflowCall.Run.LoadRepo(ctx) + if err != nil { + return nil, fmt.Errorf("failure to load run's repo: %w", err) + } + githubContext := generateGiteaContextForRun(outerWorkflowCall.Run) + taskNeeds, err := FindTaskNeeds(ctx, outerWorkflowCall) + if err != nil { + return nil, fmt.Errorf("failure evaluating 'needs' for job: %w", err) + } + needs := make([]string, 0, len(taskNeeds)) + jobResults := make(map[string]string, len(taskNeeds)) + jobOutputs := make(map[string]map[string]string, len(taskNeeds)) + for jobID, n := range taskNeeds { + needs = append(needs, jobID) + jobResults[jobID] = n.Result.String() + jobOutputs[jobID] = n.Outputs + } + vars, err := actions_model.GetVariablesOfRun(ctx, job.Run) + if err != nil { + return nil, fmt.Errorf("failure evaluating 'vars' for run: %w", err) + } + + var inputs map[string]any + if outerWorkflowCall.Run.TriggerEvent == actions_module.GithubEventWorkflowDispatch { + // workflow_dispatch inputs are stored in the event payload + var dispatchPayload *structs.WorkflowDispatchPayload + err := json.Unmarshal([]byte(outerWorkflowCall.Run.EventPayload), &dispatchPayload) + if err != nil { + return nil, fmt.Errorf("failure reading workflow dispatch payload: %w", err) + } + // transition from map[string]string to map[string]any... + inputs = make(map[string]any, len(dispatchPayload.Inputs)) + for k, v := range dispatchPayload.Inputs { + inputs[k] = v + } + } + + jobSecrets := jobparser.EvaluateWorkflowCallSecrets(&jobparser.EvaluateWorkflowCallSecretsArgs{ + CallerWorkflow: outerWorkflowPayload, + CallerSecrets: outerSecrets, + + GitCtx: githubContext, + Vars: vars, + Needs: needs, + JobResults: jobResults, + JobOutputs: jobOutputs, + JobInputs: inputs, + }) + + return jobSecrets, nil +} diff --git a/services/actions/secret_test.go b/services/actions/secret_test.go new file mode 100644 index 0000000000..107cde1a4d --- /dev/null +++ b/services/actions/secret_test.go @@ -0,0 +1,108 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package actions + +import ( + "testing" + + actions_model "forgejo.org/models/actions" + secret_model "forgejo.org/models/secret" + "forgejo.org/models/unittest" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetSecretsOfJob(t *testing.T) { + tests := []struct { + name string + runJobID int64 + secrets map[string]string + }{ + { + name: "push run", + runJobID: 600, + secrets: map[string]string{ + "SECRET_1": "the sky is blue", + "SECRET_2": "the ocean is also blue", + }, + }, + { + name: "on: pull_request_target workflow, local PR (not fork)", + runJobID: 601, + secrets: map[string]string{ + "SECRET_1": "the sky is blue", + "SECRET_2": "the ocean is also blue", + }, + }, + { + name: "on: pull_request_target workflow, fork PR", + runJobID: 602, + secrets: map[string]string{ + "SECRET_1": "the sky is blue", + "SECRET_2": "the ocean is also blue", + }, + }, + { + name: "on: pull_request workflow, local PR (not fork)", + runJobID: 603, + secrets: map[string]string{ + "SECRET_1": "the sky is blue", + "SECRET_2": "the ocean is also blue", + }, + }, + { + name: "on: pull_request workflow, fork PR", + runJobID: 604, + secrets: map[string]string{}, + }, + { + name: "workflow call inner job, inherit secrets", + runJobID: 605, + secrets: map[string]string{ + "SECRET_1": "the sky is blue", + "SECRET_2": "the ocean is also blue", + }, + }, + { + name: "workflow call two layer inner job, inherit secrets", + runJobID: 607, + secrets: map[string]string{ + // Even though we're 'inherit' in this case, we're inheriting from the parent call which is a subset + // (and modification) of the secrets -- so shouldn't see SECRET_2. + "SECRET_1": "the sky is blue -- but are you sure?", + }, + }, + { + name: "workflow call inner job, defined secrets", + runJobID: 610, + secrets: map[string]string{ + "FORGEJO": "context forgejo = refs/heads/main", + "INPUTS": "context inputs = some_wd_input_value", + "MATRIX": "context matrix = some-dimension-value", + "NEEDS": "context needs = abcdefghijklmnopqrstuvwxyz", + "SECRETS": "context secrets = the sky is blue", + "STRATEGY": "context strategy = false", + "VARS": "context vars = this is a repo variable", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer unittest.OverrideFixtures("services/actions/TestGetSecretsOfJob")() + require.NoError(t, unittest.PrepareTestDatabase()) + + // Due to encryption, more maintainable to do this rather than create secrets in fixture data + _, err := secret_model.InsertEncryptedSecret(t.Context(), 2, 0, "secret_1", "the sky is blue") + require.NoError(t, err) + _, err = secret_model.InsertEncryptedSecret(t.Context(), 0, 63, "secret_2", "the ocean is also blue") + require.NoError(t, err) + + runJob := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: tt.runJobID}) + actualSecrets, err := getSecretsOfJob(t.Context(), runJob) + require.NoError(t, err) + assert.Equal(t, tt.secrets, actualSecrets) + }) + } +} diff --git a/services/actions/task.go b/services/actions/task.go index 277c2f6ca0..1de054346a 100644 --- a/services/actions/task.go +++ b/services/actions/task.go @@ -10,7 +10,6 @@ import ( actions_model "forgejo.org/models/actions" "forgejo.org/models/db" - secret_model "forgejo.org/models/secret" "forgejo.org/modules/timeutil" "forgejo.org/modules/util" @@ -39,7 +38,7 @@ func PickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv } job = t.Job - secrets, err := secret_model.GetSecretsOfTask(ctx, t) + secrets, err := getSecretsOfTask(ctx, t) if err != nil { return fmt.Errorf("GetSecretsOfTask: %w", err) } From 51ac1bf45ffbb4e49625ba511ddec938fdec6713 Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Tue, 30 Dec 2025 18:01:17 +0100 Subject: [PATCH 072/854] feat: improve Discord webhook message formatting (#10626) This pull request escapes the dash before the author when a Discord webhook is triggered by a push event and formats the commit hash as code. ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). No tests were added, but the existing test for Discord webhooks passed. ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [x] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10626 Reviewed-by: Mathieu Fenniak Co-authored-by: Valentine Briese Co-committed-by: Valentine Briese --- services/webhook/discord.go | 2 +- services/webhook/discord_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/services/webhook/discord.go b/services/webhook/discord.go index 52aaafd5a0..cdab4d6733 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -223,7 +223,7 @@ func (d discordConvertor) Push(p *api.PushPayload) (DiscordPayload, error) { if utf8.RuneCountInString(message) > 50 { message = fmt.Sprintf("%.47s...", message) } - text += fmt.Sprintf("[%s](%s) %s - %s", commit.ID[:7], commit.URL, message, commit.Author.Name) + text += fmt.Sprintf("[`%s`](%s) %s \\- %s", commit.ID[:7], commit.URL, message, commit.Author.Name) // add linebreak to each commit but the last if i < len(p.Commits)-1 { text += "\n" diff --git a/services/webhook/discord_test.go b/services/webhook/discord_test.go index b04be30bc6..e94486def8 100644 --- a/services/webhook/discord_test.go +++ b/services/webhook/discord_test.go @@ -72,7 +72,7 @@ func TestDiscordPayload(t *testing.T) { assert.Len(t, pl.Embeds, 1) assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title) - assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.Embeds[0].Description) + assert.Equal(t, "[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message \\- user1\n[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message \\- user1", pl.Embeds[0].Description) assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.Embeds[0].URL) assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name) assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL) @@ -87,7 +87,7 @@ func TestDiscordPayload(t *testing.T) { assert.Len(t, pl.Embeds, 1) assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title) - assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... - user1", pl.Embeds[0].Description) + assert.Equal(t, "[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... \\- user1\n[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好... \\- user1", pl.Embeds[0].Description) assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name) assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL) assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL) @@ -101,7 +101,7 @@ func TestDiscordPayload(t *testing.T) { assert.Len(t, pl.Embeds, 1) assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title) - assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) \\# conflicts\n\\# \\- some/conflicting/file.txt - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) \\# conflicts\n\\# \\- some/conflicting/file.txt - user1", pl.Embeds[0].Description) + assert.Equal(t, "[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) \\# conflicts\n\\# \\- some/conflicting/file.txt \\- user1\n[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) \\# conflicts\n\\# \\- some/conflicting/file.txt \\- user1", pl.Embeds[0].Description) assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name) assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL) assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL) @@ -357,7 +357,7 @@ func TestDiscordJSONPayload(t *testing.T) { var body DiscordPayload err = json.NewDecoder(req.Body).Decode(&body) require.NoError(t, err) - assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", body.Embeds[0].Description) + assert.Equal(t, "[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message \\- user1\n[`2020558`](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message \\- user1", body.Embeds[0].Description) } var escapedMarkdownTests = map[string]struct { From 69f9d50745e75b025f714ec22f369cd6f78b4763 Mon Sep 17 00:00:00 2001 From: John Moon Date: Tue, 30 Dec 2025 22:39:34 +0100 Subject: [PATCH 073/854] feat: add Forgejo server version to runner context (#10642) Currently, there's no way for actions runners to know what version of Forgejo is running on the server side. This makes it difficult/impossible to know which features are available and can make maintaining compatibility tricky. Let's add the Forgejo server version to the context. See associated PR in the runner repo: https://code.forgejo.org/forgejo/runner/pulls/1249 ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [x] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10642 Reviewed-by: Michael Kriese Reviewed-by: Mathieu Fenniak Co-authored-by: John Moon Co-committed-by: John Moon --- services/actions/context.go | 1 + tests/integration/actions_job_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/services/actions/context.go b/services/actions/context.go index d982b231ff..0313b11031 100644 --- a/services/actions/context.go +++ b/services/actions/context.go @@ -112,6 +112,7 @@ func GenerateGiteaContext(run *actions_model.ActionRun, job *actions_model.Actio // additional contexts gitContext["gitea_default_actions_url"] = setting.Actions.DefaultActionsURL.URL() + gitContext["forgejo_server_version"] = setting.AppVer if job != nil { gitContext["job"] = job.JobID diff --git a/tests/integration/actions_job_test.go b/tests/integration/actions_job_test.go index baa1420bdd..e91f0e92bd 100644 --- a/tests/integration/actions_job_test.go +++ b/tests/integration/actions_job_test.go @@ -443,6 +443,7 @@ jobs: assert.Equal(t, actionRun.WorkflowID, gtCtx["workflow"].GetStringValue()) assert.Equal(t, "user2/actions-gitea-context/.gitea/workflows/pull.yml@refs/pull/1/head", gtCtx["workflow_ref"].GetStringValue()) assert.Equal(t, setting.Actions.DefaultActionsURL.URL(), gtCtx["gitea_default_actions_url"].GetStringValue()) + assert.Equal(t, setting.AppVer, gtCtx["forgejo_server_version"].GetStringValue()) token := gtCtx["token"].GetStringValue() assert.Equal(t, actionTask.TokenLastEight, token[len(token)-8:]) From 0a6a5cb73eb1000af25d2de9bc394ae2bc960377 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Wed, 31 Dec 2025 03:13:05 +0100 Subject: [PATCH 074/854] chore: remove obsolete code from button-legacy.css (#10581) Fixes #10580 Remove obsolete styles so that people do not trip over them. I went through the codebase with `rg` and made sure that the only elements which had potential to use such mix of classes were doing so accidentally, and removed all the unused code. ### A small fix for Forgejo themes Ref https://codeberg.org/forgejo/forgejo/pulls/10581#issuecomment-9245399. The missing variable was used in one place outside of devtest. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10581 Reviewed-by: Michael Kriese Reviewed-by: Beowulf Reviewed-by: Gusted Co-authored-by: 0ko <0ko@noreply.codeberg.org> Co-committed-by: 0ko <0ko@noreply.codeberg.org> --- templates/devtest/gitea-ui.tmpl | 2 - templates/repo/issue/filters.tmpl | 2 +- .../notification_subscriptions.tmpl | 2 +- web_src/css/modules/button-legacy.css | 41 ------------------- web_src/css/repo.css | 4 +- web_src/css/themes/theme-gitea-dark.css | 1 - web_src/css/themes/theme-gitea-light.css | 1 - 7 files changed, 4 insertions(+), 49 deletions(-) diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl index 1c88333520..6daf6d74c7 100644 --- a/templates/devtest/gitea-ui.tmpl +++ b/templates/devtest/gitea-ui.tmpl @@ -48,8 +48,6 @@
  • Supported but not recommended:

    Do not use if there is no strong requirement. Do not use grey/black buttons, they don't work well with dark theme.

    - - diff --git a/templates/repo/issue/filters.tmpl b/templates/repo/issue/filters.tmpl index 06e7c1aa6c..d69a8439ba 100644 --- a/templates/repo/issue/filters.tmpl +++ b/templates/repo/issue/filters.tmpl @@ -15,7 +15,7 @@ {{end}}
  • -