A fork of Gitea (see branch `mj`) adding Majority Judgment Polls 𐄷 over Issues and Merge Requests. https://git.mieuxvoter.fr
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

869 lines
32 KiB

Pull request review/approval and comment on code (#3748) * Initial ui components for pull request review * Add Review Add IssueComment types Signed-off-by: Jonas Franz <info@jonasfranz.software> (cherry picked from commit 2b4daab) Signed-off-by: Jonas Franz <info@jonasfranz.software> * Replace ReviewComment with Content Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add load functions Add ReviewID to findComments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add create review comment implementation Add migration for review Other small changes Signed-off-by: Jonas Franz <info@jonasfranz.software> * Simplified create and find functions for review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Moved "Pending" to first position Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add GetCurrentReview to simplify fetching current review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Preview for listing comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Move new comment form to its own file Signed-off-by: Jonas Franz <info@jonasfranz.software> * Implement Review form Show Review comments on comment stream Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for single comments Showing buttons in context Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add pending tag to pending review comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add unit tests for Review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fetch all review ids at once Add unit tests Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Improved comment rendering in "Files" view by adding Comments to DiffLine Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for invalidating comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Switched back to code.gitea.io/git Signed-off-by: Jonas Franz <info@jonasfranz.software> * Moved review migration from v64 to v65 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Rebuild css Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Improve translations Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix unit tests by updating fixtures and updating outdated test Signed-off-by: Jonas Franz <info@jonasfranz.software> * Comments will be shown at the right place now Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for deleting CodeComments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix problems caused by files in subdirectories Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for showing code comments of reviews in conversation Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for "Show/Hide outdated" Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update code.gitea.io/git Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for new webhooks Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update comparison Signed-off-by: Jonas Franz <info@jonasfranz.software> * Resolve conflicts Signed-off-by: Jonas Franz <info@jonasfranz.software> * Minor UI improvements * update code.gitea.io/git * Fix ui bug reported by @lunny causing wrong position of add button Add functionality to "Cancel" button Add scale effects to add button Hide "Cancel" button for existing comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Prepare solving conflicts Signed-off-by: Jonas Franz <info@jonasfranz.software> * Show add button only if no comments already exist for the line Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add missing vendor files Signed-off-by: Jonas Franz <info@jonasfranz.software> * Check if reviewer is nil Signed-off-by: Jonas Franz <info@jonasfranz.software> * Show forms only to users who are logged in Signed-off-by: Jonas Franz <info@jonasfranz.software> * Revert "Show forms only to users who are logged in" This reverts commit c083682 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Save patch in comment Render patch for code comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add link to comment in code Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add reply form to comment list Show forms only to signed in users Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add 'Reply' as translatable Add CODE_COMMENT_LINES setting Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix problems introduced by checking for singed in user Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add v70 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update generated stylesheet Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix preview Beginn with new review comment patch system Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add new algo to generate diff for line range Remove old algo used for cutting big diffs (it was very buggy) * Add documentation and example for CutDiffAroundLine * Fix example of CutDiffAroundLine * Fix some comment UI rendering bugs * Add code comment edit mode * Send notifications / actions to users until review gets published Fix diff generation bug Fix wrong hashtag * Fix vet errors * Send notifications also for single comments * Fix some notification bugs, fix link * Fix: add comment icon is only shown on code lines * Add lint comment * Add unit tests for git diff * Add more error messages * Regenerated css Signed-off-by: Jonas Franz <info@jonasfranz.software> * fmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Regenerated CSS with latest less version Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix test by updating comment type to new ID Signed-off-by: Jonas Franz <info@jonasfranz.software> * Introducing CodeComments as type for map[string]map[int64][]*Comment Other minor code improvements Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix data-tab issues Signed-off-by: Jonas Franz <info@jonasfranz.software> * Remove unnecessary change Signed-off-by: Jonas Franz <info@jonasfranz.software> * refactored checkForInvalidation Signed-off-by: Jonas Franz <info@jonasfranz.software> * Append comments instead of setting Signed-off-by: Jonas Franz <info@jonasfranz.software> * Use HeadRepo instead of BaseRepo Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update migration Signed-off-by: Jonas Franz <info@jonasfranz.de> * Regenerated CSS Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add copyright Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update index.css Signed-off-by: Jonas Franz <info@jonasfranz.software>
4 years ago
Pull request review/approval and comment on code (#3748) * Initial ui components for pull request review * Add Review Add IssueComment types Signed-off-by: Jonas Franz <info@jonasfranz.software> (cherry picked from commit 2b4daab) Signed-off-by: Jonas Franz <info@jonasfranz.software> * Replace ReviewComment with Content Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add load functions Add ReviewID to findComments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add create review comment implementation Add migration for review Other small changes Signed-off-by: Jonas Franz <info@jonasfranz.software> * Simplified create and find functions for review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Moved "Pending" to first position Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add GetCurrentReview to simplify fetching current review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Preview for listing comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Move new comment form to its own file Signed-off-by: Jonas Franz <info@jonasfranz.software> * Implement Review form Show Review comments on comment stream Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for single comments Showing buttons in context Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add pending tag to pending review comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add unit tests for Review Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fetch all review ids at once Add unit tests Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Improved comment rendering in "Files" view by adding Comments to DiffLine Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for invalidating comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Switched back to code.gitea.io/git Signed-off-by: Jonas Franz <info@jonasfranz.software> * Moved review migration from v64 to v65 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Rebuild css Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Improve translations Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix unit tests by updating fixtures and updating outdated test Signed-off-by: Jonas Franz <info@jonasfranz.software> * Comments will be shown at the right place now Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for deleting CodeComments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix problems caused by files in subdirectories Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for showing code comments of reviews in conversation Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for "Show/Hide outdated" Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update code.gitea.io/git Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add support for new webhooks Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update comparison Signed-off-by: Jonas Franz <info@jonasfranz.software> * Resolve conflicts Signed-off-by: Jonas Franz <info@jonasfranz.software> * Minor UI improvements * update code.gitea.io/git * Fix ui bug reported by @lunny causing wrong position of add button Add functionality to "Cancel" button Add scale effects to add button Hide "Cancel" button for existing comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Prepare solving conflicts Signed-off-by: Jonas Franz <info@jonasfranz.software> * Show add button only if no comments already exist for the line Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add missing vendor files Signed-off-by: Jonas Franz <info@jonasfranz.software> * Check if reviewer is nil Signed-off-by: Jonas Franz <info@jonasfranz.software> * Show forms only to users who are logged in Signed-off-by: Jonas Franz <info@jonasfranz.software> * Revert "Show forms only to users who are logged in" This reverts commit c083682 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Save patch in comment Render patch for code comments Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add link to comment in code Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add reply form to comment list Show forms only to signed in users Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add 'Reply' as translatable Add CODE_COMMENT_LINES setting Signed-off-by: Jonas Franz <info@jonasfranz.software> * gofmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix problems introduced by checking for singed in user Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add v70 Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update generated stylesheet Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix preview Beginn with new review comment patch system Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add new algo to generate diff for line range Remove old algo used for cutting big diffs (it was very buggy) * Add documentation and example for CutDiffAroundLine * Fix example of CutDiffAroundLine * Fix some comment UI rendering bugs * Add code comment edit mode * Send notifications / actions to users until review gets published Fix diff generation bug Fix wrong hashtag * Fix vet errors * Send notifications also for single comments * Fix some notification bugs, fix link * Fix: add comment icon is only shown on code lines * Add lint comment * Add unit tests for git diff * Add more error messages * Regenerated css Signed-off-by: Jonas Franz <info@jonasfranz.software> * fmt Signed-off-by: Jonas Franz <info@jonasfranz.software> * Regenerated CSS with latest less version Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix test by updating comment type to new ID Signed-off-by: Jonas Franz <info@jonasfranz.software> * Introducing CodeComments as type for map[string]map[int64][]*Comment Other minor code improvements Signed-off-by: Jonas Franz <info@jonasfranz.software> * Fix data-tab issues Signed-off-by: Jonas Franz <info@jonasfranz.software> * Remove unnecessary change Signed-off-by: Jonas Franz <info@jonasfranz.software> * refactored checkForInvalidation Signed-off-by: Jonas Franz <info@jonasfranz.software> * Append comments instead of setting Signed-off-by: Jonas Franz <info@jonasfranz.software> * Use HeadRepo instead of BaseRepo Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update migration Signed-off-by: Jonas Franz <info@jonasfranz.de> * Regenerated CSS Signed-off-by: Jonas Franz <info@jonasfranz.software> * Add copyright Signed-off-by: Jonas Franz <info@jonasfranz.software> * Update index.css Signed-off-by: Jonas Franz <info@jonasfranz.software>
4 years ago
Repository avatars (#6986) * Repository avatars - first variant of code from old work for gogs - add migration 87 - add new option in app.ini - add en-US locale string - add new class in repository.less * Add changed index.css, remove unused template name * Update en-us doc about configuration options * Add comments to new functions, add new option to docker app.ini * Add comment for lint * Remove variable, not needed * Fix formatting * Update swagger api template * Check if avatar exists * Fix avatar link/path checks * Typo * TEXT column can't have a default value * Fixes: - remove old avatar file on upload - use ID in name of avatar file - users may upload same files - add simple tests * Fix fmt check * Generate PNG instead of "static" GIF * More informative comment * Fix error message * Update avatar upload checks: - add file size check - add new option - update config docs - add new string to en-us locale * Fixes: - use FileHEader field for check file size - add new test - upload big image * Fix formatting * Update comments * Update log message * Removed wrong style - not needed * Use Sync2 to migrate * Update repos list view - bigger avatar - fix html blocks alignment * A little adjust avatar size * Use small icons for explore/repo list * Use new cool avatar preparation func by @lafriks * Missing changes for new function * Remove unused import, move imports * Missed new option definition in app.ini Add file size check in user/profile avatar upload * Use smaller field length for Avatar * Use session to update repo DB data, update DeleteAvatar - use session too * Fix err variable definition * As suggested @lafriks - return as soon as possible, code readability
3 years ago
Template Repositories (#8768) * Start work on templates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Continue work Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix IsTemplate vs IsGenerated Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tabs vs spaces * Tabs vs Spaces * Add templates to API & start adding tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix integration tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove unused User Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move template tests to existing repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Minor re-check updates and cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test cleanup Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix optionalbool Signed-off-by: jolheiser <john.olheiser@gmail.com> * make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Test fixes and icon change Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add new user and repo for tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests (finally) Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update meta repo with env variables Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move generation to create page Combine with repo create template Modify API search to prioritize owner for repo Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests and coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix swagger and JS lint Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix API searching for own private repos Signed-off-by: jolheiser <john.olheiser@gmail.com> * Change wording Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix repo search test. User had a private repo that didn't show up Signed-off-by: jolheiser <john.olheiser@gmail.com> * Another search test fix Signed-off-by: jolheiser <john.olheiser@gmail.com> * Clarify git content Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Feedback updates Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add topics WIP Signed-off-by: jolheiser <john.olheiser@gmail.com> * Finish adding topics Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update locale Signed-off-by: jolheiser <john.olheiser@gmail.com>
3 years ago
Change target branch for pull request (#6488) * Adds functionality to change target branch of created pull requests Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Use const instead of var in JavaScript additions Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Check if branches are equal and if PR already exists before changing target branch Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Make sure to check all commits Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Print error messages for user as error flash message Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Disallow changing target branch of closed or merged pull requests Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Resolve conflicts after merge of upstream/master Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Change order of branch select fields Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Removes duplicate check Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Use ctx.Tr for translations Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Recompile JS Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Use correct translation namespace Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Remove redundant if condition Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Moves most change branch logic into pull service Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Completes comment Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Add Ref to ChangesPayload for logging changed target branches instead of creating a new struct Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Revert changes to go.mod Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Directly use createComment method Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Return 404 if pull request is not found. Move written check up Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Remove variable declaration Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Return client errors on change pull request target errors Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Return error in commit.HasPreviousCommit Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Adds blank line Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Test patch before persisting new target branch Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Update patch before testing (not working) Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Removes patch calls when changeing pull request target Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Removes unneeded check for base name Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Moves ChangeTargetBranch completely to pull service. Update patch status. Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Set webhook mode after errors were validated Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Update PR in one transaction Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Move logic for check if head is equal with branch to pull model Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Adds missing comment and simplify return Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com> * Adjust CreateComment method call Signed-off-by: Mario Lubenka <mario.lubenka@googlemail.com>
3 years ago
Restricted users (#6274) * Restricted users (#4334): initial implementation * Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Mention restricted users in the faq Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert unnecessary change `.isUserPartOfOrg` -> `.IsUserPartOfOrg` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Remove unnecessary `org.IsOrganization()` call Signed-off-by: Manush Dodunekov <manush@stendahls.se> * Revert to an `int64` keyed `accessMap` * Add type `userAccess` * Add convenience func updateUserAccess() * Turn accessMap into a `map[int64]userAccess` Signed-off-by: Manush Dodunekov <manush@stendahls.se> * or even better: `map[int64]*userAccess` * updateUserAccess(): use tighter syntax as suggested by lafriks * even tighter * Avoid extra loop * Don't disclose limited orgs to unauthenticated users * Don't assume block only applies to orgs * Use an array of `VisibleType` for filtering * fix yet another thinko * Ok - no need for u * Revert "Ok - no need for u" This reverts commit 5c3e886aabd5acd997a3b35687d322439732c200. Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv>
3 years ago
Add Organization Wide Labels (#10814) * Add organization wide labels Implement organization wide labels similar to organization wide webhooks. This lets you create individual labels for organizations that can be used for all repos under that organization (so being able to reuse the same label across multiple repos). This makes it possible for small organizations with many repos to use labels effectively. Fixes #7406 * Add migration * remove comments * fix tests * Update options/locale/locale_en-US.ini Removed unused translation string * show org labels in issue search label filter * Use more clear var name * rename migration after merge from master * comment typo * update migration again after rebase with master * check for orgID <=0 per guillep2k review * fmt * Apply suggestions from code review Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * remove unused code * Make sure RepoID is 0 when searching orgID per code review * more changes/code review requests * More descriptive translation var per code review * func description/delete comment when issue label deleted instead of hiding it * remove comment * only use issues in that repo when calculating number of open issues for org label on repo label page * Add integration test for IssuesSearch API with labels * remove unused function * Update models/issue_label.go Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * Use subquery in GetLabelIDsInReposByNames * Fix tests to use correct orgID * fix more tests * IssuesSearch api now uses new BuildLabelNamesIssueIDsCondition. Add a few more tests as well * update comment for clarity * Revert previous code change now that we can use the new BuildLabelNamesIssueIDsCondition * Don't sort repos by date in IssuesSearch API After much debugging I've found a strange issue where in some cases MySQL will return a different result than other enigines if a query is sorted by a null collumn. For example with our integration test data where we don't set updated_unix in repository fixtures: SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 45 Returns different results for MySQL than other engines. However, the similar query: SELECT `id`, `owner_id`, `owner_name`, `lower_name`, `name`, `description`, `website`, `original_service_type`, `original_url`, `default_branch`, `num_watches`, `num_stars`, `num_forks`, `num_issues`, `num_closed_issues`, `num_pulls`, `num_closed_pulls`, `num_milestones`, `num_closed_milestones`, `is_private`, `is_empty`, `is_archived`, `is_mirror`, `status`, `is_fork`, `fork_id`, `is_template`, `template_id`, `size`, `is_fsck_enabled`, `close_issues_via_commit_in_any_branch`, `topics`, `avatar`, `created_unix`, `updated_unix` FROM `repository` ORDER BY updated_unix DESC LIMIT 15 OFFSET 30 Returns the same results. This causes integration tests to fail on MySQL in certain cases but would never show up in a real installation. Since this API call always returns issues based on the optionally provided repo_priority_id or the issueID itself, there is no change to results by changing the repo sorting method used to get ids earlier in the function. * linter is back! * code review * remove now unused option * Fix newline at end of files * more unused code * update to master * check for matching ids before query * Update models/issue_label.go Co-Authored-By: 6543 <6543@obermui.de> * Update models/issue_label.go * update comments * Update routers/org/setting.go Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Add configurable Trust Models (#11712) * Add configurable Trust Models Gitea's default signature verification model differs from GitHub. GitHub uses signatures to verify that the committer is who they say they are - meaning that when GitHub makes a signed commit it must be the committer. The GitHub model prevents re-publishing of commits after revocation of a key and prevents re-signing of other people's commits to create a completely trusted repository signed by one key or a set of trusted keys. The default behaviour of Gitea in contrast is to always display the avatar and information related to a signature. This allows signatures to be decoupled from the committer. That being said, allowing arbitary users to present other peoples commits as theirs is not necessarily desired therefore we have a trust model whereby signatures from collaborators are marked trusted, signatures matching the commit line are marked untrusted and signatures that match a user in the db but not the committer line are marked unmatched. The problem with this model is that this conflicts with Github therefore we need to provide an option to allow users to choose the Github model should they wish to. Signed-off-by: Andrew Thornton <art27@cantab.net> * Adjust locale strings Signed-off-by: Andrew Thornton <art27@cantab.net> * as per @6543 Co-authored-by: 6543 <6543@obermui.de> * Update models/gpg_key.go * Add migration for repository Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2 years ago
[Enhancement] Allow admin to merge pr with protected file changes (#12078) * [Enhancement] Allow admin to merge pr with protected file changes As tilte, show protected message in diff page and merge box. Signed-off-by: a1012112796 <1012112796@qq.com> * remove unused ver * Update options/locale/locale_en-US.ini Co-authored-by: Cirno the Strongest <1447794+CirnoT@users.noreply.github.com> * Add TrN * Apply suggestions from code review * fix lint * Update options/locale/locale_en-US.ini Co-authored-by: zeripath <art27@cantab.net> * Apply suggestions from code review * move pr proteced files check to TestPatch * Call TestPatch when protected branches settings changed * Apply review suggestion @CirnoT * move to service @lunny * slightly restructure routers/private/hook.go Adds a lot of comments and simplifies the logic Signed-off-by: Andrew Thornton <art27@cantab.net> * placate lint Signed-off-by: Andrew Thornton <art27@cantab.net> * skip duplicate protected files check * fix check logic * slight refactor of TestPatch Signed-off-by: Andrew Thornton <art27@cantab.net> * When checking for protected files changes in TestPatch use the temporary repository Signed-off-by: Andrew Thornton <art27@cantab.net> * fix introduced issue with hook Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove the check on PR index being greater than 0 as it unnecessary Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <matti@mdranta.net> Co-authored-by: Cirno the Strongest <1447794+CirnoT@users.noreply.github.com> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
4 years ago
Better logging (#6038) (#6095) * Panic don't fatal on create new logger Fixes #5854 Signed-off-by: Andrew Thornton <art27@cantab.net> * partial broken * Update the logging infrastrcture Signed-off-by: Andrew Thornton <art27@cantab.net> * Reset the skip levels for Fatal and Error Signed-off-by: Andrew Thornton <art27@cantab.net> * broken ncsa * More log.Error fixes Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove nal * set log-levels to lowercase * Make console_test test all levels * switch to lowercased levels * OK now working * Fix vetting issues * Fix lint * Fix tests * change default logging to match current gitea * Improve log testing Signed-off-by: Andrew Thornton <art27@cantab.net> * reset error skip levels to 0 * Update documentation and access logger configuration * Redirect the router log back to gitea if redirect macaron log but also allow setting the log level - i.e. TRACE * Fix broken level caching * Refactor the router log * Add Router logger * Add colorizing options * Adjust router colors * Only create logger if they will be used * update app.ini.sample * rename Attribute ColorAttribute * Change from white to green for function * Set fatal/error levels * Restore initial trace logger * Fix Trace arguments in modules/auth/auth.go * Properly handle XORMLogger * Improve admin/config page * fix fmt * Add auto-compression of old logs * Update error log levels * Remove the unnecessary skip argument from Error, Fatal and Critical * Add stacktrace support * Fix tests * Remove x/sync from vendors? * Add stderr option to console logger * Use filepath.ToSlash to protect against Windows in tests * Remove prefixed underscores from names in colors.go * Remove not implemented database logger This was removed from Gogs on 4 Mar 2016 but left in the configuration since then. * Ensure that log paths are relative to ROOT_PATH * use path.Join * rename jsonConfig to logConfig * Rename "config" to "jsonConfig" to make it clearer * Requested changes * Requested changes: XormLogger * Try to color the windows terminal If successful default to colorizing the console logs * fixup * Colorize initially too * update vendor * Colorize logs on default and remove if this is not a colorizing logger * Fix documentation * fix test * Use go-isatty to detect if on windows we are on msys or cygwin * Fix spelling mistake * Add missing vendors * More changes * Rationalise the ANSI writer protection * Adjust colors on advice from @0x5c * Make Flags a comma separated list * Move to use the windows constant for ENABLE_VIRTUAL_TERMINAL_PROCESSING * Ensure matching is done on the non-colored message - to simpify EXPRESSION
4 years ago
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2017 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package migrations
  6. import (
  7. "context"
  8. "fmt"
  9. "os"
  10. "reflect"
  11. "regexp"
  12. "strings"
  13. "code.gitea.io/gitea/modules/log"
  14. "code.gitea.io/gitea/modules/setting"
  15. "xorm.io/xorm"
  16. "xorm.io/xorm/names"
  17. "xorm.io/xorm/schemas"
  18. )
  19. const minDBVersion = 70 // Gitea 1.5.3
  20. // Migration describes on migration from lower version to high version
  21. type Migration interface {
  22. Description() string
  23. Migrate(*xorm.Engine) error
  24. }
  25. type migration struct {
  26. description string
  27. migrate func(*xorm.Engine) error
  28. }
  29. // NewMigration creates a new migration
  30. func NewMigration(desc string, fn func(*xorm.Engine) error) Migration {
  31. return &migration{desc, fn}
  32. }
  33. // Description returns the migration's description
  34. func (m *migration) Description() string {
  35. return m.description
  36. }
  37. // Migrate executes the migration
  38. func (m *migration) Migrate(x *xorm.Engine) error {
  39. return m.migrate(x)
  40. }
  41. // Version describes the version table. Should have only one row with id==1
  42. type Version struct {
  43. ID int64 `xorm:"pk autoincr"`
  44. Version int64
  45. }
  46. // This is a sequence of migrations. Add new migrations to the bottom of the list.
  47. // If you want to "retire" a migration, remove it from the top of the list and
  48. // update minDBVersion accordingly
  49. var migrations = []Migration{
  50. // Gitea 1.5.0 ends at v69
  51. // v70 -> v71
  52. NewMigration("add issue_dependencies", addIssueDependencies),
  53. // v71 -> v72
  54. NewMigration("protect each scratch token", addScratchHash),
  55. // v72 -> v73
  56. NewMigration("add review", addReview),
  57. // Gitea 1.6.0 ends at v73
  58. // v73 -> v74
  59. NewMigration("add must_change_password column for users table", addMustChangePassword),
  60. // v74 -> v75
  61. NewMigration("add approval whitelists to protected branches", addApprovalWhitelistsToProtectedBranches),
  62. // v75 -> v76
  63. NewMigration("clear nonused data which not deleted when user was deleted", clearNonusedData),
  64. // Gitea 1.7.0 ends at v76
  65. // v76 -> v77
  66. NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMerge),
  67. // v77 -> v78
  68. NewMigration("add theme to users", addUserDefaultTheme),
  69. // v78 -> v79
  70. NewMigration("rename repo is_bare to repo is_empty", renameRepoIsBareToIsEmpty),
  71. // v79 -> v80
  72. NewMigration("add can close issues via commit in any branch", addCanCloseIssuesViaCommitInAnyBranch),
  73. // v80 -> v81
  74. NewMigration("add is locked to issues", addIsLockedToIssues),
  75. // v81 -> v82
  76. NewMigration("update U2F counter type", changeU2FCounterType),
  77. // Gitea 1.8.0 ends at v82
  78. // v82 -> v83
  79. NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable),
  80. // v83 -> v84
  81. NewMigration("add uploader id for table attachment", addUploaderIDForAttachment),
  82. // v84 -> v85
  83. NewMigration("add table to store original imported gpg keys", addGPGKeyImport),
  84. // v85 -> v86
  85. NewMigration("hash application token", hashAppToken),
  86. // v86 -> v87
  87. NewMigration("add http method to webhook", addHTTPMethodToWebhook),
  88. // v87 -> v88
  89. NewMigration("add avatar field to repository", addAvatarFieldToRepository),
  90. // Gitea 1.9.0 ends at v88
  91. // v88 -> v89
  92. NewMigration("add commit status context field to commit_status", addCommitStatusContext),
  93. // v89 -> v90
  94. NewMigration("add original author/url migration info to issues, comments, and repo ", addOriginalMigrationInfo),
  95. // v90 -> v91
  96. NewMigration("change length of some repository columns", changeSomeColumnsLengthOfRepo),
  97. // v91 -> v92
  98. NewMigration("add index on owner_id of repository and type, review_id of comment", addIndexOnRepositoryAndComment),
  99. // v92 -> v93
  100. NewMigration("remove orphaned repository index statuses", removeLingeringIndexStatus),
  101. // v93 -> v94
  102. NewMigration("add email notification enabled preference to user", addEmailNotificationEnabledToUser),
  103. // v94 -> v95
  104. NewMigration("add enable_status_check, status_check_contexts to protected_branch", addStatusCheckColumnsForProtectedBranches),
  105. // v95 -> v96
  106. NewMigration("add table columns for cross referencing issues", addCrossReferenceColumns),
  107. // v96 -> v97
  108. NewMigration("delete orphaned attachments", deleteOrphanedAttachments),
  109. // v97 -> v98
  110. NewMigration("add repo_admin_change_team_access to user", addRepoAdminChangeTeamAccessColumnForUser),
  111. // v98 -> v99
  112. NewMigration("add original author name and id on migrated release", addOriginalAuthorOnMigratedReleases),
  113. // v99 -> v100
  114. NewMigration("add task table and status column for repository table", addTaskTable),
  115. // v100 -> v101
  116. NewMigration("update migration repositories' service type", updateMigrationServiceTypes),
  117. // v101 -> v102
  118. NewMigration("change length of some external login users columns", changeSomeColumnsLengthOfExternalLoginUser),
  119. // Gitea 1.10.0 ends at v102
  120. // v102 -> v103
  121. NewMigration("update migration repositories' service type", dropColumnHeadUserNameOnPullRequest),
  122. // v103 -> v104
  123. NewMigration("Add WhitelistDeployKeys to protected branch", addWhitelistDeployKeysToBranches),
  124. // v104 -> v105
  125. NewMigration("remove unnecessary columns from label", removeLabelUneededCols),
  126. // v105 -> v106
  127. NewMigration("add includes_all_repositories to teams", addTeamIncludesAllRepositories),
  128. // v106 -> v107
  129. NewMigration("add column `mode` to table watch", addModeColumnToWatch),
  130. // v107 -> v108
  131. NewMigration("Add template options to repository", addTemplateToRepo),
  132. // v108 -> v109
  133. NewMigration("Add comment_id on table notification", addCommentIDOnNotification),
  134. // v109 -> v110
  135. NewMigration("add can_create_org_repo to team", addCanCreateOrgRepoColumnForTeam),
  136. // v110 -> v111
  137. NewMigration("change review content type to text", changeReviewContentToText),
  138. // v111 -> v112
  139. NewMigration("update branch protection for can push and whitelist enable", addBranchProtectionCanPushAndEnableWhitelist),
  140. // v112 -> v113
  141. NewMigration("remove release attachments which repository deleted", removeAttachmentMissedRepo),
  142. // v113 -> v114
  143. NewMigration("new feature: change target branch of pull requests", featureChangeTargetBranch),
  144. // v114 -> v115
  145. NewMigration("Remove authentication credentials from stored URL", sanitizeOriginalURL),
  146. // v115 -> v116
  147. NewMigration("add user_id prefix to existing user avatar name", renameExistingUserAvatarName),
  148. // v116 -> v117
  149. NewMigration("Extend TrackedTimes", extendTrackedTimes),
  150. // Gitea 1.11.0 ends at v117
  151. // v117 -> v118
  152. NewMigration("Add block on rejected reviews branch protection", addBlockOnRejectedReviews),
  153. // v118 -> v119
  154. NewMigration("Add commit id and stale to reviews", addReviewCommitAndStale),
  155. // v119 -> v120
  156. NewMigration("Fix migrated repositories' git service type", fixMigratedRepositoryServiceType),
  157. // v120 -> v121
  158. NewMigration("Add owner_name on table repository", addOwnerNameOnRepository),
  159. // v121 -> v122
  160. NewMigration("add is_restricted column for users table", addIsRestricted),
  161. // v122 -> v123
  162. NewMigration("Add Require Signed Commits to ProtectedBranch", addRequireSignedCommits),
  163. // v123 -> v124
  164. NewMigration("Add original informations for reactions", addReactionOriginals),
  165. // v124 -> v125
  166. NewMigration("Add columns to user and repository", addUserRepoMissingColumns),
  167. // v125 -> v126
  168. NewMigration("Add some columns on review for migration", addReviewMigrateInfo),
  169. // v126 -> v127
  170. NewMigration("Fix topic repository count", fixTopicRepositoryCount),
  171. // v127 -> v128
  172. NewMigration("add repository code language statistics", addLanguageStats),
  173. // v128 -> v129
  174. NewMigration("fix merge base for pull requests", fixMergeBase),
  175. // v129 -> v130
  176. NewMigration("remove dependencies from deleted repositories", purgeUnusedDependencies),
  177. // v130 -> v131
  178. NewMigration("Expand webhooks for more granularity", expandWebhooks),
  179. // v131 -> v132
  180. NewMigration("Add IsSystemWebhook column to webhooks table", addSystemWebhookColumn),
  181. // v132 -> v133
  182. NewMigration("Add Branch Protection Protected Files Column", addBranchProtectionProtectedFilesColumn),
  183. // v133 -> v134
  184. NewMigration("Add EmailHash Table", addEmailHashTable),
  185. // v134 -> v135
  186. NewMigration("Refix merge base for merged pull requests", refixMergeBase),
  187. // v135 -> v136
  188. NewMigration("Add OrgID column to Labels table", addOrgIDLabelColumn),
  189. // v136 -> v137
  190. NewMigration("Add CommitsAhead and CommitsBehind Column to PullRequest Table", addCommitDivergenceToPulls),
  191. // v137 -> v138
  192. NewMigration("Add Branch Protection Block Outdated Branch", addBlockOnOutdatedBranch),
  193. // v138 -> v139
  194. NewMigration("Add ResolveDoerID to Comment table", addResolveDoerIDCommentColumn),
  195. // v139 -> v140
  196. NewMigration("prepend refs/heads/ to issue refs", prependRefsHeadsToIssueRefs),
  197. // Gitea 1.12.0 ends at v140
  198. // v140 -> v141
  199. NewMigration("Save detected language file size to database instead of percent", fixLanguageStatsToSaveSize),
  200. // v141 -> v142
  201. NewMigration("Add KeepActivityPrivate to User table", addKeepActivityPrivateUserColumn),
  202. // v142 -> v143
  203. NewMigration("Ensure Repository.IsArchived is not null", setIsArchivedToFalse),
  204. // v143 -> v144
  205. NewMigration("recalculate Stars number for all user", recalculateStars),
  206. // v144 -> v145
  207. NewMigration("update Matrix Webhook http method to 'PUT'", updateMatrixWebhookHTTPMethod),
  208. // v145 -> v146
  209. NewMigration("Increase Language field to 50 in LanguageStats", increaseLanguageField),
  210. // v146 -> v147
  211. NewMigration("Add projects info to repository table", addProjectsInfo),
  212. // v147 -> v148
  213. NewMigration("create review for 0 review id code comments", createReviewsForCodeComments),
  214. // v148 -> v149
  215. NewMigration("remove issue dependency comments who refer to non existing issues", purgeInvalidDependenciesComments),
  216. // v149 -> v150
  217. NewMigration("Add Created and Updated to Milestone table", addCreatedAndUpdatedToMilestones),
  218. // v150 -> v151
  219. NewMigration("add primary key to repo_topic", addPrimaryKeyToRepoTopic),
  220. // v151 -> v152
  221. NewMigration("set default password algorithm to Argon2", setDefaultPasswordToArgon2),
  222. // v152 -> v153
  223. NewMigration("add TrustModel field to Repository", addTrustModelToRepository),
  224. // v153 > v154
  225. NewMigration("add Team review request support", addTeamReviewRequestSupport),
  226. // v154 > v155
  227. NewMigration("add timestamps to Star, Label, Follow, Watch and Collaboration", addTimeStamps),
  228. // Gitea 1.13.0 ends at v155
  229. // v155 -> v156
  230. NewMigration("add changed_protected_files column for pull_request table", addChangedProtectedFilesPullRequestColumn),
  231. // v156 -> v157
  232. NewMigration("fix publisher ID for tag releases", fixPublisherIDforTagReleases),
  233. // v157 -> v158
  234. NewMigration("ensure repo topics are up-to-date", fixRepoTopics),
  235. // v158 -> v159
  236. NewMigration("code comment replies should have the commitID of the review they are replying to", updateCodeCommentReplies),
  237. // v159 -> v160
  238. NewMigration("update reactions constraint", updateReactionConstraint),
  239. // v160 -> v161
  240. NewMigration("Add block on official review requests branch protection", addBlockOnOfficialReviewRequests),
  241. // v161 -> v162
  242. NewMigration("Convert task type from int to string", convertTaskTypeToString),
  243. // v162 -> v163
  244. NewMigration("Convert webhook task type from int to string", convertWebhookTaskTypeToString),
  245. // v163 -> v164
  246. NewMigration("Convert topic name from 25 to 50", convertTopicNameFrom25To50),
  247. // v164 -> v165
  248. NewMigration("Add scope and nonce columns to oauth2_grant table", addScopeAndNonceColumnsToOAuth2Grant),
  249. // v165 -> v166
  250. NewMigration("Convert hook task type from char(16) to varchar(16) and trim the column", convertHookTaskTypeToVarcharAndTrim),
  251. // v166 -> v167
  252. NewMigration("Where Password is Valid with Empty String delete it", recalculateUserEmptyPWD),
  253. // v167 -> v168
  254. NewMigration("Add user redirect", addUserRedirect),
  255. // v168 -> v169
  256. NewMigration("Recreate user table to fix default values", recreateUserTableToFixDefaultValues),
  257. // v169 -> v170
  258. NewMigration("Update DeleteBranch comments to set the old_ref to the commit_sha", commentTypeDeleteBranchUseOldRef),
  259. // v170 -> v171
  260. NewMigration("Add Dismissed to Review table", addDismissedReviewColumn),
  261. // v171 -> v172
  262. NewMigration("Add Sorting to ProjectBoard table", addSortingColToProjectBoard),
  263. // v172 -> v173
  264. NewMigration("Add sessions table for go-chi/session", addSessionTable),
  265. // v173 -> v174
  266. NewMigration("Add time_id column to Comment", addTimeIDCommentColumn),
  267. // v174 -> v175
  268. NewMigration("Create repo transfer table", addRepoTransfer),
  269. // v175 -> v176
  270. NewMigration("Fix Postgres ID Sequences broken by recreate-table", fixPostgresIDSequences),
  271. // v176 -> v177
  272. NewMigration("Remove invalid labels from comments", removeInvalidLabels),
  273. // v177 -> v178
  274. NewMigration("Delete orphaned IssueLabels", deleteOrphanedIssueLabels),
  275. }
  276. // GetCurrentDBVersion returns the current db version
  277. func GetCurrentDBVersion(x *xorm.Engine) (int64, error) {
  278. if err := x.Sync(new(Version)); err != nil {
  279. return -1, fmt.Errorf("sync: %v", err)
  280. }
  281. currentVersion := &Version{ID: 1}
  282. has, err := x.Get(currentVersion)
  283. if err != nil {
  284. return -1, fmt.Errorf("get: %v", err)
  285. }
  286. if !has {
  287. return -1, nil
  288. }
  289. return currentVersion.Version, nil
  290. }
  291. // ExpectedVersion returns the expected db version
  292. func ExpectedVersion() int64 {
  293. return int64(minDBVersion + len(migrations))
  294. }
  295. // EnsureUpToDate will check if the db is at the correct version
  296. func EnsureUpToDate(x *xorm.Engine) error {
  297. currentDB, err := GetCurrentDBVersion(x)
  298. if err != nil {
  299. return err
  300. }
  301. if currentDB < 0 {
  302. return fmt.Errorf("Database has not been initialised")
  303. }
  304. if minDBVersion > currentDB {
  305. return fmt.Errorf("DB version %d (<= %d) is too old for auto-migration. Upgrade to Gitea 1.6.4 first then upgrade to this version", currentDB, minDBVersion)
  306. }
  307. expected := ExpectedVersion()
  308. if currentDB != expected {
  309. return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "gitea [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected)
  310. }
  311. return nil
  312. }
  313. // Migrate database to current version
  314. func Migrate(x *xorm.Engine) error {
  315. // Set a new clean the default mapper to GonicMapper as that is the default for Gitea.
  316. x.SetMapper(names.GonicMapper{})
  317. if err := x.Sync(new(Version)); err != nil {
  318. return fmt.Errorf("sync: %v", err)
  319. }
  320. currentVersion := &Version{ID: 1}
  321. has, err := x.Get(currentVersion)
  322. if err != nil {
  323. return fmt.Errorf("get: %v", err)
  324. } else if !has {
  325. // If the version record does not exist we think
  326. // it is a fresh installation and we can skip all migrations.
  327. currentVersion.ID = 0
  328. currentVersion.Version = int64(minDBVersion + len(migrations))
  329. if _, err = x.InsertOne(currentVersion); err != nil {
  330. return fmt.Errorf("insert: %v", err)
  331. }
  332. }
  333. v := currentVersion.Version
  334. if minDBVersion > v {
  335. log.Fatal(`Gitea no longer supports auto-migration from your previously installed version.
  336. Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`)
  337. return nil
  338. }
  339. // Downgrading Gitea's database version not supported
  340. if int(v-minDBVersion) > len(migrations) {
  341. msg := fmt.Sprintf("Downgrading database version from '%d' to '%d' is not supported and may result in loss of data integrity.\nIf you really know what you're doing, execute `UPDATE version SET version=%d WHERE id=1;`\n",
  342. v, minDBVersion+len(migrations), minDBVersion+len(migrations))
  343. fmt.Fprint(os.Stderr, msg)
  344. log.Fatal(msg)
  345. return nil
  346. }
  347. // Migrate
  348. for i, m := range migrations[v-minDBVersion:] {
  349. log.Info("Migration[%d]: %s", v+int64(i), m.Description())
  350. // Reset the mapper between each migration - migrations are not supposed to depend on each other
  351. x.SetMapper(names.GonicMapper{})
  352. if err = m.Migrate(x); err != nil {
  353. return fmt.Errorf("do migrate: %v", err)
  354. }
  355. currentVersion.Version = v + int64(i) + 1
  356. if _, err = x.ID(1).Update(currentVersion); err != nil {
  357. return err
  358. }
  359. }
  360. return nil
  361. }
  362. // RecreateTables will recreate the tables for the provided beans using the newly provided bean definition and move all data to that new table
  363. // WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION
  364. func RecreateTables(beans ...interface{}) func(*xorm.Engine) error {
  365. return func(x *xorm.Engine) error {
  366. sess := x.NewSession()
  367. defer sess.Close()
  368. if err := sess.Begin(); err != nil {
  369. return err
  370. }
  371. sess = sess.StoreEngine("InnoDB")
  372. for _, bean := range beans {
  373. log.Info("Recreating Table: %s for Bean: %s", x.TableName(bean), reflect.Indirect(reflect.ValueOf(bean)).Type().Name())
  374. if err := recreateTable(sess, bean); err != nil {
  375. return err
  376. }
  377. }
  378. return sess.Commit()
  379. }
  380. }
  381. // recreateTable will recreate the table using the newly provided bean definition and move all data to that new table
  382. // WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION
  383. // WARNING: YOU MUST COMMIT THE SESSION AT THE END
  384. func recreateTable(sess *xorm.Session, bean interface{}) error {
  385. // TODO: This will not work if there are foreign keys
  386. tableName := sess.Engine().TableName(bean)
  387. tempTableName := fmt.Sprintf("tmp_recreate__%s", tableName)
  388. // We need to move the old table away and create a new one with the correct columns
  389. // We will need to do this in stages to prevent data loss
  390. //
  391. // First create the temporary table
  392. if err := sess.Table(tempTableName).CreateTable(bean); err != nil {
  393. log.Error("Unable to create table %s. Error: %v", tempTableName, err)
  394. return err
  395. }
  396. if err := sess.Table(tempTableName).CreateUniques(bean); err != nil {
  397. log.Error("Unable to create uniques for table %s. Error: %v", tempTableName, err)
  398. return err
  399. }
  400. if err := sess.Table(tempTableName).CreateIndexes(bean); err != nil {
  401. log.Error("Unable to create indexes for table %s. Error: %v", tempTableName, err)
  402. return err
  403. }
  404. // Work out the column names from the bean - these are the columns to select from the old table and install into the new table
  405. table, err := sess.Engine().TableInfo(bean)
  406. if err != nil {
  407. log.Error("Unable to get table info. Error: %v", err)
  408. return err
  409. }
  410. newTableColumns := table.Columns()
  411. if len(newTableColumns) == 0 {
  412. return fmt.Errorf("no columns in new table")
  413. }
  414. hasID := false
  415. for _, column := range newTableColumns {
  416. hasID = hasID || (column.IsPrimaryKey && column.IsAutoIncrement)
  417. }
  418. if hasID && setting.Database.UseMSSQL {
  419. if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` ON", tempTableName)); err != nil {
  420. log.Error("Unable to set identity insert for table %s. Error: %v", tempTableName, err)
  421. return err
  422. }
  423. }
  424. sqlStringBuilder := &strings.Builder{}
  425. _, _ = sqlStringBuilder.WriteString("INSERT INTO `")
  426. _, _ = sqlStringBuilder.WriteString(tempTableName)
  427. _, _ = sqlStringBuilder.WriteString("` (`")
  428. _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
  429. _, _ = sqlStringBuilder.WriteString("`")
  430. for _, column := range newTableColumns[1:] {
  431. _, _ = sqlStringBuilder.WriteString(", `")
  432. _, _ = sqlStringBuilder.WriteString(column.Name)
  433. _, _ = sqlStringBuilder.WriteString("`")
  434. }
  435. _, _ = sqlStringBuilder.WriteString(")")
  436. _, _ = sqlStringBuilder.WriteString(" SELECT ")
  437. if newTableColumns[0].Default != "" {
  438. _, _ = sqlStringBuilder.WriteString("COALESCE(`")
  439. _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
  440. _, _ = sqlStringBuilder.WriteString("`, ")
  441. _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Default)
  442. _, _ = sqlStringBuilder.WriteString(")")
  443. } else {
  444. _, _ = sqlStringBuilder.WriteString("`")
  445. _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name)
  446. _, _ = sqlStringBuilder.WriteString("`")
  447. }
  448. for _, column := range newTableColumns[1:] {
  449. if column.Default != "" {
  450. _, _ = sqlStringBuilder.WriteString(", COALESCE(`")
  451. _, _ = sqlStringBuilder.WriteString(column.Name)
  452. _, _ = sqlStringBuilder.WriteString("`, ")
  453. _, _ = sqlStringBuilder.WriteString(column.Default)
  454. _, _ = sqlStringBuilder.WriteString(")")
  455. } else {
  456. _, _ = sqlStringBuilder.WriteString(", `")
  457. _, _ = sqlStringBuilder.WriteString(column.Name)
  458. _, _ = sqlStringBuilder.WriteString("`")
  459. }
  460. }
  461. _, _ = sqlStringBuilder.WriteString(" FROM `")
  462. _, _ = sqlStringBuilder.WriteString(tableName)
  463. _, _ = sqlStringBuilder.WriteString("`")
  464. if _, err := sess.Exec(sqlStringBuilder.String()); err != nil {
  465. log.Error("Unable to set copy data in to temp table %s. Error: %v", tempTableName, err)
  466. return err
  467. }
  468. if hasID && setting.Database.UseMSSQL {
  469. if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` OFF", tempTableName)); err != nil {
  470. log.Error("Unable to switch off identity insert for table %s. Error: %v", tempTableName, err)
  471. return err
  472. }
  473. }
  474. switch {
  475. case setting.Database.UseSQLite3:
  476. // SQLite will drop all the constraints on the old table
  477. if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
  478. log.Error("Unable to drop old table %s. Error: %v", tableName, err)
  479. return err
  480. }
  481. if err := sess.Table(tempTableName).DropIndexes(bean); err != nil {
  482. log.Error("Unable to drop indexes on temporary table %s. Error: %v", tempTableName, err)
  483. return err
  484. }
  485. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil {
  486. log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
  487. return err
  488. }
  489. if err := sess.Table(tableName).CreateIndexes(bean); err != nil {
  490. log.Error("Unable to recreate indexes on table %s. Error: %v", tableName, err)
  491. return err
  492. }
  493. if err := sess.Table(tableName).CreateUniques(bean); err != nil {
  494. log.Error("Unable to recreate uniques on table %s. Error: %v", tableName, err)
  495. return err
  496. }
  497. case setting.Database.UseMySQL:
  498. // MySQL will drop all the constraints on the old table
  499. if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
  500. log.Error("Unable to drop old table %s. Error: %v", tableName, err)
  501. return err
  502. }
  503. // SQLite and MySQL will move all the constraints from the temporary table to the new table
  504. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil {
  505. log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
  506. return err
  507. }
  508. case setting.Database.UsePostgreSQL:
  509. var originalSequences []string
  510. type sequenceData struct {
  511. LastValue int `xorm:"'last_value'"`
  512. IsCalled bool `xorm:"'is_called'"`
  513. }
  514. sequenceMap := map[string]sequenceData{}
  515. schema := sess.Engine().Dialect().URI().Schema
  516. sess.Engine().SetSchema("")
  517. if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE ? || '_%' AND sequence_catalog = ?", tableName, setting.Database.Name).Find(&originalSequences); err != nil {
  518. log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
  519. return err
  520. }
  521. sess.Engine().SetSchema(schema)
  522. for _, sequence := range originalSequences {
  523. sequenceData := sequenceData{}
  524. if _, err := sess.Table(sequence).Cols("last_value", "is_called").Get(&sequenceData); err != nil {
  525. log.Error("Unable to get last_value and is_called from %s. Error: %v", sequence, err)
  526. return err
  527. }
  528. sequenceMap[sequence] = sequenceData
  529. }
  530. // CASCADE causes postgres to drop all the constraints on the old table
  531. if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s` CASCADE", tableName)); err != nil {
  532. log.Error("Unable to drop old table %s. Error: %v", tableName, err)
  533. return err
  534. }
  535. // CASCADE causes postgres to move all the constraints from the temporary table to the new table
  536. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil {
  537. log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
  538. return err
  539. }
  540. var indices []string
  541. sess.Engine().SetSchema("")
  542. if err := sess.Table("pg_indexes").Cols("indexname").Where("tablename = ? ", tableName).Find(&indices); err != nil {
  543. log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
  544. return err
  545. }
  546. sess.Engine().SetSchema(schema)
  547. for _, index := range indices {
  548. newIndexName := strings.Replace(index, "tmp_recreate__", "", 1)
  549. if _, err := sess.Exec(fmt.Sprintf("ALTER INDEX `%s` RENAME TO `%s`", index, newIndexName)); err != nil {
  550. log.Error("Unable to rename %s to %s. Error: %v", index, newIndexName, err)
  551. return err
  552. }
  553. }
  554. var sequences []string
  555. sess.Engine().SetSchema("")
  556. if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE 'tmp_recreate__' || ? || '_%' AND sequence_catalog = ?", tableName, setting.Database.Name).Find(&sequences); err != nil {
  557. log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
  558. return err
  559. }
  560. sess.Engine().SetSchema(schema)
  561. for _, sequence := range sequences {
  562. newSequenceName := strings.Replace(sequence, "tmp_recreate__", "", 1)
  563. if _, err := sess.Exec(fmt.Sprintf("ALTER SEQUENCE `%s` RENAME TO `%s`", sequence, newSequenceName)); err != nil {
  564. log.Error("Unable to rename %s sequence to %s. Error: %v", sequence, newSequenceName, err)
  565. return err
  566. }
  567. val, ok := sequenceMap[newSequenceName]
  568. if newSequenceName == tableName+"_id_seq" {
  569. if ok && val.LastValue != 0 {
  570. if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', %d, %t)", newSequenceName, val.LastValue, val.IsCalled)); err != nil {
  571. log.Error("Unable to reset %s to %d. Error: %v", newSequenceName, val, err)
  572. return err
  573. }
  574. } else {
  575. // We're going to try to guess this
  576. if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', COALESCE((SELECT MAX(id)+1 FROM `%s`), 1), false)", newSequenceName, tableName)); err != nil {
  577. log.Error("Unable to reset %s. Error: %v", newSequenceName, err)
  578. return err
  579. }
  580. }
  581. } else if ok {
  582. if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', %d, %t)", newSequenceName, val.LastValue, val.IsCalled)); err != nil {
  583. log.Error("Unable to reset %s to %d. Error: %v", newSequenceName, val, err)
  584. return err
  585. }
  586. }
  587. }
  588. case setting.Database.UseMSSQL:
  589. // MSSQL will drop all the constraints on the old table
  590. if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
  591. log.Error("Unable to drop old table %s. Error: %v", tableName, err)
  592. return err
  593. }
  594. // MSSQL sp_rename will move all the constraints from the temporary table to the new table
  595. if _, err := sess.Exec(fmt.Sprintf("sp_rename `%s`,`%s`", tempTableName, tableName)); err != nil {
  596. log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err)
  597. return err
  598. }
  599. default:
  600. log.Fatal("Unrecognized DB")
  601. }
  602. return nil
  603. }
  604. // WARNING: YOU MUST COMMIT THE SESSION AT THE END
  605. func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...string) (err error) {
  606. if tableName == "" || len(columnNames) == 0 {
  607. return nil
  608. }
  609. // TODO: This will not work if there are foreign keys
  610. switch {
  611. case setting.Database.UseSQLite3:
  612. // First drop the indexes on the columns
  613. res, errIndex := sess.Query(fmt.Sprintf("PRAGMA index_list(`%s`)", tableName))
  614. if errIndex != nil {
  615. return errIndex
  616. }
  617. for _, row := range res {
  618. indexName := row["name"]
  619. indexRes, err := sess.Query(fmt.Sprintf("PRAGMA index_info(`%s`)", indexName))
  620. if err != nil {
  621. return err
  622. }
  623. if len(indexRes) != 1 {
  624. continue
  625. }
  626. indexColumn := string(indexRes[0]["name"])
  627. for _, name := range columnNames {
  628. if name == indexColumn {
  629. _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s`", indexName))
  630. if err != nil {
  631. return err
  632. }
  633. }
  634. }
  635. }
  636. // Here we need to get the columns from the original table
  637. sql := fmt.Sprintf("SELECT sql FROM sqlite_master WHERE tbl_name='%s' and type='table'", tableName)
  638. res, err := sess.Query(sql)
  639. if err != nil {
  640. return err
  641. }
  642. tableSQL := string(res[0]["sql"])
  643. // Separate out the column definitions
  644. tableSQL = tableSQL[strings.Index(tableSQL, "("):]
  645. // Remove the required columnNames
  646. for _, name := range columnNames {
  647. tableSQL = regexp.MustCompile(regexp.QuoteMeta("`"+name+"`")+"[^`,)]*?[,)]").ReplaceAllString(tableSQL, "")
  648. }
  649. // Ensure the query is ended properly
  650. tableSQL = strings.TrimSpace(tableSQL)
  651. if tableSQL[len(tableSQL)-1] != ')' {
  652. if tableSQL[len(tableSQL)-1] == ',' {
  653. tableSQL = tableSQL[:len(tableSQL)-1]
  654. }
  655. tableSQL += ")"
  656. }
  657. // Find all the columns in the table
  658. columns := regexp.MustCompile("`([^`]*)`").FindAllString(tableSQL, -1)
  659. tableSQL = fmt.Sprintf("CREATE TABLE `new_%s_new` ", tableName) + tableSQL
  660. if _, err := sess.Exec(tableSQL); err != nil {
  661. return err
  662. }
  663. // Now restore the data
  664. columnsSeparated := strings.Join(columns, ",")
  665. insertSQL := fmt.Sprintf("INSERT INTO `new_%s_new` (%s) SELECT %s FROM %s", tableName, columnsSeparated, columnsSeparated, tableName)
  666. if _, err := sess.Exec(insertSQL); err != nil {
  667. return err
  668. }
  669. // Now drop the old table
  670. if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil {
  671. return err
  672. }
  673. // Rename the table
  674. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `new_%s_new` RENAME TO `%s`", tableName, tableName)); err != nil {
  675. return err
  676. }
  677. case setting.Database.UsePostgreSQL:
  678. cols := ""
  679. for _, col := range columnNames {
  680. if cols != "" {
  681. cols += ", "
  682. }
  683. cols += "DROP COLUMN `" + col + "` CASCADE"
  684. }
  685. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
  686. return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
  687. }
  688. case setting.Database.UseMySQL:
  689. // Drop indexes on columns first
  690. sql := fmt.Sprintf("SHOW INDEX FROM %s WHERE column_name IN ('%s')", tableName, strings.Join(columnNames, "','"))
  691. res, err := sess.Query(sql)
  692. if err != nil {
  693. return err
  694. }
  695. for _, index := range res {
  696. indexName := index["column_name"]
  697. if len(indexName) > 0 {
  698. _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s` ON `%s`", indexName, tableName))
  699. if err != nil {
  700. return err
  701. }
  702. }
  703. }
  704. // Now drop the columns
  705. cols := ""
  706. for _, col := range columnNames {
  707. if cols != "" {
  708. cols += ", "
  709. }
  710. cols += "DROP COLUMN `" + col + "`"
  711. }
  712. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
  713. return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
  714. }
  715. case setting.Database.UseMSSQL:
  716. cols := ""
  717. for _, col := range columnNames {
  718. if cols != "" {
  719. cols += ", "
  720. }
  721. cols += "`" + strings.ToLower(col) + "`"
  722. }
  723. sql := fmt.Sprintf("SELECT Name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = OBJECT_ID('%[1]s') AND PARENT_COLUMN_ID IN (SELECT column_id FROM sys.columns WHERE lower(NAME) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))",
  724. tableName, strings.ReplaceAll(cols, "`", "'"))
  725. constraints := make([]string, 0)
  726. if err := sess.SQL(sql).Find(&constraints); err != nil {
  727. return fmt.Errorf("Find constraints: %v", err)
  728. }
  729. for _, constraint := range constraints {
  730. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil {
  731. return fmt.Errorf("Drop table `%s` constraint `%s`: %v", tableName, constraint, err)
  732. }
  733. }
  734. if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil {
  735. return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
  736. }
  737. default:
  738. log.Fatal("Unrecognized DB")
  739. }
  740. return nil
  741. }
  742. // modifyColumn will modify column's type or other propertity. SQLITE is not supported
  743. func modifyColumn(x *xorm.Engine, tableName string, col *schemas.Column) error {
  744. var indexes map[string]*schemas.Index
  745. var err error
  746. // MSSQL have to remove index at first, otherwise alter column will fail
  747. // ref. https://sqlzealots.com/2018/05/09/error-message-the-index-is-dependent-on-column-alter-table-alter-column-failed-because-one-or-more-objects-access-this-column/
  748. if x.Dialect().URI().DBType == schemas.MSSQL {
  749. indexes, err = x.Dialect().GetIndexes(x.DB(), context.Background(), tableName)
  750. if err != nil {
  751. return err
  752. }
  753. for _, index := range indexes {
  754. _, err = x.Exec(x.Dialect().DropIndexSQL(tableName, index))
  755. if err != nil {
  756. return err
  757. }
  758. }
  759. }
  760. defer func() {
  761. for _, index := range indexes {
  762. _, err = x.Exec(x.Dialect().CreateIndexSQL(tableName, index))
  763. if err != nil {
  764. log.Error("Create index %s on table %s failed: %v", index.Name, tableName, err)
  765. }
  766. }
  767. }()
  768. alterSQL := x.Dialect().ModifyColumnSQL(tableName, col)
  769. if _, err := x.Exec(alterSQL); err != nil {
  770. return err
  771. }
  772. return nil
  773. }