From 1756e30e102d079f8425aa2061ef80fd36c2e57d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 30 Oct 2023 04:13:06 +0100 Subject: [PATCH 01/10] Allow pull requests Manually Merged option to be used by non-admins (#27780) Currently this feature is only available to admins, but there is no clear reason why. If a user can actually merge pull requests, then this seems fine as well. This is useful in situations where direct pushes to the repository are commonly done by developers. --------- Co-authored-by: delvh --- routers/web/repo/issue.go | 8 +++++--- templates/repo/issue/view_content/pull.tmpl | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 96fce48878219..94300da868330 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1773,7 +1773,7 @@ func ViewIssue(ctx *context.Context) { pull := issue.PullRequest pull.Issue = issue canDelete := false - ctx.Data["AllowMerge"] = false + allowMerge := false if ctx.IsSigned { if err := pull.LoadHeadRepo(ctx); err != nil { @@ -1806,7 +1806,7 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("GetUserRepoPermission", err) return } - ctx.Data["AllowMerge"], err = pull_service.IsUserAllowedToMerge(ctx, pull, perm, ctx.Doer) + allowMerge, err = pull_service.IsUserAllowedToMerge(ctx, pull, perm, ctx.Doer) if err != nil { ctx.ServerError("IsUserAllowedToMerge", err) return @@ -1818,6 +1818,8 @@ func ViewIssue(ctx *context.Context) { } } + ctx.Data["AllowMerge"] = allowMerge + prUnit, err := repo.GetUnit(ctx, unit.TypePullRequests) if err != nil { ctx.ServerError("GetUnit", err) @@ -1927,7 +1929,7 @@ func ViewIssue(ctx *context.Context) { if pull.CanAutoMerge() || pull.IsWorkInProgress(ctx) || pull.IsChecking() { return false } - if (ctx.Doer.IsAdmin || ctx.Repo.IsAdmin()) && prConfig.AllowManualMerge { + if allowMerge && prConfig.AllowManualMerge { return true } diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index 2fed5848d5b13..e06404376ceb6 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -263,7 +263,7 @@ }, { 'name': 'manually-merged', - 'allowed': {{and $prUnit.PullRequestsConfig.AllowManualMerge $.IsRepoAdmin}}, + 'allowed': {{$prUnit.PullRequestsConfig.AllowManualMerge}}, 'textDoMerge': {{ctx.Locale.Tr "repo.pulls.merge_manually"}}, 'hideMergeMessageTexts': true, 'hideAutoMerge': true, @@ -349,13 +349,13 @@ {{end}}{{/* end if: pull request status */}} {{/* - Manually Merged is not a well-known feature, it helps repo admins to mark a non-mergeable PR (already merged, conflicted) as merged + Manually Merged is not a well-known feature, it is used to mark a non-mergeable PR (already merged, conflicted) as merged To test it: * Enable "Manually Merged" feature in the Repository Settings * Create a pull request, either: * - Merge the pull request branch locally and push the merged commit to Gitea * - Make some conflicts between the base branch and the pull request branch - * Then the Manually Merged form will be shown to repo admin users + * Then the Manually Merged form will be shown in the merge form */}} {{if and $.StillCanManualMerge (not $showGeneralMergeForm)}}
From 0a710133cdb0d1970e8b7392d259b8c0b68896f4 Mon Sep 17 00:00:00 2001 From: Chongyi Zheng Date: Mon, 30 Oct 2023 03:56:43 -0400 Subject: [PATCH 02/10] Bump workflows in github actions (#27836) All major version upgrades are related to using Node v20 as default runtime --- .github/workflows/cron-licenses.yml | 2 +- .github/workflows/cron-translations.yml | 2 +- .github/workflows/pull-compliance.yml | 6 +++--- .github/workflows/pull-docker-dryrun.yml | 8 +++---- .github/workflows/pull-e2e-tests.yml | 2 +- .github/workflows/release-nightly.yml | 22 +++++++++---------- .github/workflows/release-tag-rc.yml | 22 +++++++++---------- .github/workflows/release-tag-version.yml | 26 +++++++++++------------ 8 files changed, 45 insertions(+), 45 deletions(-) diff --git a/.github/workflows/cron-licenses.yml b/.github/workflows/cron-licenses.yml index 0fbcbf603d8fd..6ef5813a64fc7 100644 --- a/.github/workflows/cron-licenses.yml +++ b/.github/workflows/cron-licenses.yml @@ -18,7 +18,7 @@ jobs: - run: make generate-license generate-gitignore timeout-minutes: 40 - name: push translations to repo - uses: appleboy/git-push-action@v0.0.2 + uses: appleboy/git-push-action@v0.0.3 with: author_email: "teabot@gitea.io" author_name: GiteaBot diff --git a/.github/workflows/cron-translations.yml b/.github/workflows/cron-translations.yml index b0effdee9d6a2..390aae7c07951 100644 --- a/.github/workflows/cron-translations.yml +++ b/.github/workflows/cron-translations.yml @@ -22,7 +22,7 @@ jobs: - name: update locales run: ./build/update-locales.sh - name: push translations to repo - uses: appleboy/git-push-action@v0.0.2 + uses: appleboy/git-push-action@v0.0.3 with: author_email: "teabot@gitea.io" author_name: GiteaBot diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index bf9236b093f98..6977dc32b2917 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -58,7 +58,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend @@ -115,7 +115,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend @@ -162,7 +162,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend diff --git a/.github/workflows/pull-docker-dryrun.yml b/.github/workflows/pull-docker-dryrun.yml index 61f1fd5632e11..f74277de671bf 100644 --- a/.github/workflows/pull-docker-dryrun.yml +++ b/.github/workflows/pull-docker-dryrun.yml @@ -16,8 +16,8 @@ jobs: needs: files-changed runs-on: ubuntu-latest steps: - - uses: docker/setup-buildx-action@v2 - - uses: docker/build-push-action@v4 + - uses: docker/setup-buildx-action@v3 + - uses: docker/build-push-action@v5 with: push: false tags: gitea/gitea:linux-amd64 @@ -27,8 +27,8 @@ jobs: needs: files-changed runs-on: ubuntu-latest steps: - - uses: docker/setup-buildx-action@v2 - - uses: docker/build-push-action@v4 + - uses: docker/setup-buildx-action@v3 + - uses: docker/build-push-action@v5 with: push: false file: Dockerfile.rootless diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index 357ccb48be7f9..540263788d46a 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -21,7 +21,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend frontend deps-backend diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index b70a65c070e97..ef1e63df2ffc0 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -2,7 +2,7 @@ name: release-nightly on: push: - branches: [ main, release/v* ] + branches: [main, release/v*] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -22,7 +22,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend deps-backend @@ -32,7 +32,7 @@ jobs: TAGS: bindata sqlite sqlite_unlock_notify - name: import gpg key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.GPGSIGN_KEY }} passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }} @@ -68,8 +68,8 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Get cleaned branch name id: clean_name run: | @@ -81,14 +81,14 @@ jobs: REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//') echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT" - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: fetch go modules run: make vendor - name: build rootful docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -105,8 +105,8 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Get cleaned branch name id: clean_name run: | @@ -118,14 +118,14 @@ jobs: REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//') echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT" - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: fetch go modules run: make vendor - name: build rootless docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/release-tag-rc.yml b/.github/workflows/release-tag-rc.yml index 06b21db4db72c..861179d9c8652 100644 --- a/.github/workflows/release-tag-rc.yml +++ b/.github/workflows/release-tag-rc.yml @@ -3,7 +3,7 @@ name: release-tag-rc on: push: tags: - - 'v1*-rc*' + - "v1*-rc*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -21,7 +21,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend deps-backend @@ -31,7 +31,7 @@ jobs: TAGS: bindata sqlite sqlite_unlock_notify - name: import gpg key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.GPGSIGN_KEY }} passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }} @@ -68,8 +68,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -78,12 +78,12 @@ jobs: tags: | type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootful docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -97,8 +97,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -110,12 +110,12 @@ jobs: tags: | type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootless docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/release-tag-version.yml b/.github/workflows/release-tag-version.yml index f85f00289412a..c3fce7e2a7c58 100644 --- a/.github/workflows/release-tag-version.yml +++ b/.github/workflows/release-tag-version.yml @@ -3,9 +3,9 @@ name: release-tag-version on: push: tags: - - 'v1.*' - - '!v1*-rc*' - - '!v1*-dev' + - "v1.*" + - "!v1*-rc*" + - "!v1*-dev" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -23,7 +23,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend deps-backend @@ -33,7 +33,7 @@ jobs: TAGS: bindata sqlite sqlite_unlock_notify - name: import gpg key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.GPGSIGN_KEY }} passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }} @@ -70,8 +70,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -87,12 +87,12 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootful docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -106,8 +106,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -126,12 +126,12 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootless docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 From c8602a8dfa05f653e7de8ed2e677c8967b8688f5 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Mon, 30 Oct 2023 09:39:29 +0100 Subject: [PATCH 03/10] Add Index to pull_auto_merge.doer_id (#27811) Reported at https://codeberg.org/forgejo/forgejo/issues/1677 This column is used by [deleteUser](https://github.com/go-gitea/gitea/blob/f089be91da44ee3e85fbe326a204c7c8a5df3d31/services/user/delete.go#L90). Note: This PR contains a Migration, so we can't backport it to 1.21. --- models/migrations/migrations.go | 2 ++ models/migrations/v1_22/v282.go | 16 ++++++++++++++++ models/pull/automerge.go | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 models/migrations/v1_22/v282.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 4a06cdc73a3ac..28e3be503b299 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -548,6 +548,8 @@ var migrations = []Migration{ NewMigration("Rename user themes", v1_22.RenameUserThemes), // v281 -> v282 NewMigration("Add auth_token table", v1_22.CreateAuthTokenTable), + // v282 -> v283 + NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_22/v282.go b/models/migrations/v1_22/v282.go new file mode 100644 index 0000000000000..baad9e09168bd --- /dev/null +++ b/models/migrations/v1_22/v282.go @@ -0,0 +1,16 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "xorm.io/xorm" +) + +func AddIndexToPullAutoMergeDoerID(x *xorm.Engine) error { + type PullAutoMerge struct { + DoerID int64 `xorm:"INDEX NOT NULL"` + } + + return x.Sync(&PullAutoMerge{}) +} diff --git a/models/pull/automerge.go b/models/pull/automerge.go index f68fb7c681e78..f69fcb60d16ca 100644 --- a/models/pull/automerge.go +++ b/models/pull/automerge.go @@ -17,7 +17,7 @@ import ( type AutoMerge struct { ID int64 `xorm:"pk autoincr"` PullID int64 `xorm:"UNIQUE"` - DoerID int64 `xorm:"NOT NULL"` + DoerID int64 `xorm:"INDEX NOT NULL"` Doer *user_model.User `xorm:"-"` MergeStyle repo_model.MergeStyle `xorm:"varchar(30)"` Message string `xorm:"LONGTEXT"` From 0e021cd33ee3eb3d8f204bd075e2597b7ec8b391 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Mon, 30 Oct 2023 18:11:16 +0900 Subject: [PATCH 04/10] Fix display member unit in the menu bar if there are no hidden members in public org (#27795) Follow #26363. I missed that org templates also using `templates/user/overview/header.tmpl`. You can confirm this problem in https://gitea.com/gitea/-/projects with anonymous access. Before: (no login) ![image](https://github.com/go-gitea/gitea/assets/18380374/e285565c-ca65-4b18-9ff7-434c6367c13a) After: ![image](https://github.com/go-gitea/gitea/assets/18380374/81e7532a-c458-4552-8d75-6896538e42cb) --- templates/user/overview/header.tmpl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/user/overview/header.tmpl b/templates/user/overview/header.tmpl index 69a4e9a8565a8..9b6458474e5aa 100644 --- a/templates/user/overview/header.tmpl +++ b/templates/user/overview/header.tmpl @@ -27,14 +27,14 @@ {{end}} {{if .ContextUser.IsOrganization}} - {{if .IsOrganizationMember}} - + {{if .NumMembers}} + {{svg "octicon-person"}} {{ctx.Locale.Tr "org.members"}} - {{if .NumMembers}} -
{{.NumMembers}}
- {{end}} +
{{.NumMembers}}
- + {{end}} + {{if .IsOrganizationMember}} + {{svg "octicon-people"}} {{ctx.Locale.Tr "org.teams"}} {{if .NumTeams}}
{{.NumTeams}}
From e5f19dd317cba78b870f9ec6c6af181d16a30c7e Mon Sep 17 00:00:00 2001 From: Denys Konovalov Date: Mon, 30 Oct 2023 10:53:16 +0100 Subject: [PATCH 05/10] Always use whole user name as link (#27815) Starting from #25790 this shared template only linked the username of the user if both display name and username were shown. I experienced myself always trying to click on the display name - I think it is annoying for others too. After: ![grafik](https://github.com/go-gitea/gitea/assets/47871822/a0e82127-b773-4ca4-890f-d18422a7bef2) ![grafik](https://github.com/go-gitea/gitea/assets/47871822/79efcf93-2f50-4fc4-ba15-afc6174be48c) --- templates/shared/user/name.tmpl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/templates/shared/user/name.tmpl b/templates/shared/user/name.tmpl index 343c76240748f..896349fdf8b80 100644 --- a/templates/shared/user/name.tmpl +++ b/templates/shared/user/name.tmpl @@ -1,5 +1 @@ -{{if .FullName}} - {{.FullName}} (
{{.Name}}) -{{else}} - {{.Name}} -{{end}} +{{.Name}}{{if .FullName}} ({{.FullName}}){{end}} From ec0c6829d4c1096bfa0f9feb52b87b70fba014ea Mon Sep 17 00:00:00 2001 From: FuXiaoHei Date: Mon, 30 Oct 2023 18:40:05 +0800 Subject: [PATCH 06/10] Fix/upload artifact error windows (#27802) From issue https://github.com/go-gitea/gitea/issues/27314 When act_runner in `host` mode on Windows. `upload_artifact@v3` actions use `path.join` to generate `itemPath` params when uploading artifact chunk. `itemPath` is encoded as `${artifact_name}\${artifact_path}`. It's twice query escaped from ${artifact_name}/${artifact_path} that joined by Windows slash \. **So we need convert Windows slash to linux**. In https://github.com/go-gitea/gitea/issues/27314, runner shows logs from `upload_artifact@v3` like with `%255C`: ``` [artifact-cases/test-artifact-cases] | ::error::Unexpected response. Unable to upload chunk to http://192.168.31.230:3000/api/actions_pipeline/_apis/pipelines/workflows/6/artifacts/34d628a422db9367c869d3fb36be81f5/upload?itemPath=more-files%255Css.json ``` But in gitea server at the same time, But shows `%5C` ``` 2023/10/27 19:29:51 ...eb/routing/logger.go:102:func1() [I] router: completed PUT /api/actions_pipeline/_apis/pipelines/workflows/6/artifacts/34d628a422db9367c869d3fb36be81f5/upload?itemPath=more-files%5Css.json for 192.168.31.230:55340, 400 Bad Request in 17.6ms @ :1(actions.artifactRoutes.uploadArtifact-fm) ``` I found `%255C` is escaped by `https://github.com/actions/upload-artifact/blob/main/dist/index.js#L2329`. --------- Co-authored-by: wxiaoguang --- routers/api/actions/artifacts_utils.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/routers/api/actions/artifacts_utils.go b/routers/api/actions/artifacts_utils.go index 4c939348622b7..381e7eb16ee95 100644 --- a/routers/api/actions/artifacts_utils.go +++ b/routers/api/actions/artifacts_utils.go @@ -58,7 +58,8 @@ func validateArtifactHash(ctx *ArtifactContext, artifactName string) bool { func parseArtifactItemPath(ctx *ArtifactContext) (string, string, bool) { // itemPath is generated from upload-artifact action // it's formatted as {artifact_name}/{artfict_path_in_runner} - itemPath := util.PathJoinRel(ctx.Req.URL.Query().Get("itemPath")) + // act_runner in host mode on Windows, itemPath is joined by Windows slash '\' + itemPath := util.PathJoinRelX(ctx.Req.URL.Query().Get("itemPath")) artifactName := strings.Split(itemPath, "/")[0] artifactPath := strings.TrimPrefix(itemPath, artifactName+"/") if !validateArtifactHash(ctx, artifactName) { From a18ecaed61365ec8d6688631ab2febd211bd2fe0 Mon Sep 17 00:00:00 2001 From: nodiscc Date: Mon, 30 Oct 2023 23:28:02 +0000 Subject: [PATCH 07/10] doc: actions/act-runner: document obtaining a runner registration token from gitea CLI (#27845) --- docs/content/usage/actions/act-runner.en-us.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/content/usage/actions/act-runner.en-us.md b/docs/content/usage/actions/act-runner.en-us.md index e2915be365149..1cb19e6bb0f1d 100644 --- a/docs/content/usage/actions/act-runner.en-us.md +++ b/docs/content/usage/actions/act-runner.en-us.md @@ -114,6 +114,12 @@ If you cannot see the settings page, please make sure that you have the right pe The format of the registration token is a random string `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`. +A registration token can also be obtained from the gitea [command-line interface](../../../administration/command-line.en-us.md#actions-generate-runner-token): + +``` +gitea --config /etc/gitea/app.ini actions generate-runner-token +``` + ### Register the runner The act runner can be registered by running the following command: From 6ca234a35643608639375d83b9e878ee986280c3 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 31 Oct 2023 11:31:09 +0800 Subject: [PATCH 08/10] Fix wrong relative path on obtain token from command line (#27850) Caused by #27845 --- docs/content/usage/actions/act-runner.en-us.md | 2 +- docs/content/usage/actions/act-runner.zh-cn.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/content/usage/actions/act-runner.en-us.md b/docs/content/usage/actions/act-runner.en-us.md index 1cb19e6bb0f1d..33813f5910d62 100644 --- a/docs/content/usage/actions/act-runner.en-us.md +++ b/docs/content/usage/actions/act-runner.en-us.md @@ -114,7 +114,7 @@ If you cannot see the settings page, please make sure that you have the right pe The format of the registration token is a random string `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`. -A registration token can also be obtained from the gitea [command-line interface](../../../administration/command-line.en-us.md#actions-generate-runner-token): +A registration token can also be obtained from the gitea [command-line interface](../../administration/command-line.en-us.md#actions-generate-runner-token): ``` gitea --config /etc/gitea/app.ini actions generate-runner-token diff --git a/docs/content/usage/actions/act-runner.zh-cn.md b/docs/content/usage/actions/act-runner.zh-cn.md index 11b69960f78af..39d5c238c7929 100644 --- a/docs/content/usage/actions/act-runner.zh-cn.md +++ b/docs/content/usage/actions/act-runner.zh-cn.md @@ -113,6 +113,8 @@ Runner级别决定了从哪里获取注册令牌。 注册令牌的格式是一个随机字符串 `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`。 +注册令牌也可以通过 Gitea 的 [命令行](../../administration/command-line.en-us.md#actions-generate-runner-token) 获得: + ### 注册Runner 可以通过运行以下命令来注册Act Runner: From 9106514e516f1e75ae539f3cd2f3a794c7d2c50a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Gomond Date: Tue, 31 Oct 2023 04:46:09 +0100 Subject: [PATCH 09/10] Add user secrets API integration tests (#27832) Adds the missing user secrets API integration tests so #27829 does not happen again --- tests/integration/api_user_secrets_test.go | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tests/integration/api_user_secrets_test.go diff --git a/tests/integration/api_user_secrets_test.go b/tests/integration/api_user_secrets_test.go new file mode 100644 index 0000000000000..5909f4b831541 --- /dev/null +++ b/tests/integration/api_user_secrets_test.go @@ -0,0 +1,98 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "fmt" + "net/http" + "testing" + + auth_model "code.gitea.io/gitea/models/auth" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/tests" +) + +func TestAPIUserSecrets(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user1") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + + t.Run("Create", func(t *testing.T) { + cases := []struct { + Name string + ExpectedStatus int + }{ + { + Name: "", + ExpectedStatus: http.StatusNotFound, + }, + { + Name: "-", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "_", + ExpectedStatus: http.StatusCreated, + }, + { + Name: "secret", + ExpectedStatus: http.StatusCreated, + }, + { + Name: "2secret", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "GITEA_secret", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "GITHUB_secret", + ExpectedStatus: http.StatusBadRequest, + }, + } + + for _, c := range cases { + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/user/actions/secrets/%s?token=%s", c.Name, token), api.CreateOrUpdateSecretOption{ + Data: "data", + }) + MakeRequest(t, req, c.ExpectedStatus) + } + }) + + t.Run("Update", func(t *testing.T) { + name := "update_secret" + url := fmt.Sprintf("/api/v1/user/actions/secrets/%s?token=%s", name, token) + + req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ + Data: "initial", + }) + MakeRequest(t, req, http.StatusCreated) + + req = NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ + Data: "changed", + }) + MakeRequest(t, req, http.StatusNoContent) + }) + + t.Run("Delete", func(t *testing.T) { + name := "delete_secret" + url := fmt.Sprintf("/api/v1/user/actions/secrets/%s?token=%s", name, token) + + req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ + Data: "initial", + }) + MakeRequest(t, req, http.StatusCreated) + + req = NewRequest(t, "DELETE", url) + MakeRequest(t, req, http.StatusNoContent) + + req = NewRequest(t, "DELETE", url) + MakeRequest(t, req, http.StatusNotFound) + + req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/actions/secrets/000?token=%s", token)) + MakeRequest(t, req, http.StatusBadRequest) + }) +} From 16d15ce087cd4b9ddf91f6acff7eacac24e6aac5 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 31 Oct 2023 12:43:38 +0800 Subject: [PATCH 10/10] Fix package webhook (#27839) Fix #23742 --------- Co-authored-by: KN4CK3R --- modules/structs/package.go | 1 + services/convert/package.go | 1 + services/webhook/dingtalk.go | 6 ++++++ services/webhook/discord.go | 6 ++++++ services/webhook/feishu.go | 8 +++++++- services/webhook/general.go | 18 ++++++++++++++++++ services/webhook/matrix.go | 15 +++++++++++++++ services/webhook/msteams.go | 14 ++++++++++++++ services/webhook/packagist.go | 4 ++++ services/webhook/payloader.go | 3 +++ services/webhook/slack.go | 6 ++++++ services/webhook/telegram.go | 6 ++++++ services/webhook/wechatwork.go | 6 ++++++ templates/swagger/v1_json.tmpl | 4 ++++ 14 files changed, 97 insertions(+), 1 deletion(-) diff --git a/modules/structs/package.go b/modules/structs/package.go index 0059535bea800..a9a9429de2d3a 100644 --- a/modules/structs/package.go +++ b/modules/structs/package.go @@ -16,6 +16,7 @@ type Package struct { Type string `json:"type"` Name string `json:"name"` Version string `json:"version"` + HTMLURL string `json:"html_url"` // swagger:strfmt date-time CreatedAt time.Time `json:"created_at"` } diff --git a/services/convert/package.go b/services/convert/package.go index 276856594bb4c..e90ce8a00f848 100644 --- a/services/convert/package.go +++ b/services/convert/package.go @@ -35,6 +35,7 @@ func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_m Name: pd.Package.Name, Version: pd.Version.Version, CreatedAt: pd.Version.CreatedUnix.AsTime(), + HTMLURL: pd.FullWebLink(), }, nil } diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index c6fbe2f07656e..d615e7254f874 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -173,6 +173,12 @@ func (d *DingtalkPayload) Release(p *api.ReleasePayload) (api.Payloader, error) return createDingtalkPayload(text, text, "view release", p.Release.HTMLURL), nil } +func (d *DingtalkPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true) + + return createDingtalkPayload(text, text, "view package", p.Package.HTMLURL), nil +} + func createDingtalkPayload(title, text, singleTitle, singleURL string) *DingtalkPayload { return &DingtalkPayload{ MsgType: "actionCard", diff --git a/services/webhook/discord.go b/services/webhook/discord.go index b22bb4f91210b..e2ac1410b8af2 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -256,6 +256,12 @@ func (d *DiscordPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { return d.createPayload(p.Sender, text, p.Release.Note, p.Release.HTMLURL, color), nil } +func (d *DiscordPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, color := getPackagePayloadInfo(p, noneLinkFormatter, false) + + return d.createPayload(p.Sender, text, "", p.Package.HTMLURL, color), nil +} + // GetDiscordPayload converts a discord webhook into a DiscordPayload func GetDiscordPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) { s := new(DiscordPayload) diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go index 089f51952fd78..556443e70b7e4 100644 --- a/services/webhook/feishu.go +++ b/services/webhook/feishu.go @@ -16,7 +16,7 @@ import ( type ( // FeishuPayload represents FeishuPayload struct { - MsgType string `json:"msg_type"` // text / post / image / share_chat / interactive + MsgType string `json:"msg_type"` // text / post / image / share_chat / interactive / file /audio / media Content struct { Text string `json:"text"` } `json:"content"` @@ -175,6 +175,12 @@ func (f *FeishuPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { return newFeishuTextPayload(text), nil } +func (f *FeishuPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true) + + return newFeishuTextPayload(text), nil +} + // GetFeishuPayload converts a ding talk webhook into a FeishuPayload func GetFeishuPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(FeishuPayload), p, event) diff --git a/services/webhook/general.go b/services/webhook/general.go index 986467bc99dba..69b944f4bd5e6 100644 --- a/services/webhook/general.go +++ b/services/webhook/general.go @@ -293,6 +293,24 @@ func getIssueCommentPayloadInfo(p *api.IssueCommentPayload, linkFormatter linkFo return text, issueTitle, color } +func getPackagePayloadInfo(p *api.PackagePayload, linkFormatter linkFormatter, withSender bool) (text string, color int) { + refLink := linkFormatter(p.Package.HTMLURL, p.Package.Name+":"+p.Package.Version) + + switch p.Action { + case api.HookPackageCreated: + text = fmt.Sprintf("Package created: %s", refLink) + color = greenColor + case api.HookPackageDeleted: + text = fmt.Sprintf("Package deleted: %s", refLink) + color = redColor + } + if withSender { + text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + } + + return text, color +} + // ToHook convert models.Webhook to api.Hook // This function is not part of the convert package to prevent an import cycle func ToHook(repoLink string, w *webhook_model.Webhook) (*api.Hook, error) { diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index a7f57f97b6a42..ab7e6b72c25f1 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -210,6 +210,21 @@ func (m *MatrixPayload) Repository(p *api.RepositoryPayload) (api.Payloader, err return getMatrixPayload(text, nil, m.MsgType), nil } +func (m *MatrixPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + senderLink := MatrixLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) + repoLink := MatrixLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName) + var text string + + switch p.Action { + case api.HookPackageCreated: + text = fmt.Sprintf("[%s] Package published by %s", repoLink, senderLink) + case api.HookPackageDeleted: + text = fmt.Sprintf("[%s] Package deleted by %s", repoLink, senderLink) + } + + return getMatrixPayload(text, nil, m.MsgType), nil +} + // GetMatrixPayload converts a Matrix webhook into a MatrixPayload func GetMatrixPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) { s := new(MatrixPayload) diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index dfc1c682895ef..f58da3fe1cd6f 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -296,6 +296,20 @@ func (m *MSTeamsPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { ), nil } +func (m *MSTeamsPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + title, color := getPackagePayloadInfo(p, noneLinkFormatter, false) + + return createMSTeamsPayload( + p.Repository, + p.Sender, + title, + "", + p.Package.HTMLURL, + color, + &MSTeamsFact{"Package:", p.Package.Name}, + ), nil +} + // GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload func GetMSTeamsPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(MSTeamsPayload), p, event) diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go index e47e7d32850f4..714a4c076ef17 100644 --- a/services/webhook/packagist.go +++ b/services/webhook/packagist.go @@ -104,6 +104,10 @@ func (f *PackagistPayload) Release(_ *api.ReleasePayload) (api.Payloader, error) return nil, nil } +func (f *PackagistPayload) Package(_ *api.PackagePayload) (api.Payloader, error) { + return nil, nil +} + // GetPackagistPayload converts a packagist webhook into a PackagistPayload func GetPackagistPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) { s := new(PackagistPayload) diff --git a/services/webhook/payloader.go b/services/webhook/payloader.go index d53e65fa5ee47..bd482c04ead4f 100644 --- a/services/webhook/payloader.go +++ b/services/webhook/payloader.go @@ -22,6 +22,7 @@ type PayloadConvertor interface { Repository(*api.RepositoryPayload) (api.Payloader, error) Release(*api.ReleasePayload) (api.Payloader, error) Wiki(*api.WikiPayload) (api.Payloader, error) + Package(*api.PackagePayload) (api.Payloader, error) } func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_module.HookEventType) (api.Payloader, error) { @@ -53,6 +54,8 @@ func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_module. return s.Release(p.(*api.ReleasePayload)) case webhook_module.HookEventWiki: return s.Wiki(p.(*api.WikiPayload)) + case webhook_module.HookEventPackage: + return s.Package(p.(*api.PackagePayload)) } return s, nil } diff --git a/services/webhook/slack.go b/services/webhook/slack.go index 75079d0fdf158..ac27b5bc71bcd 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -171,6 +171,12 @@ func (s *SlackPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { return s.createPayload(text, nil), nil } +func (s *SlackPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, SlackLinkFormatter, true) + + return s.createPayload(text, nil), nil +} + // Push implements PayloadConvertor Push method func (s *SlackPayload) Push(p *api.PushPayload) (api.Payloader, error) { // n new commits diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index ea7e8185defdd..1bdc74e183a81 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -186,6 +186,12 @@ func (t *TelegramPayload) Release(p *api.ReleasePayload) (api.Payloader, error) return createTelegramPayload(text), nil } +func (t *TelegramPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, htmlLinkFormatter, true) + + return createTelegramPayload(text), nil +} + // GetTelegramPayload converts a telegram webhook into a TelegramPayload func GetTelegramPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(TelegramPayload), p, event) diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go index a7680f1c67112..80245c7e77333 100644 --- a/services/webhook/wechatwork.go +++ b/services/webhook/wechatwork.go @@ -179,6 +179,12 @@ func (f *WechatworkPayload) Release(p *api.ReleasePayload) (api.Payloader, error return newWechatworkMarkdownPayload(text), nil } +func (f *WechatworkPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true) + + return newWechatworkMarkdownPayload(text), nil +} + // GetWechatworkPayload GetWechatworkPayload converts a ding talk webhook into a WechatworkPayload func GetWechatworkPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(WechatworkPayload), p, event) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 2389ec3beee33..75a45dc68ac56 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -21123,6 +21123,10 @@ "creator": { "$ref": "#/definitions/User" }, + "html_url": { + "type": "string", + "x-go-name": "HTMLURL" + }, "id": { "type": "integer", "format": "int64",