mirror of
https://github.com/go-gitea/gitea.git
synced 2024-09-01 14:56:30 +00:00
Merge remote-tracking branch 'origin/main' into xormigrate
This commit is contained in:
commit
23e81c596a
@ -26,7 +26,7 @@
|
||||
fork_id: 0
|
||||
is_template: false
|
||||
template_id: 0
|
||||
size: 7320
|
||||
size: 7597
|
||||
is_fsck_enabled: true
|
||||
close_issues_via_commit_in_any_branch: false
|
||||
|
||||
|
@ -572,6 +572,8 @@ var migrations = []*xormigrate.Migration{
|
||||
NewMigration("Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired),
|
||||
// v303 -> v304
|
||||
NewMigration("Add metadata column for comment table", v1_23.AddCommentMetaDataColumn),
|
||||
// v304 -> v305
|
||||
NewMigration("Add index for release sha1", v1_23.AddIndexForReleaseSha1),
|
||||
}
|
||||
|
||||
// EnsureUpToDate will check if the db is at the correct version
|
||||
|
@ -3,303 +3,11 @@
|
||||
|
||||
package v1_23 //nolint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
import "xorm.io/xorm"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"src.techknowlogick.com/xormigrate"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
const (
|
||||
minDBVersion = 70 // Gitea 1.5.3
|
||||
oldMigrationsCount = 230
|
||||
expectedVersion = minDBVersion + oldMigrationsCount
|
||||
)
|
||||
|
||||
var oldMigrationNames = []string{
|
||||
"add issue_dependencies",
|
||||
"protect each scratch token",
|
||||
"add review",
|
||||
"add must_change_password column for users table",
|
||||
"add approval whitelists to protected branches",
|
||||
"clear nonused data which not deleted when user was deleted",
|
||||
"add pull request rebase with merge commit",
|
||||
"add theme to users",
|
||||
"rename repo is_bare to repo is_empty",
|
||||
"add can close issues via commit in any branch",
|
||||
"add is locked to issues",
|
||||
"update U2F counter type",
|
||||
"hot fix for wrong release sha1 on release table",
|
||||
"add uploader id for table attachment",
|
||||
"add table to store original imported gpg keys",
|
||||
"hash application token",
|
||||
"add http method to webhook",
|
||||
"add avatar field to repository",
|
||||
"add commit status context field to commit_status",
|
||||
"add original author/url migration info to issues, comments, and repo ",
|
||||
"change length of some repository columns",
|
||||
"add index on owner_id of repository and type, review_id of comment",
|
||||
"remove orphaned repository index statuses",
|
||||
"add email notification enabled preference to user",
|
||||
"add enable_status_check, status_check_contexts to protected_branch",
|
||||
"add table columns for cross referencing issues",
|
||||
"delete orphaned attachments",
|
||||
"add repo_admin_change_team_access to user",
|
||||
"add original author name and id on migrated release",
|
||||
"add task table and status column for repository table",
|
||||
"update migration repositories' service type",
|
||||
"change length of some external login users columns",
|
||||
"update migration repositories' service type v2",
|
||||
"Add WhitelistDeployKeys to protected branch",
|
||||
"remove unnecessary columns from label",
|
||||
"add includes_all_repositories to teams",
|
||||
"add column `mode` to table watch",
|
||||
"Add template options to repository",
|
||||
"Add comment_id on table notification",
|
||||
"add can_create_org_repo to team",
|
||||
"change review content type to text",
|
||||
"update branch protection for can push and whitelist enable",
|
||||
"remove release attachments which repository deleted",
|
||||
"new feature: change target branch of pull requests",
|
||||
"Remove authentication credentials from stored URL",
|
||||
"add user_id prefix to existing user avatar name",
|
||||
"Extend TrackedTimes",
|
||||
"Add block on rejected reviews branch protection",
|
||||
"Add commit id and stale to reviews",
|
||||
"Fix migrated repositories' git service type",
|
||||
"Add owner_name on table repository",
|
||||
"add is_restricted column for users table",
|
||||
"Add Require Signed Commits to ProtectedBranch",
|
||||
"Add original information for reactions",
|
||||
"Add columns to user and repository",
|
||||
"Add some columns on review for migration",
|
||||
"Fix topic repository count",
|
||||
"add repository code language statistics",
|
||||
"fix merge base for pull requests",
|
||||
"remove dependencies from deleted repositories",
|
||||
"Expand webhooks for more granularity",
|
||||
"Add IsSystemWebhook column to webhooks table",
|
||||
"Add Branch Protection Protected Files Column",
|
||||
"Add EmailHash Table",
|
||||
"Refix merge base for merged pull requests",
|
||||
"Add OrgID column to Labels table",
|
||||
"Add CommitsAhead and CommitsBehind Column to PullRequest Table",
|
||||
"Add Branch Protection Block Outdated Branch",
|
||||
"Add ResolveDoerID to Comment table",
|
||||
"prepend refs/heads/ to issue refs",
|
||||
"Save detected language file size to database instead of percent",
|
||||
"Add KeepActivityPrivate to User table",
|
||||
"Ensure Repository.IsArchived is not null",
|
||||
"recalculate Stars number for all user",
|
||||
"update Matrix Webhook http method to 'PUT'",
|
||||
"Increase Language field to 50 in LanguageStats",
|
||||
"Add projects info to repository table",
|
||||
"create review for 0 review id code comments",
|
||||
"remove issue dependency comments who refer to non existing issues",
|
||||
"Add Created and Updated to Milestone table",
|
||||
"add primary key to repo_topic",
|
||||
"set default password algorithm to Argon2",
|
||||
"add TrustModel field to Repository",
|
||||
"add Team review request support",
|
||||
"add timestamps to Star, Label, Follow, Watch and Collaboration",
|
||||
"add changed_protected_files column for pull_request table",
|
||||
"fix publisher ID for tag releases",
|
||||
"ensure repo topics are up-to-date",
|
||||
"code comment replies should have the commitID of the review they are replying to",
|
||||
"update reactions constraint",
|
||||
"Add block on official review requests branch protection",
|
||||
"Convert task type from int to string",
|
||||
"Convert webhook task type from int to string",
|
||||
"Convert topic name from 25 to 50",
|
||||
"Add scope and nonce columns to oauth2_grant table",
|
||||
"Convert hook task type from char(16) to varchar(16) and trim the column",
|
||||
"Where Password is Valid with Empty String delete it",
|
||||
"Add user redirect",
|
||||
"Recreate user table to fix default values",
|
||||
"Update DeleteBranch comments to set the old_ref to the commit_sha",
|
||||
"Add Dismissed to Review table",
|
||||
"Add Sorting to ProjectBoard table",
|
||||
"Add sessions table for go-chi/session",
|
||||
"Add time_id column to Comment",
|
||||
"Create repo transfer table",
|
||||
"Fix Postgres ID Sequences broken by recreate-table",
|
||||
"Remove invalid labels from comments",
|
||||
"Delete orphaned IssueLabels",
|
||||
"Add LFS columns to Mirror",
|
||||
"Convert avatar url to text",
|
||||
"Delete credentials from past migrations",
|
||||
"Always save primary email on email address table",
|
||||
"Add issue resource index table",
|
||||
"Create PushMirror table",
|
||||
"Rename Task errors to message",
|
||||
"Add new table repo_archiver",
|
||||
"Create protected tag table",
|
||||
"Drop unneeded webhook related columns",
|
||||
"Add key is verified to gpg key",
|
||||
"Unwrap ldap.Sources",
|
||||
"Add agit flow pull request support",
|
||||
"Alter issue/comment table TEXT fields to LONGTEXT",
|
||||
"RecreateIssueResourceIndexTable to have a primary key instead of an unique index",
|
||||
"Add repo id column for attachment table",
|
||||
"Add Branch Protection Unprotected Files Column",
|
||||
"Add table commit_status_index",
|
||||
"Add Color to ProjectBoard table",
|
||||
"Add renamed_branch table",
|
||||
"Add issue content history table",
|
||||
"No-op (remote version is using AppState now)",
|
||||
"Add table app_state",
|
||||
"Drop table remote_version (if exists)",
|
||||
"Create key/value table for user settings",
|
||||
"Add Sorting to ProjectIssue table",
|
||||
"Add key is verified to ssh key",
|
||||
"Migrate to higher varchar on user struct",
|
||||
"Add authorize column to team_unit table",
|
||||
"Add webauthn table and migrate u2f data to webauthn - NO-OPED",
|
||||
"Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED",
|
||||
"Increase WebAuthentication CredentialID size to 410 - NO-OPED",
|
||||
"v208 was completely broken - remigrate",
|
||||
"Create ForeignReference table",
|
||||
"Add package tables",
|
||||
"Add allow edits from maintainers to PullRequest table",
|
||||
"Add auto merge table",
|
||||
"allow to view files in PRs",
|
||||
"No-op (Improve Action table indices v1)",
|
||||
"Alter hook_task table TEXT fields to LONGTEXT",
|
||||
"Improve Action table indices v2",
|
||||
"Add sync_on_commit column to push_mirror table",
|
||||
"Add container repository property",
|
||||
"Store WebAuthentication CredentialID as bytes and increase size to at least 1024",
|
||||
"Drop old CredentialID column",
|
||||
"Rename CredentialIDBytes column to CredentialID",
|
||||
"Add badges to users",
|
||||
"Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT",
|
||||
"Conan and generic packages do not need to be semantically versioned",
|
||||
"Create key/value table for system settings",
|
||||
"Add TeamInvite table",
|
||||
"Update counts of all open milestones",
|
||||
"Add ConfidentialClient column (default true) to OAuth2Application table",
|
||||
"Add index for hook_task",
|
||||
"Alter package_version.metadata_json to LONGTEXT",
|
||||
"Add header_authorization_encrypted column to webhook table",
|
||||
"Add package cleanup rule table",
|
||||
"Add index for access_token",
|
||||
"Create secrets table",
|
||||
"Drop ForeignReference table",
|
||||
"Add updated unix to LFSMetaObject",
|
||||
"Add scope for access_token",
|
||||
"Add actions tables",
|
||||
"Add card_type column to project table",
|
||||
"Alter gpg_key_import content TEXT field to MEDIUMTEXT",
|
||||
"Add exclusive label",
|
||||
"Add NeedApproval to actions tables",
|
||||
"Rename Webhook org_id to owner_id",
|
||||
"Add missed column owner_id for project table",
|
||||
"Fix incorrect project type",
|
||||
"Add version column to action_runner table",
|
||||
"Improve Action table indices v3",
|
||||
"Change Container Metadata",
|
||||
"Fix incorrect owner team unit access mode",
|
||||
"Fix incorrect admin team unit access mode",
|
||||
"Fix ExternalTracker and ExternalWiki accessMode in owner and admin team",
|
||||
"Add ActionTaskOutput table",
|
||||
"Add ArchivedUnix Column",
|
||||
"Add is_internal column to package",
|
||||
"Add Actions Artifact table",
|
||||
"Add PinOrder Column",
|
||||
"Convert scoped access tokens",
|
||||
"Drop custom_labels column of action_runner table",
|
||||
"Add variable table",
|
||||
"Add TriggerEvent to action_run table",
|
||||
"Add git_size and lfs_size columns to repository table",
|
||||
"Add branch table",
|
||||
"Alter Actions Artifact table",
|
||||
"Reduce commit status",
|
||||
"Add action_tasks_version table",
|
||||
"Update Action Ref",
|
||||
"Drop deleted branch table",
|
||||
"Fix PackageProperty typo",
|
||||
"Allow archiving labels",
|
||||
"Add Version to ActionRun table",
|
||||
"Add Action Schedule Table",
|
||||
"Add Actions artifacts expiration date",
|
||||
"Add ScheduleID for ActionRun",
|
||||
"Add RemoteAddress to mirrors",
|
||||
"Add Index to issue_user.issue_id",
|
||||
"Add Index to comment.dependent_issue_id",
|
||||
"Add Index to action.user_id",
|
||||
"Rename user themes",
|
||||
"Add auth_token table",
|
||||
"Add Index to pull_auto_merge.doer_id",
|
||||
"Add combined Index to issue_user.uid and issue_id",
|
||||
"Add ignore stale approval column on branch table",
|
||||
"Add PreviousDuration to ActionRun",
|
||||
"Add support for SHA256 git repositories",
|
||||
"Use Slug instead of ID for Badges",
|
||||
"Add user_blocking table",
|
||||
"Add default_wiki_branch to repository table",
|
||||
"Add PayloadVersion to HookTask",
|
||||
"Add Index to attachment.comment_id",
|
||||
"Ensure every project has exactly one default column - No Op",
|
||||
"Ensure every project has exactly one default column",
|
||||
"Add unique index for project issue table",
|
||||
"Add commit status summary table",
|
||||
"Add missing field of commit status summary table",
|
||||
"Add everyone_access_mode for repo_unit",
|
||||
"Drop wrongly created table o_auth2_application",
|
||||
"Add content version to issue and comment table",
|
||||
"Add force-push branch protection support",
|
||||
"Add skip_secondary_authorization option to oauth2 application table",
|
||||
"Add metadata column for comment table",
|
||||
}
|
||||
|
||||
// Version describes the version table. Should have only one row with id==1
|
||||
type Version struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Version int64
|
||||
}
|
||||
|
||||
func MigrateToXormigrate(x *xorm.Engine) error {
|
||||
if err := x.Sync(new(Version)); err != nil {
|
||||
return fmt.Errorf("sync: %w", err)
|
||||
}
|
||||
|
||||
currentVersion := &Version{ID: 1}
|
||||
has, err := x.Get(currentVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get: %w", err)
|
||||
} else if !has {
|
||||
// This should not happen
|
||||
return fmt.Errorf("could not get version")
|
||||
}
|
||||
|
||||
v := currentVersion.Version
|
||||
if minDBVersion > v {
|
||||
log.Fatal(`Gitea no longer supports auto-migration from your previously installed version.
|
||||
Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Downgrading Gitea's database version not supported
|
||||
if int(v-minDBVersion) > oldMigrationsCount {
|
||||
msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Gitea, you can not use the newer database for this old Gitea release (%d).", v, expectedVersion)
|
||||
msg += "\nGitea will exit to keep your database safe and unchanged. Please use the correct Gitea release, do not change the migration version manually (incorrect manual operation may lose data)."
|
||||
if !setting.IsProd {
|
||||
msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", expectedVersion)
|
||||
}
|
||||
log.Fatal("Migration Error: %s", msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// add migrations that already have been run
|
||||
for _, i := range oldMigrationNames[:v-minDBVersion] {
|
||||
if _, err := x.Insert(&xormigrate.Migration{ID: i}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Remove old version table
|
||||
return x.DropTables(new(Version))
|
||||
func AddIndexForReleaseSha1(x *xorm.Engine) error {
|
||||
type Release struct {
|
||||
Sha1 string `xorm:"INDEX VARCHAR(64)"`
|
||||
}
|
||||
return x.Sync(new(Release))
|
||||
}
|
||||
|
305
models/migrations/v1_23/v305.go
Normal file
305
models/migrations/v1_23/v305.go
Normal file
@ -0,0 +1,305 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_23 //nolint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"src.techknowlogick.com/xormigrate"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
const (
|
||||
minDBVersion = 70 // Gitea 1.5.3
|
||||
oldMigrationsCount = 230
|
||||
expectedVersion = minDBVersion + oldMigrationsCount
|
||||
)
|
||||
|
||||
var oldMigrationNames = []string{
|
||||
"add issue_dependencies",
|
||||
"protect each scratch token",
|
||||
"add review",
|
||||
"add must_change_password column for users table",
|
||||
"add approval whitelists to protected branches",
|
||||
"clear nonused data which not deleted when user was deleted",
|
||||
"add pull request rebase with merge commit",
|
||||
"add theme to users",
|
||||
"rename repo is_bare to repo is_empty",
|
||||
"add can close issues via commit in any branch",
|
||||
"add is locked to issues",
|
||||
"update U2F counter type",
|
||||
"hot fix for wrong release sha1 on release table",
|
||||
"add uploader id for table attachment",
|
||||
"add table to store original imported gpg keys",
|
||||
"hash application token",
|
||||
"add http method to webhook",
|
||||
"add avatar field to repository",
|
||||
"add commit status context field to commit_status",
|
||||
"add original author/url migration info to issues, comments, and repo ",
|
||||
"change length of some repository columns",
|
||||
"add index on owner_id of repository and type, review_id of comment",
|
||||
"remove orphaned repository index statuses",
|
||||
"add email notification enabled preference to user",
|
||||
"add enable_status_check, status_check_contexts to protected_branch",
|
||||
"add table columns for cross referencing issues",
|
||||
"delete orphaned attachments",
|
||||
"add repo_admin_change_team_access to user",
|
||||
"add original author name and id on migrated release",
|
||||
"add task table and status column for repository table",
|
||||
"update migration repositories' service type",
|
||||
"change length of some external login users columns",
|
||||
"update migration repositories' service type v2",
|
||||
"Add WhitelistDeployKeys to protected branch",
|
||||
"remove unnecessary columns from label",
|
||||
"add includes_all_repositories to teams",
|
||||
"add column `mode` to table watch",
|
||||
"Add template options to repository",
|
||||
"Add comment_id on table notification",
|
||||
"add can_create_org_repo to team",
|
||||
"change review content type to text",
|
||||
"update branch protection for can push and whitelist enable",
|
||||
"remove release attachments which repository deleted",
|
||||
"new feature: change target branch of pull requests",
|
||||
"Remove authentication credentials from stored URL",
|
||||
"add user_id prefix to existing user avatar name",
|
||||
"Extend TrackedTimes",
|
||||
"Add block on rejected reviews branch protection",
|
||||
"Add commit id and stale to reviews",
|
||||
"Fix migrated repositories' git service type",
|
||||
"Add owner_name on table repository",
|
||||
"add is_restricted column for users table",
|
||||
"Add Require Signed Commits to ProtectedBranch",
|
||||
"Add original information for reactions",
|
||||
"Add columns to user and repository",
|
||||
"Add some columns on review for migration",
|
||||
"Fix topic repository count",
|
||||
"add repository code language statistics",
|
||||
"fix merge base for pull requests",
|
||||
"remove dependencies from deleted repositories",
|
||||
"Expand webhooks for more granularity",
|
||||
"Add IsSystemWebhook column to webhooks table",
|
||||
"Add Branch Protection Protected Files Column",
|
||||
"Add EmailHash Table",
|
||||
"Refix merge base for merged pull requests",
|
||||
"Add OrgID column to Labels table",
|
||||
"Add CommitsAhead and CommitsBehind Column to PullRequest Table",
|
||||
"Add Branch Protection Block Outdated Branch",
|
||||
"Add ResolveDoerID to Comment table",
|
||||
"prepend refs/heads/ to issue refs",
|
||||
"Save detected language file size to database instead of percent",
|
||||
"Add KeepActivityPrivate to User table",
|
||||
"Ensure Repository.IsArchived is not null",
|
||||
"recalculate Stars number for all user",
|
||||
"update Matrix Webhook http method to 'PUT'",
|
||||
"Increase Language field to 50 in LanguageStats",
|
||||
"Add projects info to repository table",
|
||||
"create review for 0 review id code comments",
|
||||
"remove issue dependency comments who refer to non existing issues",
|
||||
"Add Created and Updated to Milestone table",
|
||||
"add primary key to repo_topic",
|
||||
"set default password algorithm to Argon2",
|
||||
"add TrustModel field to Repository",
|
||||
"add Team review request support",
|
||||
"add timestamps to Star, Label, Follow, Watch and Collaboration",
|
||||
"add changed_protected_files column for pull_request table",
|
||||
"fix publisher ID for tag releases",
|
||||
"ensure repo topics are up-to-date",
|
||||
"code comment replies should have the commitID of the review they are replying to",
|
||||
"update reactions constraint",
|
||||
"Add block on official review requests branch protection",
|
||||
"Convert task type from int to string",
|
||||
"Convert webhook task type from int to string",
|
||||
"Convert topic name from 25 to 50",
|
||||
"Add scope and nonce columns to oauth2_grant table",
|
||||
"Convert hook task type from char(16) to varchar(16) and trim the column",
|
||||
"Where Password is Valid with Empty String delete it",
|
||||
"Add user redirect",
|
||||
"Recreate user table to fix default values",
|
||||
"Update DeleteBranch comments to set the old_ref to the commit_sha",
|
||||
"Add Dismissed to Review table",
|
||||
"Add Sorting to ProjectBoard table",
|
||||
"Add sessions table for go-chi/session",
|
||||
"Add time_id column to Comment",
|
||||
"Create repo transfer table",
|
||||
"Fix Postgres ID Sequences broken by recreate-table",
|
||||
"Remove invalid labels from comments",
|
||||
"Delete orphaned IssueLabels",
|
||||
"Add LFS columns to Mirror",
|
||||
"Convert avatar url to text",
|
||||
"Delete credentials from past migrations",
|
||||
"Always save primary email on email address table",
|
||||
"Add issue resource index table",
|
||||
"Create PushMirror table",
|
||||
"Rename Task errors to message",
|
||||
"Add new table repo_archiver",
|
||||
"Create protected tag table",
|
||||
"Drop unneeded webhook related columns",
|
||||
"Add key is verified to gpg key",
|
||||
"Unwrap ldap.Sources",
|
||||
"Add agit flow pull request support",
|
||||
"Alter issue/comment table TEXT fields to LONGTEXT",
|
||||
"RecreateIssueResourceIndexTable to have a primary key instead of an unique index",
|
||||
"Add repo id column for attachment table",
|
||||
"Add Branch Protection Unprotected Files Column",
|
||||
"Add table commit_status_index",
|
||||
"Add Color to ProjectBoard table",
|
||||
"Add renamed_branch table",
|
||||
"Add issue content history table",
|
||||
"No-op (remote version is using AppState now)",
|
||||
"Add table app_state",
|
||||
"Drop table remote_version (if exists)",
|
||||
"Create key/value table for user settings",
|
||||
"Add Sorting to ProjectIssue table",
|
||||
"Add key is verified to ssh key",
|
||||
"Migrate to higher varchar on user struct",
|
||||
"Add authorize column to team_unit table",
|
||||
"Add webauthn table and migrate u2f data to webauthn - NO-OPED",
|
||||
"Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED",
|
||||
"Increase WebAuthentication CredentialID size to 410 - NO-OPED",
|
||||
"v208 was completely broken - remigrate",
|
||||
"Create ForeignReference table",
|
||||
"Add package tables",
|
||||
"Add allow edits from maintainers to PullRequest table",
|
||||
"Add auto merge table",
|
||||
"allow to view files in PRs",
|
||||
"No-op (Improve Action table indices v1)",
|
||||
"Alter hook_task table TEXT fields to LONGTEXT",
|
||||
"Improve Action table indices v2",
|
||||
"Add sync_on_commit column to push_mirror table",
|
||||
"Add container repository property",
|
||||
"Store WebAuthentication CredentialID as bytes and increase size to at least 1024",
|
||||
"Drop old CredentialID column",
|
||||
"Rename CredentialIDBytes column to CredentialID",
|
||||
"Add badges to users",
|
||||
"Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT",
|
||||
"Conan and generic packages do not need to be semantically versioned",
|
||||
"Create key/value table for system settings",
|
||||
"Add TeamInvite table",
|
||||
"Update counts of all open milestones",
|
||||
"Add ConfidentialClient column (default true) to OAuth2Application table",
|
||||
"Add index for hook_task",
|
||||
"Alter package_version.metadata_json to LONGTEXT",
|
||||
"Add header_authorization_encrypted column to webhook table",
|
||||
"Add package cleanup rule table",
|
||||
"Add index for access_token",
|
||||
"Create secrets table",
|
||||
"Drop ForeignReference table",
|
||||
"Add updated unix to LFSMetaObject",
|
||||
"Add scope for access_token",
|
||||
"Add actions tables",
|
||||
"Add card_type column to project table",
|
||||
"Alter gpg_key_import content TEXT field to MEDIUMTEXT",
|
||||
"Add exclusive label",
|
||||
"Add NeedApproval to actions tables",
|
||||
"Rename Webhook org_id to owner_id",
|
||||
"Add missed column owner_id for project table",
|
||||
"Fix incorrect project type",
|
||||
"Add version column to action_runner table",
|
||||
"Improve Action table indices v3",
|
||||
"Change Container Metadata",
|
||||
"Fix incorrect owner team unit access mode",
|
||||
"Fix incorrect admin team unit access mode",
|
||||
"Fix ExternalTracker and ExternalWiki accessMode in owner and admin team",
|
||||
"Add ActionTaskOutput table",
|
||||
"Add ArchivedUnix Column",
|
||||
"Add is_internal column to package",
|
||||
"Add Actions Artifact table",
|
||||
"Add PinOrder Column",
|
||||
"Convert scoped access tokens",
|
||||
"Drop custom_labels column of action_runner table",
|
||||
"Add variable table",
|
||||
"Add TriggerEvent to action_run table",
|
||||
"Add git_size and lfs_size columns to repository table",
|
||||
"Add branch table",
|
||||
"Alter Actions Artifact table",
|
||||
"Reduce commit status",
|
||||
"Add action_tasks_version table",
|
||||
"Update Action Ref",
|
||||
"Drop deleted branch table",
|
||||
"Fix PackageProperty typo",
|
||||
"Allow archiving labels",
|
||||
"Add Version to ActionRun table",
|
||||
"Add Action Schedule Table",
|
||||
"Add Actions artifacts expiration date",
|
||||
"Add ScheduleID for ActionRun",
|
||||
"Add RemoteAddress to mirrors",
|
||||
"Add Index to issue_user.issue_id",
|
||||
"Add Index to comment.dependent_issue_id",
|
||||
"Add Index to action.user_id",
|
||||
"Rename user themes",
|
||||
"Add auth_token table",
|
||||
"Add Index to pull_auto_merge.doer_id",
|
||||
"Add combined Index to issue_user.uid and issue_id",
|
||||
"Add ignore stale approval column on branch table",
|
||||
"Add PreviousDuration to ActionRun",
|
||||
"Add support for SHA256 git repositories",
|
||||
"Use Slug instead of ID for Badges",
|
||||
"Add user_blocking table",
|
||||
"Add default_wiki_branch to repository table",
|
||||
"Add PayloadVersion to HookTask",
|
||||
"Add Index to attachment.comment_id",
|
||||
"Ensure every project has exactly one default column - No Op",
|
||||
"Ensure every project has exactly one default column",
|
||||
"Add unique index for project issue table",
|
||||
"Add commit status summary table",
|
||||
"Add missing field of commit status summary table",
|
||||
"Add everyone_access_mode for repo_unit",
|
||||
"Drop wrongly created table o_auth2_application",
|
||||
"Add content version to issue and comment table",
|
||||
"Add force-push branch protection support",
|
||||
"Add skip_secondary_authorization option to oauth2 application table",
|
||||
"Add metadata column for comment table",
|
||||
}
|
||||
|
||||
// Version describes the version table. Should have only one row with id==1
|
||||
type Version struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Version int64
|
||||
}
|
||||
|
||||
func MigrateToXormigrate(x *xorm.Engine) error {
|
||||
if err := x.Sync(new(Version)); err != nil {
|
||||
return fmt.Errorf("sync: %w", err)
|
||||
}
|
||||
|
||||
currentVersion := &Version{ID: 1}
|
||||
has, err := x.Get(currentVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get: %w", err)
|
||||
} else if !has {
|
||||
// This should not happen
|
||||
return fmt.Errorf("could not get version")
|
||||
}
|
||||
|
||||
v := currentVersion.Version
|
||||
if minDBVersion > v {
|
||||
log.Fatal(`Gitea no longer supports auto-migration from your previously installed version.
|
||||
Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Downgrading Gitea's database version not supported
|
||||
if int(v-minDBVersion) > oldMigrationsCount {
|
||||
msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Gitea, you can not use the newer database for this old Gitea release (%d).", v, expectedVersion)
|
||||
msg += "\nGitea will exit to keep your database safe and unchanged. Please use the correct Gitea release, do not change the migration version manually (incorrect manual operation may lose data)."
|
||||
if !setting.IsProd {
|
||||
msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", expectedVersion)
|
||||
}
|
||||
log.Fatal("Migration Error: %s", msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// add migrations that already have been run
|
||||
for _, i := range oldMigrationNames[:v-minDBVersion] {
|
||||
if _, err := x.Insert(&xormigrate.Migration{ID: i}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Remove old version table
|
||||
return x.DropTables(new(Version))
|
||||
}
|
@ -77,7 +77,7 @@ type Release struct {
|
||||
Target string
|
||||
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
|
||||
Title string
|
||||
Sha1 string `xorm:"VARCHAR(64)"`
|
||||
Sha1 string `xorm:"INDEX VARCHAR(64)"`
|
||||
NumCommits int64
|
||||
NumCommitsBehind int64 `xorm:"-"`
|
||||
Note string `xorm:"TEXT"`
|
||||
@ -537,3 +537,17 @@ func InsertReleases(ctx context.Context, rels ...*Release) error {
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
|
||||
func FindTagsByCommitIDs(ctx context.Context, repoID int64, commitIDs ...string) (map[string][]*Release, error) {
|
||||
releases := make([]*Release, 0, len(commitIDs))
|
||||
if err := db.GetEngine(ctx).Where("repo_id=?", repoID).
|
||||
In("sha1", commitIDs).
|
||||
Find(&releases); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make(map[string][]*Release, len(releases))
|
||||
for _, r := range releases {
|
||||
res[r.Sha1] = append(res[r.Sha1], r)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
@ -25,3 +25,16 @@ func TestMigrate_InsertReleases(t *testing.T) {
|
||||
err := InsertReleases(db.DefaultContext, r)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func Test_FindTagsByCommitIDs(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
sha1Rels, err := FindTagsByCommitIDs(db.DefaultContext, 1, "65f1bf27bc3bf70f64657658635e66094edbcb4d")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, sha1Rels, 1)
|
||||
rels := sha1Rels["65f1bf27bc3bf70f64657658635e66094edbcb4d"]
|
||||
assert.Len(t, rels, 3)
|
||||
assert.Equal(t, "v1.1", rels[0].TagName)
|
||||
assert.Equal(t, "delete-tag", rels[1].TagName)
|
||||
assert.Equal(t, "v1.0", rels[2].TagName)
|
||||
}
|
||||
|
46
modules/git/batch.go
Normal file
46
modules/git/batch.go
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
)
|
||||
|
||||
type Batch struct {
|
||||
cancel context.CancelFunc
|
||||
Reader *bufio.Reader
|
||||
Writer WriteCloserError
|
||||
}
|
||||
|
||||
func (repo *Repository) NewBatch(ctx context.Context) (*Batch, error) {
|
||||
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
||||
if err := ensureValidGitRepository(ctx, repo.Path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var batch Batch
|
||||
batch.Writer, batch.Reader, batch.cancel = catFileBatch(ctx, repo.Path)
|
||||
return &batch, nil
|
||||
}
|
||||
|
||||
func (repo *Repository) NewBatchCheck(ctx context.Context) (*Batch, error) {
|
||||
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
||||
if err := ensureValidGitRepository(ctx, repo.Path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var check Batch
|
||||
check.Writer, check.Reader, check.cancel = catFileBatchCheck(ctx, repo.Path)
|
||||
return &check, nil
|
||||
}
|
||||
|
||||
func (b *Batch) Close() {
|
||||
if b.cancel != nil {
|
||||
b.cancel()
|
||||
b.Reader = nil
|
||||
b.Writer = nil
|
||||
b.cancel = nil
|
||||
}
|
||||
}
|
@ -26,10 +26,10 @@ type WriteCloserError interface {
|
||||
CloseWithError(err error) error
|
||||
}
|
||||
|
||||
// EnsureValidGitRepository runs git rev-parse in the repository path - thus ensuring that the repository is a valid repository.
|
||||
// ensureValidGitRepository runs git rev-parse in the repository path - thus ensuring that the repository is a valid repository.
|
||||
// Run before opening git cat-file.
|
||||
// This is needed otherwise the git cat-file will hang for invalid repositories.
|
||||
func EnsureValidGitRepository(ctx context.Context, repoPath string) error {
|
||||
func ensureValidGitRepository(ctx context.Context, repoPath string) error {
|
||||
stderr := strings.Builder{}
|
||||
err := NewCommand(ctx, "rev-parse").
|
||||
SetDescription(fmt.Sprintf("%s rev-parse [repo_path: %s]", GitExecutable, repoPath)).
|
||||
@ -43,8 +43,8 @@ func EnsureValidGitRepository(ctx context.Context, repoPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CatFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
||||
func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
|
||||
// catFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
||||
func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
|
||||
batchStdinReader, batchStdinWriter := io.Pipe()
|
||||
batchStdoutReader, batchStdoutWriter := io.Pipe()
|
||||
ctx, ctxCancel := context.WithCancel(ctx)
|
||||
@ -93,8 +93,8 @@ func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError,
|
||||
return batchStdinWriter, batchReader, cancel
|
||||
}
|
||||
|
||||
// CatFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
||||
func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
|
||||
// catFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
||||
func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
|
||||
// We often want to feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
|
||||
// so let's create a batch stdin and stdout
|
||||
batchStdinReader, batchStdinWriter := io.Pipe()
|
||||
|
@ -26,9 +26,12 @@ type Blob struct {
|
||||
// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
|
||||
// Calling the Close function on the result will discard all unread output.
|
||||
func (b *Blob) DataAsync() (io.ReadCloser, error) {
|
||||
wr, rd, cancel := b.repo.CatFileBatch(b.repo.Ctx)
|
||||
wr, rd, cancel, err := b.repo.CatFileBatch(b.repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err := wr.Write([]byte(b.ID.String() + "\n"))
|
||||
_, err = wr.Write([]byte(b.ID.String() + "\n"))
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, err
|
||||
@ -64,9 +67,13 @@ func (b *Blob) Size() int64 {
|
||||
return b.size
|
||||
}
|
||||
|
||||
wr, rd, cancel := b.repo.CatFileBatchCheck(b.repo.Ctx)
|
||||
wr, rd, cancel, err := b.repo.CatFileBatchCheck(b.repo.Ctx)
|
||||
if err != nil {
|
||||
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
||||
return 0
|
||||
}
|
||||
defer cancel()
|
||||
_, err := wr.Write([]byte(b.ID.String() + "\n"))
|
||||
_, err = wr.Write([]byte(b.ID.String() + "\n"))
|
||||
if err != nil {
|
||||
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
|
||||
return 0
|
||||
|
@ -124,7 +124,10 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
batchStdinWriter, batchReader, cancel := commit.repo.CatFileBatch(ctx)
|
||||
batchStdinWriter, batchReader, cancel, err := commit.repo.CatFileBatch(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
commitsMap := map[string]*Commit{}
|
||||
|
@ -46,7 +46,10 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
||||
|
||||
// Next feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
|
||||
// so let's create a batch stdin and stdout
|
||||
batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx)
|
||||
batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
// We'll use a scanner for the revList because it's simpler than a bufio.Reader
|
||||
|
@ -25,15 +25,11 @@ type Repository struct {
|
||||
|
||||
gpgSettings *GPGSettings
|
||||
|
||||
batchInUse bool
|
||||
batchCancel context.CancelFunc
|
||||
batchReader *bufio.Reader
|
||||
batchWriter WriteCloserError
|
||||
batchInUse bool
|
||||
batch *Batch
|
||||
|
||||
checkInUse bool
|
||||
checkCancel context.CancelFunc
|
||||
checkReader *bufio.Reader
|
||||
checkWriter WriteCloserError
|
||||
checkInUse bool
|
||||
check *Batch
|
||||
|
||||
Ctx context.Context
|
||||
LastCommitCache *LastCommitCache
|
||||
@ -55,63 +51,75 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
|
||||
return nil, util.NewNotExistErrorf("no such file or directory")
|
||||
}
|
||||
|
||||
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
||||
if err := EnsureValidGitRepository(ctx, repoPath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo := &Repository{
|
||||
return &Repository{
|
||||
Path: repoPath,
|
||||
tagCache: newObjectCache(),
|
||||
Ctx: ctx,
|
||||
}
|
||||
|
||||
repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath)
|
||||
repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repoPath)
|
||||
|
||||
return repo, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CatFileBatch obtains a CatFileBatch for this repository
|
||||
func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
|
||||
if repo.batchCancel == nil || repo.batchInUse {
|
||||
log.Debug("Opening temporary cat file batch for: %s", repo.Path)
|
||||
return CatFileBatch(ctx, repo.Path)
|
||||
func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) {
|
||||
if repo.batch == nil {
|
||||
var err error
|
||||
repo.batch, err = repo.NewBatch(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
repo.batchInUse = true
|
||||
return repo.batchWriter, repo.batchReader, func() {
|
||||
repo.batchInUse = false
|
||||
|
||||
if !repo.batchInUse {
|
||||
repo.batchInUse = true
|
||||
return repo.batch.Writer, repo.batch.Reader, func() {
|
||||
repo.batchInUse = false
|
||||
}, nil
|
||||
}
|
||||
|
||||
log.Debug("Opening temporary cat file batch for: %s", repo.Path)
|
||||
tempBatch, err := repo.NewBatch(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return tempBatch.Writer, tempBatch.Reader, tempBatch.Close, nil
|
||||
}
|
||||
|
||||
// CatFileBatchCheck obtains a CatFileBatchCheck for this repository
|
||||
func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
|
||||
if repo.checkCancel == nil || repo.checkInUse {
|
||||
log.Debug("Opening temporary cat file batch-check for: %s", repo.Path)
|
||||
return CatFileBatchCheck(ctx, repo.Path)
|
||||
func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) {
|
||||
if repo.check == nil {
|
||||
var err error
|
||||
repo.check, err = repo.NewBatchCheck(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
repo.checkInUse = true
|
||||
return repo.checkWriter, repo.checkReader, func() {
|
||||
repo.checkInUse = false
|
||||
|
||||
if !repo.checkInUse {
|
||||
repo.checkInUse = true
|
||||
return repo.check.Writer, repo.check.Reader, func() {
|
||||
repo.checkInUse = false
|
||||
}, nil
|
||||
}
|
||||
|
||||
log.Debug("Opening temporary cat file batch-check for: %s", repo.Path)
|
||||
tempBatchCheck, err := repo.NewBatchCheck(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return tempBatchCheck.Writer, tempBatchCheck.Reader, tempBatchCheck.Close, nil
|
||||
}
|
||||
|
||||
func (repo *Repository) Close() error {
|
||||
if repo == nil {
|
||||
return nil
|
||||
}
|
||||
if repo.batchCancel != nil {
|
||||
repo.batchCancel()
|
||||
repo.batchReader = nil
|
||||
repo.batchWriter = nil
|
||||
repo.batchCancel = nil
|
||||
if repo.batch != nil {
|
||||
repo.batch.Close()
|
||||
repo.batch = nil
|
||||
repo.batchInUse = false
|
||||
}
|
||||
if repo.checkCancel != nil {
|
||||
repo.checkCancel()
|
||||
repo.checkCancel = nil
|
||||
repo.checkReader = nil
|
||||
repo.checkWriter = nil
|
||||
if repo.check != nil {
|
||||
repo.check.Close()
|
||||
repo.check = nil
|
||||
repo.checkInUse = false
|
||||
}
|
||||
repo.LastCommitCache = nil
|
||||
|
@ -22,9 +22,13 @@ func (repo *Repository) IsObjectExist(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
||||
if err != nil {
|
||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||
return false
|
||||
}
|
||||
defer cancel()
|
||||
_, err := wr.Write([]byte(name + "\n"))
|
||||
_, err = wr.Write([]byte(name + "\n"))
|
||||
if err != nil {
|
||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||
return false
|
||||
@ -39,9 +43,13 @@ func (repo *Repository) IsReferenceExist(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
||||
if err != nil {
|
||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||
return false
|
||||
}
|
||||
defer cancel()
|
||||
_, err := wr.Write([]byte(name + "\n"))
|
||||
_, err = wr.Write([]byte(name + "\n"))
|
||||
if err != nil {
|
||||
log.Debug("Error writing to CatFileBatchCheck %v", err)
|
||||
return false
|
||||
|
@ -33,9 +33,12 @@ func (repo *Repository) ResolveReference(name string) (string, error) {
|
||||
|
||||
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
|
||||
func (repo *Repository) GetRefCommitID(name string) (string, error) {
|
||||
wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer cancel()
|
||||
_, err := wr.Write([]byte(name + "\n"))
|
||||
_, err = wr.Write([]byte(name + "\n"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -61,12 +64,19 @@ func (repo *Repository) RemoveReference(name string) error {
|
||||
|
||||
// IsCommitExist returns true if given commit exists in current repository.
|
||||
func (repo *Repository) IsCommitExist(name string) bool {
|
||||
if err := ensureValidGitRepository(repo.Ctx, repo.Path); err != nil {
|
||||
log.Error("IsCommitExist: %v", err)
|
||||
return false
|
||||
}
|
||||
_, _, err := NewCommand(repo.Ctx, "cat-file", "-e").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
|
||||
wr, rd, cancel := repo.CatFileBatch(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
_, _ = wr.Write([]byte(id.String() + "\n"))
|
||||
@ -143,7 +153,10 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
|
||||
}
|
||||
}
|
||||
|
||||
wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
_, err = wr.Write([]byte(commitID + "\n"))
|
||||
if err != nil {
|
||||
|
@ -20,7 +20,10 @@ import (
|
||||
func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, error) {
|
||||
// We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary.
|
||||
// so let's create a batch stdin and stdout
|
||||
batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx)
|
||||
batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
writeID := func(id string) error {
|
||||
|
@ -31,9 +31,12 @@ func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) {
|
||||
|
||||
// GetTagType gets the type of the tag, either commit (simple) or tag (annotated)
|
||||
func (repo *Repository) GetTagType(id ObjectID) (string, error) {
|
||||
wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer cancel()
|
||||
_, err := wr.Write([]byte(id.String() + "\n"))
|
||||
_, err = wr.Write([]byte(id.String() + "\n"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -89,7 +92,10 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) {
|
||||
}
|
||||
|
||||
// The tag is an annotated tag with a message.
|
||||
wr, rd, cancel := repo.CatFileBatch(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
if _, err := wr.Write([]byte(tagID.String() + "\n")); err != nil {
|
||||
|
@ -10,7 +10,10 @@ import (
|
||||
)
|
||||
|
||||
func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
|
||||
wr, rd, cancel := repo.CatFileBatch(repo.Ctx)
|
||||
wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
_, _ = wr.Write([]byte(id.String() + "\n"))
|
||||
|
@ -42,9 +42,13 @@ func (te *TreeEntry) Size() int64 {
|
||||
return te.size
|
||||
}
|
||||
|
||||
wr, rd, cancel := te.ptree.repo.CatFileBatchCheck(te.ptree.repo.Ctx)
|
||||
wr, rd, cancel, err := te.ptree.repo.CatFileBatchCheck(te.ptree.repo.Ctx)
|
||||
if err != nil {
|
||||
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
||||
return 0
|
||||
}
|
||||
defer cancel()
|
||||
_, err := wr.Write([]byte(te.ID.String() + "\n"))
|
||||
_, err = wr.Write([]byte(te.ID.String() + "\n"))
|
||||
if err != nil {
|
||||
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
|
||||
return 0
|
||||
|
@ -33,7 +33,10 @@ func (t *Tree) ListEntries() (Entries, error) {
|
||||
}
|
||||
|
||||
if t.repo != nil {
|
||||
wr, rd, cancel := t.repo.CatFileBatch(t.repo.Ctx)
|
||||
wr, rd, cancel, err := t.repo.CatFileBatch(t.repo.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cancel()
|
||||
|
||||
_, _ = wr.Write([]byte(t.ID.String() + "\n"))
|
||||
|
@ -16,10 +16,10 @@ import (
|
||||
"code.gitea.io/gitea/modules/analyze"
|
||||
"code.gitea.io/gitea/modules/charset"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/indexer/code/internal"
|
||||
indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
|
||||
inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
@ -189,21 +189,23 @@ func (b *Indexer) addDelete(filename string, repo *repo_model.Repository, batch
|
||||
func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha string, changes *internal.RepoChanges) error {
|
||||
batch := inner_bleve.NewFlushingBatch(b.inner.Indexer, maxBatchSize)
|
||||
if len(changes.Updates) > 0 {
|
||||
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
||||
if err := git.EnsureValidGitRepository(ctx, repo.RepoPath()); err != nil {
|
||||
log.Error("Unable to open git repo: %s for %-v: %v", repo.RepoPath(), repo, err)
|
||||
r, err := gitrepo.OpenRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
batchWriter, batchReader, cancel := git.CatFileBatch(ctx, repo.RepoPath())
|
||||
defer cancel()
|
||||
defer r.Close()
|
||||
gitBatch, err := r.NewBatch(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer gitBatch.Close()
|
||||
|
||||
for _, update := range changes.Updates {
|
||||
if err := b.addUpdate(ctx, batchWriter, batchReader, sha, update, repo, batch); err != nil {
|
||||
if err := b.addUpdate(ctx, gitBatch.Writer, gitBatch.Reader, sha, update, repo, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
cancel()
|
||||
gitBatch.Close()
|
||||
}
|
||||
for _, filename := range changes.RemovedFilenames {
|
||||
if err := b.addDelete(filename, repo, batch); err != nil {
|
||||
|
@ -15,11 +15,11 @@ import (
|
||||
"code.gitea.io/gitea/modules/analyze"
|
||||
"code.gitea.io/gitea/modules/charset"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/indexer/code/internal"
|
||||
indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
|
||||
inner_elasticsearch "code.gitea.io/gitea/modules/indexer/internal/elasticsearch"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
@ -154,17 +154,19 @@ func (b *Indexer) addDelete(filename string, repo *repo_model.Repository) elasti
|
||||
func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha string, changes *internal.RepoChanges) error {
|
||||
reqs := make([]elastic.BulkableRequest, 0)
|
||||
if len(changes.Updates) > 0 {
|
||||
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
|
||||
if err := git.EnsureValidGitRepository(ctx, repo.RepoPath()); err != nil {
|
||||
log.Error("Unable to open git repo: %s for %-v: %v", repo.RepoPath(), repo, err)
|
||||
r, err := gitrepo.OpenRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
batchWriter, batchReader, cancel := git.CatFileBatch(ctx, repo.RepoPath())
|
||||
defer cancel()
|
||||
defer r.Close()
|
||||
batch, err := r.NewBatch(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer batch.Close()
|
||||
|
||||
for _, update := range changes.Updates {
|
||||
updateReqs, err := b.addUpdate(ctx, batchWriter, batchReader, sha, update, repo)
|
||||
updateReqs, err := b.addUpdate(ctx, batch.Writer, batch.Reader, sha, update, repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -172,7 +174,7 @@ func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha st
|
||||
reqs = append(reqs, updateReqs...)
|
||||
}
|
||||
}
|
||||
cancel()
|
||||
batch.Close()
|
||||
}
|
||||
|
||||
for _, filename := range changes.RemovedFilenames {
|
||||
|
@ -45,7 +45,7 @@ func (p *PullRequest) GetContext() DownloaderContext { return p.Context }
|
||||
|
||||
// IsForkPullRequest returns true if the pull request from a forked repository but not the same repository
|
||||
func (p *PullRequest) IsForkPullRequest() bool {
|
||||
return p.Head.RepoPath() != p.Base.RepoPath()
|
||||
return p.Head.RepoFullName() != p.Base.RepoFullName()
|
||||
}
|
||||
|
||||
// GetGitRefName returns pull request relative path to head
|
||||
@ -62,8 +62,8 @@ type PullRequestBranch struct {
|
||||
OwnerName string `yaml:"owner_name"`
|
||||
}
|
||||
|
||||
// RepoPath returns pull request repo path
|
||||
func (p PullRequestBranch) RepoPath() string {
|
||||
// RepoFullName returns pull request repo full name
|
||||
func (p PullRequestBranch) RepoFullName() string {
|
||||
return fmt.Sprintf("%s/%s", p.OwnerName, p.RepoName)
|
||||
}
|
||||
|
||||
|
@ -1274,6 +1274,7 @@ commit_graph.color = Color
|
||||
commit.contained_in = This commit is contained in:
|
||||
commit.contained_in_default_branch = This commit is part of the default branch
|
||||
commit.load_referencing_branches_and_tags = Load branches and tags referencing this commit
|
||||
commit.load_tags_failed = Load tags failed because of internal error
|
||||
blame = Blame
|
||||
download_file = Download file
|
||||
normal_view = Normal View
|
||||
|
@ -628,6 +628,7 @@ org_still_own_repo=Esta organização ainda possui um ou mais repositórios, eli
|
||||
org_still_own_packages=Esta organização ainda possui um ou mais pacotes, elimine-os primeiro.
|
||||
|
||||
target_branch_not_exist=O ramo de destino não existe.
|
||||
target_ref_not_exist=A referência de destino não existe %s
|
||||
|
||||
admin_cannot_delete_self=Não se pode auto-remover quando tem privilégios de administração. Remova esses privilégios primeiro.
|
||||
|
||||
@ -1273,6 +1274,7 @@ commit_graph.color=Colorido
|
||||
commit.contained_in=Este cometimento está contido em:
|
||||
commit.contained_in_default_branch=Este cometimento é parte do ramo principal
|
||||
commit.load_referencing_branches_and_tags=Carregar ramos e etiquetas que referenciem este cometimento
|
||||
commit.load_tags_failed=O carregamento das etiquetas falhou por causa de um erro interno
|
||||
blame=Responsabilidade
|
||||
download_file=Descarregar ficheiro
|
||||
normal_view=Vista normal
|
||||
@ -3700,6 +3702,11 @@ workflow.disable_success=A sequência de trabalho '%s' foi desabilitada com suce
|
||||
workflow.enable=Habilitar sequência de trabalho
|
||||
workflow.enable_success=A sequência de trabalho '%s' foi habilitada com sucesso.
|
||||
workflow.disabled=A sequência de trabalho está desabilitada.
|
||||
workflow.run=Executar sequência de trabalho
|
||||
workflow.not_found=A sequência de trabalho '%s' não foi encontrada.
|
||||
workflow.run_success=A sequência de trabalho '%s' foi executada com sucesso.
|
||||
workflow.from_ref=Usar sequência de trabalho de
|
||||
workflow.has_workflow_dispatch=Esta sequência de trabalho tem um despoletador de eventos workflow_dispatch.
|
||||
|
||||
need_approval_desc=É necessária aprovação para executar sequências de trabalho para a derivação do pedido de integração.
|
||||
|
||||
|
@ -1117,7 +1117,7 @@ projects=Проекты
|
||||
packages=Пакеты
|
||||
actions=Действия
|
||||
labels=Метки
|
||||
org_labels_desc=Метки уровня организации, которые можно использовать с <strong>всеми репозиториями< / strong> в этой организации
|
||||
org_labels_desc=Метки уровня организации, которые можно использовать с <strong>всеми репозиториями</strong> в этой организации
|
||||
org_labels_desc_manage=управлять
|
||||
|
||||
milestones=Этапы
|
||||
|
@ -1217,7 +1217,7 @@ clear_ref='Geçerli referansı temizle'
|
||||
filter_branch_and_tag=Dal veya biçim imini filtrele
|
||||
find_tag=Etiketi bul
|
||||
branches=Dal
|
||||
tags=Etiket
|
||||
tags=Etiketler
|
||||
issues=Konular
|
||||
pulls=Değişiklik İstekleri
|
||||
projects=Projeler
|
||||
|
@ -40,6 +40,7 @@ func LinkAccount(ctx *context.Context) {
|
||||
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
|
||||
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
|
||||
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
|
||||
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
|
||||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
||||
ctx.Data["AllowOnlyInternalRegistration"] = setting.Service.AllowOnlyInternalRegistration
|
||||
ctx.Data["ShowRegistrationButton"] = false
|
||||
@ -132,6 +133,7 @@ func LinkAccountPostSignIn(ctx *context.Context) {
|
||||
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
|
||||
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
|
||||
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
|
||||
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
|
||||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
||||
ctx.Data["ShowRegistrationButton"] = false
|
||||
|
||||
@ -219,6 +221,7 @@ func LinkAccountPostRegister(ctx *context.Context) {
|
||||
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
|
||||
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
|
||||
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
|
||||
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
|
||||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
||||
ctx.Data["ShowRegistrationButton"] = false
|
||||
|
||||
|
@ -307,6 +307,7 @@ func RegisterOpenID(ctx *context.Context) {
|
||||
ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL
|
||||
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
|
||||
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
|
||||
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
|
||||
ctx.Data["OpenID"] = oid
|
||||
userName, _ := ctx.Session.Get("openid_determined_username").(string)
|
||||
if userName != "" {
|
||||
|
@ -83,7 +83,17 @@ func Commits(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
ctx.Data["Commits"] = processGitCommits(ctx, commits)
|
||||
|
||||
commitIDs := make([]string, 0, len(commits))
|
||||
for _, c := range commits {
|
||||
commitIDs = append(commitIDs, c.ID.String())
|
||||
}
|
||||
commitsTagsMap, err := repo_model.FindTagsByCommitIDs(ctx, ctx.Repo.Repository.ID, commitIDs...)
|
||||
if err != nil {
|
||||
log.Error("FindTagsByCommitIDs: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("repo.commit.load_tags_failed"))
|
||||
} else {
|
||||
ctx.Data["CommitsTagsMap"] = commitsTagsMap
|
||||
}
|
||||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
||||
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
||||
ctx.Data["CommitCount"] = commitsCount
|
||||
|
@ -240,7 +240,8 @@ func SettingsPost(ctx *context.Context) {
|
||||
|
||||
remoteAddress, err := util.SanitizeURL(form.MirrorAddress)
|
||||
if err != nil {
|
||||
ctx.ServerError("SanitizeURL", err)
|
||||
ctx.Data["Err_MirrorAddress"] = true
|
||||
handleSettingRemoteAddrError(ctx, err, form)
|
||||
return
|
||||
}
|
||||
pullMirror.RemoteAddress = remoteAddress
|
||||
@ -401,7 +402,8 @@ func SettingsPost(ctx *context.Context) {
|
||||
|
||||
remoteAddress, err := util.SanitizeURL(form.PushMirrorAddress)
|
||||
if err != nil {
|
||||
ctx.ServerError("SanitizeURL", err)
|
||||
ctx.Data["Err_PushMirrorAddress"] = true
|
||||
handleSettingRemoteAddrError(ctx, err, form)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@ func (n *actionsNotifier) ForkRepository(ctx context.Context, doer *user_model.U
|
||||
// Add to hook queue for created repo after session commit.
|
||||
if u.IsOrganization() {
|
||||
newNotifyInput(repo, doer, webhook_module.HookEventRepository).
|
||||
WithRef(oldRepo.DefaultBranch).
|
||||
WithRef(git.RefNameFromBranch(oldRepo.DefaultBranch).String()).
|
||||
WithPayload(&api.RepositoryPayload{
|
||||
Action: api.HookRepoCreated,
|
||||
Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}),
|
||||
|
@ -65,7 +65,7 @@ type notifyInput struct {
|
||||
Event webhook_module.HookEventType
|
||||
|
||||
// optional
|
||||
Ref string
|
||||
Ref git.RefName
|
||||
Payload api.Payloader
|
||||
PullRequest *issues_model.PullRequest
|
||||
}
|
||||
@ -89,7 +89,7 @@ func (input *notifyInput) WithDoer(doer *user_model.User) *notifyInput {
|
||||
}
|
||||
|
||||
func (input *notifyInput) WithRef(ref string) *notifyInput {
|
||||
input.Ref = ref
|
||||
input.Ref = git.RefName(ref)
|
||||
return input
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ func (input *notifyInput) WithPayload(payload api.Payloader) *notifyInput {
|
||||
func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput {
|
||||
input.PullRequest = pr
|
||||
if input.Ref == "" {
|
||||
input.Ref = pr.GetGitRefName()
|
||||
input.Ref = git.RefName(pr.GetGitRefName())
|
||||
}
|
||||
return input
|
||||
}
|
||||
@ -144,20 +144,25 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
defer gitRepo.Close()
|
||||
|
||||
ref := input.Ref
|
||||
if ref != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) {
|
||||
if ref.BranchName() != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) {
|
||||
if ref != "" {
|
||||
log.Warn("Event %q should only trigger workflows on the default branch, but its ref is %q. Will fall back to the default branch",
|
||||
input.Event, ref)
|
||||
}
|
||||
ref = input.Repo.DefaultBranch
|
||||
ref = git.RefNameFromBranch(input.Repo.DefaultBranch)
|
||||
}
|
||||
if ref == "" {
|
||||
log.Warn("Ref of event %q is empty, will fall back to the default branch", input.Event)
|
||||
ref = input.Repo.DefaultBranch
|
||||
ref = git.RefNameFromBranch(input.Repo.DefaultBranch)
|
||||
}
|
||||
|
||||
commitID, err := gitRepo.GetRefCommitID(ref.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("gitRepo.GetRefCommitID: %w", err)
|
||||
}
|
||||
|
||||
// Get the commit object for the ref
|
||||
commit, err := gitRepo.GetCommit(ref)
|
||||
commit, err := gitRepo.GetCommit(commitID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("gitRepo.GetCommit: %w", err)
|
||||
}
|
||||
@ -168,7 +173,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
|
||||
var detectedWorkflows []*actions_module.DetectedWorkflow
|
||||
actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig()
|
||||
shouldDetectSchedules := input.Event == webhook_module.HookEventPush && git.RefName(input.Ref).BranchName() == input.Repo.DefaultBranch
|
||||
shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch
|
||||
workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit,
|
||||
input.Event,
|
||||
input.Payload,
|
||||
@ -220,12 +225,12 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
}
|
||||
|
||||
if shouldDetectSchedules {
|
||||
if err := handleSchedules(ctx, schedules, commit, input, ref); err != nil {
|
||||
if err := handleSchedules(ctx, schedules, commit, input, ref.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return handleWorkflows(ctx, detectedWorkflows, commit, input, ref)
|
||||
return handleWorkflows(ctx, detectedWorkflows, commit, input, ref.String())
|
||||
}
|
||||
|
||||
func skipWorkflows(input *notifyInput, commit *git.Commit) bool {
|
||||
|
@ -245,9 +245,21 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {
|
||||
defer headGitRepo.Close()
|
||||
}
|
||||
|
||||
headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch)
|
||||
if pr.HeadRepo == nil || !headBranchExist {
|
||||
log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch)
|
||||
switch pr.Flow {
|
||||
case issues_model.PullRequestFlowGithub:
|
||||
headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch)
|
||||
if pr.HeadRepo == nil || !headBranchExist {
|
||||
log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch)
|
||||
return
|
||||
}
|
||||
case issues_model.PullRequestFlowAGit:
|
||||
headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName())
|
||||
if !headBranchExist {
|
||||
log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch)
|
||||
return
|
||||
}
|
||||
default:
|
||||
log.Error("wrong flow type %d", pr.Flow)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,11 @@
|
||||
<tr>
|
||||
<td>
|
||||
<div class="flex-text-block">
|
||||
{{if .DefaultBranchBranch.IsProtected}}{{svg "octicon-shield-lock"}}{{end}}
|
||||
<a class="gt-ellipsis" href="{{.RepoLink}}/src/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}">{{.DefaultBranchBranch.DBBranch.Name}}</a>
|
||||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DefaultBranchBranch.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{if .DefaultBranchBranch.IsProtected}}
|
||||
<span data-tooltip-content="{{ctx.Locale.Tr "repo.settings.protected_branch"}}">{{svg "octicon-shield-lock"}}</span>
|
||||
{{end}}
|
||||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DefaultBranchBranch.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "copy_branch"}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}}
|
||||
</div>
|
||||
<p class="info tw-flex tw-items-center tw-my-1">{{svg "octicon-git-commit" 16 "tw-mr-1"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p>
|
||||
@ -39,7 +41,7 @@
|
||||
</button>
|
||||
{{end}}
|
||||
{{if .EnableFeed}}
|
||||
<a role="button" class="btn interact-bg tw-p-2" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}">{{svg "octicon-rss"}}</a>
|
||||
<a role="button" class="btn interact-bg tw-p-2" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">{{svg "octicon-rss"}}</a>
|
||||
{{end}}
|
||||
{{if not $.DisableDownloadSourceArchives}}
|
||||
<div class="ui dropdown btn interact-bg tw-p-2" data-tooltip-content="{{ctx.Locale.Tr "repo.branch.download" ($.DefaultBranchBranch.DBBranch.Name)}}">
|
||||
@ -88,14 +90,16 @@
|
||||
{{if .DBBranch.IsDeleted}}
|
||||
<div class="flex-text-block">
|
||||
<span class="gt-ellipsis">{{.DBBranch.Name}}</span>
|
||||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "copy_branch"}}">{{svg "octicon-copy" 14}}</button>
|
||||
</div>
|
||||
<p class="info">{{ctx.Locale.Tr "repo.branch.deleted_by" .DBBranch.DeletedBy.Name}} {{TimeSinceUnix .DBBranch.DeletedUnix ctx.Locale}}</p>
|
||||
{{else}}
|
||||
<div class="flex-text-block">
|
||||
{{if .IsProtected}}{{svg "octicon-shield-lock"}}{{end}}
|
||||
<a class="gt-ellipsis" href="{{$.RepoLink}}/src/branch/{{PathEscapeSegments .DBBranch.Name}}">{{.DBBranch.Name}}</a>
|
||||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{if .IsProtected}}
|
||||
<span data-tooltip-content="{{ctx.Locale.Tr "repo.settings.protected_branch"}}">{{svg "octicon-shield-lock"}}</span>
|
||||
{{end}}
|
||||
<button class="btn interact-fg tw-px-1" data-clipboard-text="{{.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "copy_branch"}}">{{svg "octicon-copy" 14}}</button>
|
||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}}
|
||||
</div>
|
||||
<p class="info tw-flex tw-items-center tw-my-1">{{svg "octicon-git-commit" 16 "tw-mr-1"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage ($.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p>
|
||||
@ -156,7 +160,7 @@
|
||||
</button>
|
||||
{{end}}
|
||||
{{if $.EnableFeed}}
|
||||
<a role="button" class="btn interact-bg tw-p-2" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .DBBranch.Name}}">{{svg "octicon-rss"}}</a>
|
||||
<a role="button" class="btn interact-bg tw-p-2" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">{{svg "octicon-rss"}}</a>
|
||||
{{end}}
|
||||
{{if and (not .DBBranch.IsDeleted) (not $.DisableDownloadSourceArchives)}}
|
||||
<div class="ui dropdown btn interact-bg tw-p-2" data-tooltip-content="{{ctx.Locale.Tr "repo.branch.download" (.DBBranch.Name)}}">
|
||||
|
@ -72,6 +72,11 @@
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<pre class="commit-body tw-hidden">{{RenderCommitBody $.Context .Message ($.Repository.ComposeMetas ctx)}}</pre>
|
||||
{{end}}
|
||||
{{if $.CommitsTagsMap}}
|
||||
{{range (index $.CommitsTagsMap .ID.String)}}
|
||||
{{- template "repo/tag/name" dict "RepoLink" $.Repository.Link "TagName" .TagName "IsRelease" (not .IsTag) -}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</td>
|
||||
{{if .Committer}}
|
||||
<td class="text right aligned">{{TimeSince .Committer.When ctx.Locale}}</td>
|
||||
|
@ -42,9 +42,7 @@
|
||||
</a>
|
||||
{{end}}
|
||||
{{else if eq $refGroup "tags"}}
|
||||
<a class="ui labelled basic tiny button" href="{{$.RepoLink}}/src/tag/{{.ShortName|PathEscape}}">
|
||||
{{svg "octicon-tag"}} {{.ShortName}}
|
||||
</a>
|
||||
{{- template "repo/tag/name" dict "RepoLink" $.Repository.Link "TagName" .ShortName -}}
|
||||
{{else if eq $refGroup "remotes"}}
|
||||
<a class="ui labelled basic tiny button" href="{{$.RepoLink}}/src/commit/{{$commit.Rev|PathEscape}}">
|
||||
{{svg "octicon-cross-reference"}} {{.ShortName}}
|
||||
|
3
templates/repo/tag/name.tmpl
Normal file
3
templates/repo/tag/name.tmpl
Normal file
@ -0,0 +1,3 @@
|
||||
<a class="ui label basic tiny button{{if .IsRelease}} primary{{end}}" href="{{.RepoLink}}/src/tag/{{.TagName|PathEscape}}">
|
||||
{{svg "octicon-tag"}} {{.TagName}}
|
||||
</a>
|
7
tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive
Executable file
7
tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
ORI_DIR=`pwd`
|
||||
SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
|
||||
cd "$ORI_DIR"
|
||||
for i in `ls "$SHELL_FOLDER/proc-receive.d"`; do
|
||||
sh "$SHELL_FOLDER/proc-receive.d/$i"
|
||||
done
|
2
tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea
Executable file
2
tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea
Executable file
@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" proc-receive
|
@ -427,7 +427,7 @@ func TestCreateDeleteRefEvent(t *testing.T) {
|
||||
Title: "add workflow",
|
||||
RepoID: repo.ID,
|
||||
Event: "delete",
|
||||
Ref: "main",
|
||||
Ref: "refs/heads/main",
|
||||
WorkflowID: "createdelete.yml",
|
||||
CommitSHA: branch.CommitID,
|
||||
})
|
||||
@ -442,7 +442,7 @@ func TestCreateDeleteRefEvent(t *testing.T) {
|
||||
Title: "add workflow",
|
||||
RepoID: repo.ID,
|
||||
Event: "delete",
|
||||
Ref: "main",
|
||||
Ref: "refs/heads/main",
|
||||
WorkflowID: "createdelete.yml",
|
||||
CommitSHA: branch.CommitID,
|
||||
})
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/queue"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"code.gitea.io/gitea/modules/translation"
|
||||
@ -846,3 +847,132 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApproval(t *testing.T) {
|
||||
unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID})
|
||||
})
|
||||
}
|
||||
|
||||
func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.T) {
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
// create a pull request
|
||||
baseAPITestContext := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
|
||||
|
||||
dstPath := t.TempDir()
|
||||
|
||||
u.Path = baseAPITestContext.GitPath()
|
||||
u.User = url.UserPassword("user2", userPassword)
|
||||
|
||||
t.Run("Clone", doGitClone(dstPath, u))
|
||||
|
||||
err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content"), 0o666)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = git.AddChanges(dstPath, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = git.CommitChanges(dstPath, git.CommitChangesOptions{
|
||||
Committer: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
Name: "user2",
|
||||
When: time.Now(),
|
||||
},
|
||||
Author: &git.Signature{
|
||||
Email: "user2@example.com",
|
||||
Name: "user2",
|
||||
When: time.Now(),
|
||||
},
|
||||
Message: "Testing commit 1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
stderrBuf := &bytes.Buffer{}
|
||||
|
||||
err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o").
|
||||
AddDynamicArguments(`topic=test/head2`).
|
||||
AddArguments("-o").
|
||||
AddDynamicArguments(`title="create a test pull request with agit"`).
|
||||
AddArguments("-o").
|
||||
AddDynamicArguments(`description="This PR is a test pull request which created with agit"`).
|
||||
Run(&git.RunOpts{Dir: dstPath, Stderr: stderrBuf})
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Contains(t, stderrBuf.String(), setting.AppURL+"user2/repo1/pulls/6")
|
||||
|
||||
baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "repo1"})
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{
|
||||
Flow: issues_model.PullRequestFlowAGit,
|
||||
BaseRepoID: baseRepo.ID,
|
||||
BaseBranch: "master",
|
||||
HeadRepoID: baseRepo.ID,
|
||||
HeadBranch: "user2/test/head2",
|
||||
})
|
||||
|
||||
session := loginUser(t, "user1")
|
||||
// add protected branch for commit status
|
||||
csrf := GetCSRF(t, session, "/user2/repo1/settings/branches")
|
||||
// Change master branch to protected
|
||||
req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{
|
||||
"_csrf": csrf,
|
||||
"rule_name": "master",
|
||||
"enable_push": "true",
|
||||
"enable_status_check": "true",
|
||||
"status_check_contexts": "gitea/actions",
|
||||
"required_approvals": "1",
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
||||
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
|
||||
// first time insert automerge record, return true
|
||||
scheduled, err := automerge.ScheduleAutoMerge(db.DefaultContext, user1, pr, repo_model.MergeStyleMerge, "auto merge test")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, scheduled)
|
||||
|
||||
// second time insert automerge record, return false because it does exist
|
||||
scheduled, err = automerge.ScheduleAutoMerge(db.DefaultContext, user1, pr, repo_model.MergeStyleMerge, "auto merge test")
|
||||
assert.Error(t, err)
|
||||
assert.False(t, scheduled)
|
||||
|
||||
// reload pr again
|
||||
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
|
||||
assert.False(t, pr.HasMerged)
|
||||
assert.Empty(t, pr.MergedCommitID)
|
||||
|
||||
// update commit status to success, then it should be merged automatically
|
||||
baseGitRepo, err := gitrepo.OpenRepository(db.DefaultContext, baseRepo)
|
||||
assert.NoError(t, err)
|
||||
sha, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName())
|
||||
assert.NoError(t, err)
|
||||
masterCommitID, err := baseGitRepo.GetBranchCommitID("master")
|
||||
assert.NoError(t, err)
|
||||
baseGitRepo.Close()
|
||||
defer func() {
|
||||
testResetRepo(t, baseRepo.RepoPath(), "master", masterCommitID)
|
||||
}()
|
||||
|
||||
err = commitstatus_service.CreateCommitStatus(db.DefaultContext, baseRepo, user1, sha, &git_model.CommitStatus{
|
||||
State: api.CommitStatusSuccess,
|
||||
TargetURL: "https://gitea.com",
|
||||
Context: "gitea/actions",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// reload pr again
|
||||
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
|
||||
assert.False(t, pr.HasMerged)
|
||||
assert.Empty(t, pr.MergedCommitID)
|
||||
|
||||
// approve the PR from non-author
|
||||
approveSession := loginUser(t, "user1")
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/user2/repo1/pulls/%d", pr.Index))
|
||||
resp := approveSession.MakeRequest(t, req, http.StatusOK)
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
testSubmitReview(t, approveSession, htmlDoc.GetCSRF(), "user2", "repo1", strconv.Itoa(int(pr.Index)), sha, "approve", http.StatusOK)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// realod pr again
|
||||
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
|
||||
assert.True(t, pr.HasMerged)
|
||||
assert.NotEmpty(t, pr.MergedCommitID)
|
||||
|
||||
unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID})
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user