From 4341f19c2167bef3cab48b576a2870c2f69f9324 Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 22 Jan 2026 16:19:16 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9Adelete?= =?UTF-8?q?=E5=88=86=E6=94=AF=E5=92=8C=E6=A0=87=E7=AD=BE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/projects/branches_controller.rb | 23 +++++++++++++++++-- .../api/v1/projects/tags_controller.rb | 11 ++++++++- .../v1/projects/branches/delete_service.rb | 2 +- .../api/v1/projects/tags/delete_service.rb | 2 +- config/routes/api.rb | 7 +++++- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/projects/branches_controller.rb b/app/controllers/api/v1/projects/branches_controller.rb index d6ce5d2cf..6003c3005 100644 --- a/app/controllers/api/v1/projects/branches_controller.rb +++ b/app/controllers/api/v1/projects/branches_controller.rb @@ -32,16 +32,35 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController @result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token) end - before_action :require_operate_above, only: [:create, :destroy, :restore] + before_action :require_operate_above, only: [:create, :delete, :destroy, :restore] def create @result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token) @project.update_column(:updated_on, Time.now) end + def delete + @result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:branch_name], current_user&.gitea_token) + if @result_object + @project.update_column(:updated_on, Time.now) + # 有开启的pr需要一同关闭 + # 1、删除本仓库中存在未关闭的pr,即本仓库分支1->分支2 + # 2、如果是fork仓库,考虑删除主仓库中存在未关闭的pr,即本仓库:分支1->主:分支2,同时分两种删除:1删除本仓库分支1,2删除主仓库分支2 + close_pull_requests_by(@project, params[:branch_name]) + if @project.forked_from_project_id.present? + # fork项目中删除分支 + close_pull_requests_by(@project.fork_project, params[:branch_name]) + end + + return render_ok + else + return render_error('删除分支失败!') + end + end + def destroy @name = params[:name].include?('.json') ? params[:name][0..-6] : params[:name] - @result_object = Api::V1::Projects::Branches::DeleteService.call(@project, URI.escape(Base64.decode64(@name)), current_user&.gitea_token) + @result_object = Api::V1::Projects::Branches::DeleteService.call(@project, Base64.decode64(@name), current_user&.gitea_token) if @result_object @project.update_column(:updated_on, Time.now) # 有开启的pr需要一同关闭 diff --git a/app/controllers/api/v1/projects/tags_controller.rb b/app/controllers/api/v1/projects/tags_controller.rb index 32116aef2..88de00d61 100644 --- a/app/controllers/api/v1/projects/tags_controller.rb +++ b/app/controllers/api/v1/projects/tags_controller.rb @@ -11,7 +11,7 @@ class Api::V1::Projects::TagsController < Api::V1::BaseController @result_object = Api::V1::Projects::Tags::GetService.call(@project, Base64.decode64(@name), current_user&.gitea_token) end - before_action :require_operate_above, only: [:create, :destroy] + before_action :require_operate_above, only: [:create, :delete, :destroy] def create @result_object = Api::V1::Projects::Tags::CreateService.call(@project, tag_params, current_user&.gitea_token) @@ -19,6 +19,15 @@ class Api::V1::Projects::TagsController < Api::V1::BaseController @project.update_column(:updated_on, Time.now) end + def delete + @result_object = Api::V1::Projects::Tags::DeleteService.call(@project, params[:branch_name], current_user&.gitea_token) + if @result_object + return render_ok + else + return render_error('删除标签失败!') + end + end + def destroy @name = params[:name].include?('.json') ? params[:name][0..-6] : params[:name] @result_object = Api::V1::Projects::Tags::DeleteService.call(@project, Base64.decode64(@name), current_user&.gitea_token) diff --git a/app/services/api/v1/projects/branches/delete_service.rb b/app/services/api/v1/projects/branches/delete_service.rb index 341079273..47520d3be 100644 --- a/app/services/api/v1/projects/branches/delete_service.rb +++ b/app/services/api/v1/projects/branches/delete_service.rb @@ -32,7 +32,7 @@ class Api::V1::Projects::Branches::DeleteService < ApplicationService def excute_data_to_gitea begin - @gitea_data = $gitea_client.delete_repos_branches_by_owner_repo_branch(owner, repo, CGI.escape(branch_name), {query: request_params}) + @gitea_data = $gitea_client.delete_repos_branches_by_owner_repo_branch(owner, repo, URI.encode(branch_name), {query: request_params}) rescue => e raise Error, '保护分支无法删除!' if e.to_s.include?("branch protected") raise Error, '删除分支失败!' diff --git a/app/services/api/v1/projects/tags/delete_service.rb b/app/services/api/v1/projects/tags/delete_service.rb index 8f898bf1a..c5f3c375d 100644 --- a/app/services/api/v1/projects/tags/delete_service.rb +++ b/app/services/api/v1/projects/tags/delete_service.rb @@ -32,7 +32,7 @@ class Api::V1::Projects::Tags::DeleteService < ApplicationService def excute_data_to_gitea begin - @gitea_data = $gitea_client.delete_repos_tags_by_owner_repo_tag(owner, repo, CGI.escape(tag_name), {query: request_params}) + @gitea_data = $gitea_client.delete_repos_tags_by_owner_repo_tag(owner, repo, URI.encode(tag_name), {query: request_params}) rescue => e raise Error, '请先删除发行版!' if e.to_s.include?("409") raise Error, '删除标签失败!' diff --git a/config/routes/api.rb b/config/routes/api.rb index 2b0d070cb..b33d68af0 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -235,12 +235,17 @@ defaults format: :json do get :github get :all post :restore + post :delete patch :update_default_branch end end match 'branches/*name', to: "branches#destroy", via: :all, constraints: { name: /[^\/]+/ } - resources :tags, param: :name, only: [:index, :create] + resources :tags, param: :name, only: [:index, :create] do + collection do + post :delete + end + end delete 'tags/*name', to: "tags#destroy", via: :all, constraints: { name: /[^\/]+/ } get 'tags/*name', to: "tags#show", via: :all, constraints: { name: /[^\/]+/ } get '/compare/:base...:head/files' => 'compare#files', :constraints => { base: /.+/, head: /.+/ } From 0ea1a843da787f98612bb1a41de115fd2ca0e8b5 Mon Sep 17 00:00:00 2001 From: yystopf Date: Thu, 22 Jan 2026 16:25:28 +0800 Subject: [PATCH 02/10] fixed: branch_name to tag_name --- app/controllers/api/v1/projects/tags_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/projects/tags_controller.rb b/app/controllers/api/v1/projects/tags_controller.rb index 88de00d61..0fb860715 100644 --- a/app/controllers/api/v1/projects/tags_controller.rb +++ b/app/controllers/api/v1/projects/tags_controller.rb @@ -20,7 +20,7 @@ class Api::V1::Projects::TagsController < Api::V1::BaseController end def delete - @result_object = Api::V1::Projects::Tags::DeleteService.call(@project, params[:branch_name], current_user&.gitea_token) + @result_object = Api::V1::Projects::Tags::DeleteService.call(@project, params[:tag_name], current_user&.gitea_token) if @result_object return render_ok else From a8ec291050efc6e5ae1c3516d6e3487255ba5168 Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 23 Jan 2026 08:50:19 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E5=88=86?= =?UTF-8?q?=E6=94=AF=E5=90=8D=E4=B8=8E=E6=A0=87=E7=AD=BE=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E7=9B=B8=E5=90=8C=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/projects/branches/create_service.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/services/api/v1/projects/branches/create_service.rb b/app/services/api/v1/projects/branches/create_service.rb index 39964e402..165bafe8e 100644 --- a/app/services/api/v1/projects/branches/create_service.rb +++ b/app/services/api/v1/projects/branches/create_service.rb @@ -39,8 +39,15 @@ class Api::V1::Projects::Branches::CreateService < ApplicationService end def excute_data_to_gitea - @gitea_data = $gitea_client.post_repos_branches_by_owner_repo(owner, repo, {body: request_body.to_json, query: request_params}) rescue nil - raise Error, '创建分支失败!' unless @gitea_data.is_a?(Hash) + begin + @gitea_data = $gitea_client.post_repos_branches_by_owner_repo(owner, repo, {body: request_body.to_json, query: request_params}) + rescue Gitea::Api::ServerError => e + if e.http_code == 409 && e.to_s.include?("The branch with the same tag already exists") + raise Error, '创建分支失败,分支名称与标签名称不能相同!' + else + raise Error, '创建分支失败!' + end + end end def check_branch_exist From 47832df856da812c7b0f842515295f9f37a4a850 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jan 2026 15:09:10 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E6=9B=B4=E6=94=B9=EF=BC=9A=E7=89=B9?= =?UTF-8?q?=E6=AE=8A=E5=AD=97=E7=AC=A6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/repositories_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index a5a740de7..cca6d0536 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -83,7 +83,7 @@ class RepositoriesController < ApplicationController end def sub_entries - file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip)) + file_path_uri = URI.parse(URI.encode(params[:filepath].to_s)).gsub!("&", "%26") tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") if @project.educoder? if params[:type] === 'file' From 7759ea558c3d82e40f912f07ea389511d9422dc2 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jan 2026 15:26:36 +0800 Subject: [PATCH 05/10] =?UTF-8?q?fixed=EF=BC=9A=E4=BB=A3=E7=A0=81=E5=9B=9E?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/repositories_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index ea473d14f..fa45a1dea 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -83,7 +83,7 @@ class RepositoriesController < ApplicationController end def sub_entries - file_path_uri = URI.parse(URI.encode(params[:filepath].to_s)).gsub!("&", "%26") + file_path_uri = URI.parse(URI.encode(params[:filepath].to_s)) tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") if @project.educoder? if params[:type] === 'file' From aab613ebcef65cdbdd42e17d74da69a971ed73d6 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jan 2026 15:42:07 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E6=9B=B4=E6=94=B9=EF=BC=9A=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=8E=BB=E9=99=A4=E7=A9=BA=E6=A0=BC=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/repositories_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index fa45a1dea..ad7acc986 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -337,7 +337,7 @@ class RepositoriesController < ApplicationController # TODO 获取最新commit信息 def project_commits if params[:filepath].present? - file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip)) + file_path_uri = URI.parse(URI.encode(params[:filepath].to_s)) Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri, sha: get_ref, page: 1, limit: 1, token: @project&.owner&.gitea_token).call else From 6c56712573a7330c77158a4e7a5f9ec26a728b7f Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jan 2026 15:51:29 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E6=9B=B4=E6=94=B9=EF=BC=9A=E7=89=B9?= =?UTF-8?q?=E6=AE=8A=E5=AD=97=E7=AC=A6=E5=87=BD=E6=95=B0=E4=BD=BF=E7=94=A8?= =?UTF-8?q?uri.escape?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/projects/commits_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/projects/commits_controller.rb b/app/controllers/api/v1/projects/commits_controller.rb index b80d09750..141bbf789 100644 --- a/app/controllers/api/v1/projects/commits_controller.rb +++ b/app/controllers/api/v1/projects/commits_controller.rb @@ -12,7 +12,7 @@ class Api::V1::Projects::CommitsController < Api::V1::BaseController def files if params[:filepath].present? - @result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha_filepath(@project&.owner.login, @project&.identifier, params[:sha], CGI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}}) + @result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha_filepath(@project&.owner.login, @project&.identifier, params[:sha], URI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}}) else @result_object = $gitea_hat_client.get_repos_commits_files_by_owner_repo_sha(@project&.owner.login, @project&.identifier, params[:sha], {query: {token: current_user&.gitea_token, page: page, limit: limit}}) end From c8b80c04d6a7ac6cfe2722541b73dfe00b290594 Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jan 2026 15:53:58 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E6=9B=B4=E6=94=B9=EF=BC=9A=E7=89=B9?= =?UTF-8?q?=E6=AE=8A=E5=AD=97=E7=AC=A6=E5=87=BD=E6=95=B0=E4=BD=BF=E7=94=A8?= =?UTF-8?q?uri.escape?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/projects/actions/runs_controller.rb | 2 +- app/controllers/api/v1/projects/pulls/pulls_controller.rb | 2 +- app/controllers/repositories_controller.rb | 2 +- app/helpers/projects_helper.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/projects/actions/runs_controller.rb b/app/controllers/api/v1/projects/actions/runs_controller.rb index 474ab8d91..9119b73e4 100644 --- a/app/controllers/api/v1/projects/actions/runs_controller.rb +++ b/app/controllers/api/v1/projects/actions/runs_controller.rb @@ -51,7 +51,7 @@ class Api::V1::Projects::Actions::RunsController < Api::V1::Projects::Actions::B domain = GiteaService.gitea_config[:domain] api_url = GiteaService.gitea_config[:hat_base_url] - url = "/repos/#{@owner.login}/#{@repository.identifier}/actions/runs/#{CGI.escape(params[:run_id])}/jobs/#{CGI.escape(params[:job])}/logs" + url = "/repos/#{@owner.login}/#{@repository.identifier}/actions/runs/#{URI.escape(params[:run_id])}/jobs/#{URI.escape(params[:job])}/logs" file_path = [domain, api_url, url].join file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("?") diff --git a/app/controllers/api/v1/projects/pulls/pulls_controller.rb b/app/controllers/api/v1/projects/pulls/pulls_controller.rb index af6a36c2b..9f8db2f42 100644 --- a/app/controllers/api/v1/projects/pulls/pulls_controller.rb +++ b/app/controllers/api/v1/projects/pulls/pulls_controller.rb @@ -37,7 +37,7 @@ class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController def files if params[:filepath].present? - @result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index_filepath(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, CGI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}}) + @result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index_filepath(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, URI.escape(params[:filepath]), {query: {token: current_user&.gitea_token}}) else @result_object = $gitea_hat_client.get_repos_pulls_files_by_owner_repo_index(@project&.owner.login, @project&.identifier, @pull_request.gitea_number, {query: {isNew: "true",token: current_user&.gitea_token, page: page, limit: limit}}) end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index ad7acc986..6d1887550 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -309,7 +309,7 @@ class RepositoriesController < ApplicationController api_url = GiteaService.gitea_config[:base_url] tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") - url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}" + url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{URI.escape(params[:filepath])}?ref=#{URI.escape(params[:ref])}" file_path = [domain, api_url, url].join file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("&") diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index ed5f67212..7e511df93 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -22,7 +22,7 @@ module ProjectsHelper end def render_download_file_url(owner, repository, filepath, ref) - [base_url, "/api/#{owner&.login}/#{repository.identifier}/raw/#{CGI.escape(filepath)}?ref=#{CGI.escape(ref)}"].join + [base_url, "/api/#{owner&.login}/#{repository.identifier}/raw/#{URI.escape(filepath)}?ref=#{URI.escape(ref)}"].join end def render_http_url(project) From bf4ff93ed96c8903fba29aa65125f09f7f6f51ac Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jan 2026 16:09:15 +0800 Subject: [PATCH 09/10] =?UTF-8?q?fixed=EF=BC=9A=E4=BB=A3=E7=A0=81=E5=9B=9E?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/repositories_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 6d1887550..ad7acc986 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -309,7 +309,7 @@ class RepositoriesController < ApplicationController api_url = GiteaService.gitea_config[:base_url] tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") - url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{URI.escape(params[:filepath])}?ref=#{URI.escape(params[:ref])}" + url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}" file_path = [domain, api_url, url].join file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("&") From f77b2ae1822da356118e514fe738238f01ee223b Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 28 Jan 2026 16:10:42 +0800 Subject: [PATCH 10/10] =?UTF-8?q?fixed=EF=BC=9A=E4=BB=A3=E7=A0=81=E5=9B=9E?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/projects_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 7e511df93..ed5f67212 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -22,7 +22,7 @@ module ProjectsHelper end def render_download_file_url(owner, repository, filepath, ref) - [base_url, "/api/#{owner&.login}/#{repository.identifier}/raw/#{URI.escape(filepath)}?ref=#{URI.escape(ref)}"].join + [base_url, "/api/#{owner&.login}/#{repository.identifier}/raw/#{CGI.escape(filepath)}?ref=#{CGI.escape(ref)}"].join end def render_http_url(project)