From 9119a94354cd15a7ee921e73dff14a24ad6e2492 Mon Sep 17 00:00:00 2001 From: hiifong Date: Wed, 12 Mar 2025 22:54:48 +0800 Subject: [PATCH 1/2] Update --- .dockerignore | 12 - .gitattributes | 2 - .github/workflows/cron-licenses.yml | 2 +- .github/workflows/pull-compliance.yml | 2 +- .github/workflows/pull-db-tests.yml | 6 +- .gitignore | 12 - CHANGELOG.md | 22 + Makefile | 36 +- build/generate-licenses.go | 176 - build/license/aliasgenerator.go | 41 - build/license/aliasgenerator_test.go | 39 - cmd/doctor.go | 5 +- cmd/hook.go | 2 +- cmd/migrate.go | 4 +- cmd/migrate_storage.go | 4 +- cmd/web_acme.go | 9 +- custom/conf/app.example.ini | 19 + go.mod | 8 +- go.sum | 16 +- models/actions/run.go | 20 +- models/actions/run_list.go | 2 +- models/actions/runner.go | 14 + models/actions/schedule.go | 22 +- models/actions/schedule_spec_list.go | 2 +- models/actions/variable.go | 14 + models/activities/action.go | 146 +- models/activities/action_test.go | 37 - models/asymkey/error.go | 2 +- models/auth/access_token_scope.go | 14 +- models/auth/access_token_scope_test.go | 5 +- models/db/context.go | 3 + models/db/engine_hook.go | 2 +- models/db/engine_init.go | 4 +- models/db/log.go | 2 +- models/db/name.go | 2 +- models/issues/issue.go | 3 + models/issues/issue_list.go | 2 +- models/issues/label.go | 9 + models/issues/milestone_test.go | 8 +- models/issues/pull_list.go | 9 +- models/issues/pull_list_test.go | 12 +- models/issues/reaction.go | 10 +- .../system_setting.yml | 24 + models/migrations/migrations.go | 4 +- models/migrations/v1_12/v128.go | 10 +- models/migrations/v1_12/v134.go | 6 +- models/migrations/v1_24/main_test.go | 14 + models/migrations/v1_24/v314.go | 19 + models/migrations/v1_24/v315.go | 98 + models/migrations/v1_24/v315_test.go | 27 + models/organization/org.go | 4 +- models/organization/org_test.go | 8 +- models/organization/org_user.go | 2 +- models/organization/team_list.go | 3 + models/packages/descriptor.go | 9 +- models/project/column.go | 3 + models/repo/archiver.go | 6 +- models/repo/org_repo.go | 37 +- models/repo/repo.go | 21 +- models/repo/repo_list.go | 5 - models/repo/user_repo.go | 2 +- models/secret/secret.go | 14 + models/user/must_change_password.go | 2 +- models/user/user.go | 12 +- models/user/user_list.go | 4 + models/webhook/webhook_test.go | 2 +- modules/base/tool.go | 22 - modules/fileicon/basic.go | 27 + modules/fileicon/material.go | 157 + modules/fileicon/material_test.go | 26 + modules/git/batch_reader.go | 12 +- modules/git/blame.go | 4 +- modules/git/blob.go | 20 +- modules/git/command.go | 44 +- modules/git/command_race_test.go | 8 +- modules/git/command_test.go | 24 +- modules/git/commit.go | 26 +- modules/git/commit_info_nogogit.go | 6 +- modules/git/config.go | 16 +- modules/git/diff.go | 12 +- modules/git/fsck.go | 2 +- modules/git/git.go | 2 +- modules/git/grep.go | 4 +- modules/git/log_name_status.go | 4 +- modules/git/pipeline/catfile.go | 10 +- modules/git/pipeline/lfs_nogogit.go | 2 +- modules/git/pipeline/namerev.go | 2 +- modules/git/pipeline/revlist.go | 8 +- modules/git/remote.go | 6 +- modules/git/repo.go | 34 +- modules/git/repo_archive.go | 4 +- modules/git/repo_attribute.go | 8 +- modules/git/repo_blame.go | 4 +- modules/git/repo_branch.go | 22 +- modules/git/repo_branch_nogogit.go | 2 +- modules/git/repo_commit.go | 66 +- modules/git/repo_commit_gogit.go | 2 +- modules/git/repo_commit_nogogit.go | 8 +- modules/git/repo_commitgraph.go | 2 +- modules/git/repo_compare.go | 48 +- modules/git/repo_gpg.go | 8 +- modules/git/repo_index.go | 20 +- modules/git/repo_object.go | 6 +- modules/git/repo_ref.go | 4 +- modules/git/repo_ref_nogogit.go | 2 +- modules/git/repo_stats.go | 6 +- modules/git/repo_tag.go | 12 +- modules/git/repo_tree.go | 4 +- modules/git/repo_tree_gogit.go | 2 +- modules/git/submodule.go | 6 +- modules/git/submodule_test.go | 6 +- modules/git/tree.go | 8 +- modules/git/tree_nogogit.go | 6 +- modules/gitrepo/branch.go | 6 +- modules/highlight/highlight.go | 3 +- modules/httplib/request.go | 7 + modules/httplib/url.go | 78 +- modules/httplib/url_test.go | 23 + modules/indexer/code/bleve/bleve.go | 2 +- .../code/elasticsearch/elasticsearch.go | 2 +- modules/indexer/code/git.go | 16 +- modules/indexer/code/gitgrep/gitgrep.go | 4 +- modules/lfstransfer/backend/backend.go | 12 +- modules/lfstransfer/backend/lock.go | 13 +- modules/lfstransfer/backend/util.go | 52 +- modules/lfstransfer/backend/util_test.go | 53 + modules/log/event_format.go | 30 +- modules/log/logger.go | 2 +- modules/log/logger_global.go | 2 +- modules/log/logger_impl.go | 33 +- modules/log/logger_test.go | 70 +- modules/log/manager_test.go | 2 +- modules/log/misc.go | 16 +- modules/markup/sanitizer_default_test.go | 4 + modules/packages/conda/metadata.go | 6 +- modules/private/internal.go | 4 + modules/reqctx/datastore.go | 5 +- modules/setting/config.go | 81 + modules/setting/mailer.go | 5 +- modules/setting/ui.go | 3 + modules/structs/hook.go | 15 + modules/structs/pull.go | 10 +- modules/structs/repo_actions.go | 37 + modules/templates/helper.go | 6 +- modules/templates/util_render.go | 15 +- modules/templates/util_render_legacy.go | 17 +- modules/templates/util_render_test.go | 23 +- modules/translation/i18n/errors.go | 13 - modules/translation/i18n/format.go | 3 +- modules/translation/i18n/localestore.go | 3 +- modules/util/error.go | 40 +- modules/util/util.go | 55 + modules/web/routing/logger.go | 27 +- modules/webhook/type.go | 4 +- options/fileicon/material-icon-rules.json | 9548 +++++++++++++ options/fileicon/material-icon-svgs.json | 1074 ++ options/license/389-exception | 7 - options/license/3D-Slicer-1.0 | 190 - options/license/AAL | 23 - options/license/ADSL | 1 - options/license/AFL-1.1 | 27 - options/license/AFL-1.2 | 28 - options/license/AFL-2.0 | 45 - options/license/AFL-2.1 | 45 - options/license/AFL-3.0 | 43 - options/license/AGPL-1.0-only | 86 - options/license/AGPL-1.0-or-later | 86 - options/license/{AGPL-3.0-only => AGPL-3.0} | 0 options/license/AGPL-3.0-or-later | 235 - options/license/AMD-newlib | 11 - options/license/AMDPLPA | 20 - options/license/AML | 9 - options/license/AML-glslang | 41 - options/license/AMPAS | 13 - options/license/ANTLR-PD | 5 - options/license/ANTLR-PD-fallback | 7 - options/license/APAFML | 3 - options/license/APL-1.0 | 295 - options/license/APSL-1.0 | 109 - options/license/APSL-1.1 | 108 - options/license/APSL-1.2 | 103 - options/license/APSL-2.0 | 102 - options/license/ASWF-Digital-Assets-1.0 | 17 - options/license/ASWF-Digital-Assets-1.1 | 17 - options/license/Abstyles | 11 - options/license/AdaCore-doc | 1 - options/license/Adobe-2006 | 12 - options/license/Adobe-Display-PostScript | 30 - options/license/Adobe-Glyph | 10 - options/license/Adobe-Utopia | 12 - options/license/Afmparse | 10 - options/license/Aladdin | 62 - options/license/Apache-1.0 | 20 - options/license/Apache-1.1 | 21 - options/license/App-s2p | 5 - options/license/Arphic-1999 | 58 - options/license/Artistic-1.0 | 49 - options/license/Artistic-1.0-Perl | 51 - options/license/Artistic-1.0-cl8 | 51 - options/license/Artistic-2.0 | 85 - options/license/Asterisk-exception | 5 - .../Asterisk-linking-protocols-exception | 13 - options/license/Autoconf-exception-2.0 | 5 - options/license/Autoconf-exception-3.0 | 26 - options/license/Autoconf-exception-generic | 4 - .../license/Autoconf-exception-generic-3.0 | 6 - options/license/Autoconf-exception-macro | 12 - options/license/BSD-1-Clause | 7 - options/license/BSD-2-Clause-Darwin | 28 - options/license/BSD-2-Clause-Patent | 19 - options/license/BSD-2-Clause-Views | 11 - options/license/BSD-2-Clause-first-lines | 27 - options/license/BSD-3-Clause-Attribution | 11 - options/license/BSD-3-Clause-HP | 23 - options/license/BSD-3-Clause-LBNL | 12 - options/license/BSD-3-Clause-Modification | 35 - .../license/BSD-3-Clause-No-Military-License | 16 - .../license/BSD-3-Clause-No-Nuclear-License | 14 - .../BSD-3-Clause-No-Nuclear-License-2014 | 16 - .../license/BSD-3-Clause-No-Nuclear-Warranty | 14 - options/license/BSD-3-Clause-Open-MPI | 34 - options/license/BSD-3-Clause-Sun | 29 - options/license/BSD-3-Clause-acpica | 26 - options/license/BSD-3-Clause-flex | 42 - options/license/BSD-4-Clause | 14 - options/license/BSD-4-Clause-Shortened | 13 - options/license/BSD-4-Clause-UC | 15 - options/license/BSD-4.3RENO | 9 - options/license/BSD-4.3TAHOE | 11 - .../license/BSD-Advertising-Acknowledgement | 37 - .../license/BSD-Attribution-HPND-disclaimer | 37 - options/license/BSD-Inferno-Nettverk | 41 - options/license/BSD-Protection | 53 - options/license/BSD-Source-Code | 10 - options/license/BSD-Source-beginning-file | 23 - options/license/BSD-Systemics | 39 - options/license/BSD-Systemics-W3Works | 62 - options/license/BUSL-1.1 | 71 - options/license/Baekmuk | 9 - options/license/Bahyph | 11 - options/license/Barr | 1 - options/license/Beerware | 1 - options/license/Bison-exception-1.24 | 4 - options/license/Bison-exception-2.2 | 5 - options/license/BitTorrent-1.0 | 330 - options/license/BitTorrent-1.1 | 137 - options/license/Bitstream-Charter | 9 - options/license/Bitstream-Vera | 15 - options/license/BlueOak-1.0.0 | 55 - options/license/Boehm-GC | 12 - options/license/Boehm-GC-without-fee | 14 - options/license/Bootloader-exception | 10 - options/license/Borceux | 19 - options/license/Brian-Gladman-2-Clause | 17 - options/license/Brian-Gladman-3-Clause | 26 - options/license/C-UDA-1.0 | 47 - options/license/CAL-1.0 | 354 - .../license/CAL-1.0-Combined-Work-Exception | 354 - options/license/CATOSL-1.1 | 114 - options/license/CC-BY-1.0 | 80 - options/license/CC-BY-2.0 | 81 - options/license/CC-BY-2.5 | 81 - options/license/CC-BY-2.5-AU | 112 - options/license/CC-BY-3.0 | 319 - options/license/CC-BY-3.0-AT | 111 - options/license/CC-BY-3.0-AU | 136 - options/license/CC-BY-3.0-DE | 108 - options/license/CC-BY-3.0-IGO | 101 - options/license/CC-BY-3.0-NL | 97 - options/license/CC-BY-3.0-US | 83 - options/license/CC-BY-NC-1.0 | 75 - options/license/CC-BY-NC-2.0 | 81 - options/license/CC-BY-NC-2.5 | 81 - options/license/CC-BY-NC-3.0 | 334 - options/license/CC-BY-NC-3.0-DE | 110 - options/license/CC-BY-NC-4.0 | 158 - options/license/CC-BY-NC-ND-1.0 | 75 - options/license/CC-BY-NC-ND-2.0 | 77 - options/license/CC-BY-NC-ND-2.5 | 77 - options/license/CC-BY-NC-ND-3.0 | 308 - options/license/CC-BY-NC-ND-3.0-DE | 101 - options/license/CC-BY-NC-ND-3.0-IGO | 99 - options/license/CC-BY-NC-ND-4.0 | 155 - options/license/CC-BY-NC-SA-1.0 | 83 - options/license/CC-BY-NC-SA-2.0 | 87 - options/license/CC-BY-NC-SA-2.0-DE | 85 - options/license/CC-BY-NC-SA-2.0-FR | 93 - options/license/CC-BY-NC-SA-2.0-UK | 149 - options/license/CC-BY-NC-SA-2.5 | 87 - options/license/CC-BY-NC-SA-3.0 | 360 - options/license/CC-BY-NC-SA-3.0-DE | 125 - options/license/CC-BY-NC-SA-3.0-IGO | 105 - options/license/CC-BY-NC-SA-4.0 | 170 - options/license/CC-BY-ND-1.0 | 73 - options/license/CC-BY-ND-2.0 | 75 - options/license/CC-BY-ND-2.5 | 75 - options/license/CC-BY-ND-3.0 | 293 - options/license/CC-BY-ND-3.0-DE | 100 - options/license/CC-BY-ND-4.0 | 154 - options/license/CC-BY-SA-1.0 | 81 - options/license/CC-BY-SA-2.0 | 85 - options/license/CC-BY-SA-2.0-UK | 147 - options/license/CC-BY-SA-2.1-JP | 83 - options/license/CC-BY-SA-2.5 | 85 - options/license/CC-BY-SA-3.0 | 359 - options/license/CC-BY-SA-3.0-AT | 139 - options/license/CC-BY-SA-3.0-DE | 135 - options/license/CC-BY-SA-3.0-IGO | 107 - options/license/CC-PDDC | 8 - options/license/CC-PDM-1.0 | 27 - options/license/CC-SA-1.0 | 198 - options/license/CDDL-1.0 | 119 - options/license/CDDL-1.1 | 123 - options/license/CDL-1.0 | 53 - options/license/CDLA-Permissive-1.0 | 85 - options/license/CDLA-Permissive-2.0 | 35 - options/license/CDLA-Sharing-1.0 | 89 - options/license/CECILL-1.0 | 216 - options/license/CECILL-1.1 | 229 - options/license/CECILL-2.0 | 506 - options/license/CECILL-2.1 | 518 - options/license/CECILL-B | 515 - options/license/CECILL-C | 517 - options/license/CERN-OHL-1.1 | 47 - options/license/CERN-OHL-1.2 | 48 - options/license/CERN-OHL-P-2.0 | 199 - options/license/CERN-OHL-S-2.0 | 289 - options/license/CERN-OHL-W-2.0 | 310 - options/license/CFITSIO | 7 - options/license/CGAL-linking-exception | 4 - options/license/CLISP-exception-2.0 | 15 - options/license/CMU-Mach | 22 - options/license/CMU-Mach-nodoc | 11 - options/license/CNRI-Jython | 12 - options/license/CNRI-Python | 25 - options/license/CNRI-Python-GPL-Compatible | 23 - options/license/COIL-1.0 | 30 - options/license/CPAL-1.0 | 172 - options/license/CPL-1.0 | 87 - options/license/CPOL-1.02 | 98 - options/license/CUA-OPL-1.0 | 143 - options/license/Caldera | 25 - options/license/Caldera-no-preamble | 35 - options/license/Catharon | 121 - options/license/ClArtistic | 61 - options/license/Classpath-exception-2.0 | 3 - options/license/Clips | 15 - options/license/Community-Spec-1.0 | 293 - options/license/Condor-1.1 | 38 - options/license/Cornell-Lossless-JPEG | 20 - options/license/Cronyx | 11 - options/license/Crossword | 5 - options/license/CrystalStacker | 7 - options/license/Cube | 17 - options/license/D-FSL-1.0 | 147 - options/license/DEC-3-Clause | 28 - options/license/DL-DE-BY-2.0 | 45 - options/license/DL-DE-ZERO-2.0 | 25 - options/license/DOC | 15 - options/license/DRL-1.0 | 12 - options/license/DRL-1.1 | 17 - options/license/DSDP | 18 - options/license/DigiRule-FOSS-exception | 54 - options/license/DocBook-Schema | 22 - options/license/DocBook-Stylesheet | 13 - options/license/DocBook-XML | 48 - options/license/Dotseqn | 5 - options/license/ECL-1.0 | 23 - options/license/ECL-2.0 | 98 - options/license/EFL-1.0 | 13 - options/license/EFL-2.0 | 9 - options/license/EPICS | 32 - options/license/EUDatagrid | 24 - options/license/EUPL-1.0 | 154 - options/license/EUPL-1.1 | 157 - options/license/Elastic-2.0 | 93 - options/license/Entessa | 22 - options/license/ErlPL-1.1 | 93 - options/license/Eurosym | 18 - options/license/FBM | 6 - options/license/FDK-AAC | 79 - options/license/FLTK-exception | 17 - options/license/FSFAP | 1 - options/license/FSFAP-no-warranty-disclaimer | 5 - options/license/FSFUL | 3 - options/license/FSFULLR | 3 - options/license/FSFULLRWD | 11 - options/license/FTL | 79 - options/license/Fair | 7 - options/license/Fawkes-Runtime-exception | 1 - options/license/Ferguson-Twofish | 15 - options/license/Font-exception-2.0 | 1 - options/license/Frameworx-1.0 | 69 - options/license/FreeBSD-DOC | 23 - options/license/FreeImage | 117 - options/license/Furuseth | 13 - options/license/GCC-exception-2.0 | 1 - options/license/GCC-exception-2.0-note | 16 - options/license/GCC-exception-3.1 | 33 - options/license/GCR-docs | 30 - options/license/GD | 24 - options/license/GFDL-1.1-invariants-only | 119 - options/license/GFDL-1.1-invariants-or-later | 119 - options/license/GFDL-1.1-no-invariants-only | 119 - .../license/GFDL-1.1-no-invariants-or-later | 119 - options/license/GFDL-1.1-only | 119 - options/license/GFDL-1.1-or-later | 119 - options/license/GFDL-1.2-invariants-only | 130 - options/license/GFDL-1.2-invariants-or-later | 130 - options/license/GFDL-1.2-no-invariants-only | 130 - .../license/GFDL-1.2-no-invariants-or-later | 130 - options/license/GFDL-1.2-only | 130 - options/license/GFDL-1.2-or-later | 130 - options/license/GFDL-1.3-invariants-only | 149 - options/license/GFDL-1.3-invariants-or-later | 149 - options/license/GFDL-1.3-no-invariants-only | 149 - .../license/GFDL-1.3-no-invariants-or-later | 149 - options/license/GFDL-1.3-only | 149 - options/license/GFDL-1.3-or-later | 149 - options/license/GL2PS | 13 - options/license/GLWTPL | 25 - options/license/GNAT-exception | 6 - options/license/GNOME-examples-exception | 1 - options/license/GNU-compiler-exception | 6 - options/license/GPL-1.0-only | 100 - options/license/GPL-1.0-or-later | 100 - options/license/{GPL-2.0-only => GPL-2.0} | 0 options/license/GPL-2.0-or-later | 117 - options/license/{GPL-3.0-only => GPL-3.0} | 0 options/license/GPL-3.0-389-ds-base-exception | 10 - options/license/GPL-3.0-interface-exception | 7 - options/license/GPL-3.0-linking-exception | 3 - .../license/GPL-3.0-linking-source-exception | 3 - options/license/GPL-3.0-or-later | 232 - options/license/GPL-CC-1.0 | 46 - options/license/GStreamer-exception-2005 | 1 - options/license/GStreamer-exception-2008 | 1 - options/license/Giftware | 9 - options/license/Glide | 95 - options/license/Glulxe | 3 - options/license/Gmsh-exception | 16 - options/license/Graphics-Gems | 5 - options/license/Gutmann | 2 - options/license/HIDAPI | 2 - options/license/HP-1986 | 10 - options/license/HP-1989 | 16 - options/license/HPND | 7 - options/license/HPND-DEC | 22 - options/license/HPND-Fenneberg-Livingston | 13 - options/license/HPND-INRIA-IMAG | 9 - options/license/HPND-Intel | 25 - options/license/HPND-Kevlin-Henney | 10 - options/license/HPND-MIT-disclaimer | 18 - options/license/HPND-Markus-Kuhn | 3 - options/license/HPND-Netrek | 10 - options/license/HPND-Pbmplus | 8 - options/license/HPND-UC | 8 - options/license/HPND-UC-export-US | 10 - options/license/HPND-doc | 8 - options/license/HPND-doc-sell | 9 - options/license/HPND-export-US | 5 - .../license/HPND-export-US-acknowledgement | 22 - options/license/HPND-export-US-modify | 24 - options/license/HPND-export2-US | 21 - options/license/HPND-merchantability-variant | 9 - .../license/HPND-sell-MIT-disclaimer-xserver | 12 - options/license/HPND-sell-regexpr | 9 - options/license/HPND-sell-variant | 19 - .../license/HPND-sell-variant-MIT-disclaimer | 20 - .../HPND-sell-variant-MIT-disclaimer-rev | 15 - options/license/HTMLTIDY | 13 - options/license/HaskellReport | 6 - options/license/Hippocratic-2.1 | 33 - options/license/IBM-pibs | 8 - options/license/ICU | 12 - options/license/IEC-Code-Components-EULA | 37 - options/license/IJG | 38 - options/license/IJG-short | 35 - options/license/IPA | 83 - options/license/IPL-1.0 | 215 - options/license/ISC-Veillard | 9 - options/license/ImageMagick | 98 - options/license/Imlib2 | 9 - options/license/Independent-modules-exception | 18 - options/license/Info-ZIP | 16 - options/license/Inner-Net-2.0 | 34 - options/license/InnoSetup | 27 - options/license/Intel | 13 - options/license/Intel-ACPI | 34 - options/license/Interbase-1.0 | 199 - options/license/JPL-image | 21 - options/license/JPNIC | 40 - options/license/JSON | 11 - options/license/Jam | 5 - options/license/JasPer-2.0 | 17 - options/license/Kastrup | 3 - options/license/Kazlib | 4 - options/license/KiCad-libraries-exception | 1 - options/license/Knuth-CTAN | 5 - options/license/LAL-1.2 | 67 - options/license/LAL-1.3 | 88 - options/license/LGPL-2.0-only | 175 - options/license/LGPL-2.0-or-later | 175 - options/license/{LGPL-2.1-only => LGPL-2.1} | 0 options/license/LGPL-2.1-or-later | 176 - options/license/{LGPL-3.0-only => LGPL-3.0} | 0 options/license/LGPL-3.0-linking-exception | 16 - options/license/LGPL-3.0-or-later | 304 - options/license/LGPLLR | 89 - options/license/LLGPL | 56 - options/license/LLVM-exception | 15 - options/license/LOOP | 44 - options/license/LPD-document | 8 - options/license/LPL-1.0 | 81 - options/license/LPL-1.02 | 85 - options/license/LPPL-1.0 | 103 - options/license/LPPL-1.1 | 141 - options/license/LPPL-1.2 | 139 - options/license/LPPL-1.3a | 175 - options/license/LPPL-1.3c | 184 - options/license/LZMA-SDK-9.11-to-9.20 | 8 - options/license/LZMA-SDK-9.22 | 15 - options/license/LZMA-exception | 3 - options/license/Latex2e | 9 - options/license/Latex2e-translated-notice | 26 - options/license/Leptonica | 9 - options/license/LiLiQ-P-1.1 | 70 - options/license/LiLiQ-R-1.1 | 94 - options/license/LiLiQ-Rplus-1.1 | 88 - options/license/Libpng | 76 - options/license/Libtool-exception | 1 - options/license/Linux-OpenIB | 18 - options/license/Linux-man-pages-1-para | 4 - options/license/Linux-man-pages-copyleft | 21 - .../license/Linux-man-pages-copyleft-2-para | 8 - options/license/Linux-man-pages-copyleft-var | 16 - options/license/Linux-syscall-note | 12 - options/license/Lucida-Bitmap-Fonts | 53 - options/license/MIPS | 4 - options/license/MIT-CMU | 7 - options/license/MIT-Click | 30 - options/license/MIT-Festival | 22 - options/license/MIT-Khronos-old | 23 - options/license/MIT-Modern-Variant | 17 - options/license/MIT-Wu | 28 - options/license/MIT-advertising | 7 - options/license/MIT-enna | 9 - options/license/MIT-feh | 5 - options/license/MIT-open-group | 23 - options/license/MIT-testregex | 17 - options/license/MITNFA | 7 - options/license/MMIXware | 17 - options/license/MPEG-SSG | 23 - options/license/MPL-1.0 | 123 - options/license/MPL-1.1 | 143 - options/license/MPL-2.0-no-copyleft-exception | 373 - options/license/MS-LPL | 24 - options/license/MS-PL | 22 - options/license/MS-RL | 30 - options/license/MTLL | 24 - options/license/Mackerras-3-Clause | 25 - .../license/Mackerras-3-Clause-acknowledgment | 25 - options/license/MakeIndex | 19 - options/license/Martin-Birgmeier | 5 - options/license/McPhee-slideshow | 6 - options/license/Minpack | 51 - options/license/MirOS | 7 - options/license/Motosoto | 372 - options/license/MulanPSL-1.0 | 116 - options/license/Multics | 13 - options/license/Mup | 13 - options/license/NAIST-2003 | 70 - options/license/NASA-1.3 | 85 - options/license/NBPL-1.0 | 59 - options/license/NCBI-PD | 19 - options/license/NCGL-UK-2.0 | 67 - options/license/NCL | 32 - options/license/NCSA | 15 - options/license/NGPL | 21 - options/license/NICTA-1.0 | 61 - options/license/NIST-PD | 15 - options/license/NIST-PD-fallback | 5 - options/license/NIST-Software | 28 - options/license/NLOD-1.0 | 79 - options/license/NLOD-2.0 | 80 - options/license/NLPL | 14 - options/license/NOSL | 150 - options/license/NPL-1.0 | 102 - options/license/NPL-1.1 | 186 - options/license/NPOSL-3.0 | 59 - options/license/NRL | 28 - options/license/NTP | 5 - options/license/NTP-0 | 5 - options/license/Naumen | 21 - options/license/NetCDF | 7 - options/license/Newsletr | 7 - options/license/Nokia | 159 - options/license/Nokia-Qt-exception-1.1 | 16 - options/license/Noweb | 9 - options/license/O-UDA-1.0 | 47 - options/license/OAR | 12 - options/license/OCCT-PL | 112 - options/license/OCCT-exception-1.0 | 3 - options/license/OCLC-2.0 | 76 - options/license/OCaml-LGPL-linking-exception | 1 - options/license/ODC-By-1.0 | 195 - options/license/ODbL-1.0 | 540 - options/license/OFFIS | 22 - options/license/OFL-1.0 | 49 - options/license/OFL-1.0-RFN | 49 - options/license/OFL-1.0-no-RFN | 49 - options/license/OFL-1.1-RFN | 43 - options/license/OFL-1.1-no-RFN | 43 - options/license/OGC-1.0 | 17 - options/license/OGDL-Taiwan-1.0 | 141 - options/license/OGL-Canada-2.0 | 51 - options/license/OGL-UK-1.0 | 69 - options/license/OGL-UK-2.0 | 72 - options/license/OGL-UK-3.0 | 69 - options/license/OGTSL | 55 - options/license/OLDAP-1.1 | 60 - options/license/OLDAP-1.2 | 60 - options/license/OLDAP-1.3 | 62 - options/license/OLDAP-1.4 | 62 - options/license/OLDAP-2.0 | 18 - options/license/OLDAP-2.0.1 | 18 - options/license/OLDAP-2.1 | 20 - options/license/OLDAP-2.2 | 22 - options/license/OLDAP-2.2.1 | 22 - options/license/OLDAP-2.2.2 | 24 - options/license/OLDAP-2.3 | 24 - options/license/OLDAP-2.4 | 22 - options/license/OLDAP-2.5 | 22 - options/license/OLDAP-2.6 | 20 - options/license/OLDAP-2.7 | 20 - options/license/OLDAP-2.8 | 20 - options/license/OLFL-1.3 | 220 - options/license/OML | 5 - options/license/OPL-1.0 | 136 - options/license/OPL-UK-3.0 | 114 - options/license/OPUBL-1.0 | 78 - options/license/OSET-PL-2.1 | 162 - options/license/OSL-1.0 | 45 - options/license/OSL-1.1 | 47 - options/license/OSL-2.0 | 47 - options/license/OSL-2.1 | 47 - .../license/OpenJDK-assembly-exception-1.0 | 31 - options/license/OpenPBS-2.3 | 76 - options/license/OpenSSL | 48 - options/license/OpenSSL-standalone | 50 - options/license/OpenVision | 33 - options/license/PADL | 6 - options/license/PCRE2-exception | 8 - options/license/PDDL-1.0 | 136 - options/license/PHP-3.0 | 28 - options/license/PHP-3.01 | 27 - options/license/PPL | 96 - .../license/PS-or-PDF-font-exception-20170817 | 8 - options/license/PSF-2.0 | 47 - options/license/Parity-6.0.0 | 44 - options/license/Parity-7.0.0 | 71 - options/license/Pixar | 174 - options/license/Plexus | 15 - options/license/PolyForm-Noncommercial-1.0.0 | 131 - options/license/PolyForm-Small-Business-1.0.0 | 121 - options/license/PostgreSQL | 12 - options/license/Python-2.0 | 72 - options/license/Python-2.0.1 | 193 - options/license/QPL-1.0 | 50 - options/license/QPL-1.0-INRIA-2004 | 102 - options/license/QPL-1.0-INRIA-2004-exception | 5 - options/license/Qhull | 17 - options/license/Qt-GPL-exception-1.0 | 21 - options/license/Qt-LGPL-exception-1.1 | 22 - options/license/Qwt-exception-1.0 | 12 - options/license/RHeCos-1.1 | 137 - options/license/RPL-1.1 | 177 - options/license/RPL-1.5 | 167 - options/license/RPSL-1.0 | 179 - options/license/RRDtool-FLOSS-exception-2.0 | 66 - options/license/RSA-MD | 9 - options/license/RSCPL | 128 - options/license/Rdisc | 13 - options/license/Ruby | 29 - options/license/Ruby-pty | 10 - options/license/SANE-exception | 20 - options/license/SAX-PD | 31 - options/license/SAX-PD-2.0 | 10 - options/license/SCEA | 60 - options/license/SGI-B-1.0 | 82 - options/license/SGI-B-1.1 | 84 - options/license/SGI-B-2.0 | 12 - options/license/SGI-OpenGL | 34 - options/license/SGP4 | 1 - options/license/SHL-0.5 | 64 - options/license/SHL-0.51 | 65 - options/license/SHL-2.0 | 22 - options/license/SHL-2.1 | 45 - options/license/SISSL | 116 - options/license/SISSL-1.2 | 113 - options/license/SL | 4 - options/license/SMAIL-GPL | 144 - options/license/SMLNJ | 7 - options/license/SMPPL | 29 - options/license/SNIA | 122 - options/license/SPL-1.0 | 149 - options/license/SSH-OpenSSH | 67 - options/license/SSH-short | 5 - options/license/SSLeay-standalone | 58 - options/license/SSPL-1.0 | 557 - options/license/SWI-exception | 6 - options/license/SWL | 7 - options/license/Saxpath | 19 - options/license/SchemeReport | 3 - options/license/Sendmail | 36 - options/license/Sendmail-8.23 | 36 - options/license/Sendmail-Open-Source-1.1 | 75 - options/license/SimPL-2.0 | 37 - options/license/Sleepycat | 37 - options/license/Soundex | 9 - options/license/Spencer-86 | 9 - options/license/Spencer-94 | 12 - options/license/Spencer-99 | 9 - options/license/SugarCRM-1.1.3 | 149 - options/license/Sun-PPP | 13 - options/license/Sun-PPP-2000 | 13 - options/license/SunPro | 6 - options/license/Swift-exception | 6 - options/license/Symlinks | 10 - options/license/TAPR-OHL-1.0 | 266 - options/license/TCL | 9 - options/license/TCP-wrappers | 7 - options/license/TGPPL-1.0 | 181 - options/license/TMate | 21 - options/license/TORQUE-1.1 | 25 - options/license/TOSL | 9 - options/license/TPDL | 2 - options/license/TPL-1.0 | 475 - options/license/TTWL | 8 - options/license/TTYP0 | 29 - options/license/TU-Berlin-1.0 | 10 - options/license/TU-Berlin-2.0 | 20 - options/license/TermReadKey | 1 - options/license/Texinfo-exception | 4 - options/license/ThirdEye | 7 - options/license/TrustedQSL | 58 - options/license/UBDL-exception | 59 - options/license/UCAR | 32 - options/license/UCL-1.0 | 48 - options/license/UMich-Merit | 19 - options/license/URT-RLE | 15 - options/license/Ubuntu-font-1.0 | 96 - options/license/Unicode-3.0 | 39 - options/license/Unicode-DFS-2015 | 19 - options/license/Unicode-DFS-2016 | 22 - options/license/Unicode-TOU | 51 - options/license/Universal-FOSS-exception-1.0 | 11 - options/license/UnixCrypt | 6 - options/license/VOSTROM | 27 - options/license/VSL-1.0 | 18 - options/license/Vim | 30 - options/license/W3C | 29 - options/license/W3C-19980720 | 23 - options/license/W3C-20150513 | 17 - options/license/Watcom-1.0 | 106 - options/license/Widget-Workshop | 19 - options/license/Wsuipa | 5 - options/license/WxWindows-exception-3.1 | 9 - options/license/X11 | 13 - .../X11-distribute-modifications-variant | 25 - options/license/X11-swapped | 23 - options/license/XFree86-1.1 | 16 - options/license/XSkat | 10 - options/license/Xdebug-1.03 | 60 - options/license/Xerox | 5 - options/license/Xfig | 7 - options/license/Xnet | 11 - options/license/YPL-1.0 | 47 - options/license/YPL-1.1 | 47 - options/license/ZPL-1.1 | 33 - options/license/ZPL-2.0 | 23 - options/license/ZPL-2.1 | 21 - options/license/Zed | 3 - options/license/Zeeff | 3 - options/license/Zend-2.0 | 18 - options/license/Zimbra-1.3 | 47 - options/license/Zimbra-1.4 | 47 - options/license/any-OSI | 3 - options/license/any-OSI-perl-modules | 11 - options/license/bcrypt-Solar-Designer | 11 - options/license/blessing | 5 - options/license/bzip2-1.0.6 | 15 - options/license/check-cvs | 2 - options/license/checkmk | 9 - options/license/copyleft-next-0.3.0 | 219 - options/license/copyleft-next-0.3.1 | 220 - options/license/cryptsetup-OpenSSL-exception | 12 - options/license/curl | 10 - options/license/cve-tou | 16 - options/license/diffmark | 2 - options/license/dtoa | 14 - options/license/dvipdfm | 1 - options/license/eCos-exception-2.0 | 3 - options/license/eGenix | 40 - options/license/erlang-otp-linking-exception | 11 - options/license/etalab-2.0 | 179 - options/license/etc/license-aliases.json | 1 - options/license/fmt-exception | 6 - options/license/freertos-exception-2.0 | 19 - options/license/fwlw | 5 - options/license/gSOAP-1.3b | 148 - options/license/generic-xts | 17 - options/license/gnu-javamail-exception | 1 - options/license/gnuplot | 14 - options/license/gtkbook | 6 - options/license/harbour-exception | 23 - options/license/hdparm | 9 - options/license/i2p-gpl-java-exception | 1 - options/license/iMatix | 39 - options/license/libpng-2.0 | 33 - options/license/libpri-OpenH323-exception | 4 - options/license/libselinux-1.0 | 21 - options/license/libtiff | 8 - options/license/libutil-David-Nugent | 15 - options/license/lsof | 26 - options/license/magaz | 4 - options/license/mailprio | 9 - options/license/metamail | 12 - options/license/mif-exception | 1 - options/license/mpi-permissive | 15 - options/license/mpich2 | 24 - options/license/mplus | 6 - options/license/mxml-exception | 16 - options/license/openvpn-openssl-exception | 3 - options/license/pkgconf | 7 - options/license/pnmstitch | 23 - options/license/psfrag | 5 - options/license/psutils | 29 - options/license/python-ldap | 10 - options/license/radvd | 37 - options/license/romic-exception | 6 - options/license/snprintf | 3 - options/license/softSurfer | 6 - options/license/ssh-keyscan | 5 - options/license/stunnel-exception | 5 - options/license/swrule | 1 - options/license/threeparttable | 3 - options/license/u-boot-exception-2.0 | 6 - options/license/ulem | 4 - options/license/vsftpd-openssl-exception | 5 - options/license/w3m | 11 - options/license/wwl | 5 - options/license/x11vnc-openssl-exception | 9 - options/license/xinetd | 25 - options/license/xkeyboard-config-Zinoviev | 15 - options/license/xlock | 14 - options/license/xpp | 21 - options/license/xzoom | 12 - options/license/zlib-acknowledgement | 15 - options/locale/locale_cs-CZ.ini | 3 - options/locale/locale_de-DE.ini | 20 +- options/locale/locale_el-GR.ini | 3 - options/locale/locale_en-US.ini | 31 +- options/locale/locale_es-ES.ini | 2 - options/locale/locale_fa-IR.ini | 1 - options/locale/locale_fr-FR.ini | 3 - options/locale/locale_ga-IE.ini | 4 +- options/locale/locale_hu-HU.ini | 1 - options/locale/locale_it-IT.ini | 1 - options/locale/locale_ja-JP.ini | 3 - options/locale/locale_lv-LV.ini | 3 - options/locale/locale_nl-NL.ini | 1 - options/locale/locale_pl-PL.ini | 1 - options/locale/locale_pt-BR.ini | 2 - options/locale/locale_pt-PT.ini | 3 - options/locale/locale_ru-RU.ini | 3 - options/locale/locale_si-LK.ini | 1 - options/locale/locale_tr-TR.ini | 3 - options/locale/locale_uk-UA.ini | 1 - options/locale/locale_zh-CN.ini | 3 - options/locale/locale_zh-TW.ini | 3 - package-lock.json | 110 + package.json | 1 + .../img/svg/material-folder-generic.svg | 1 + .../img/svg/material-folder-symlink.svg | 1 + routers/api/actions/runner/runner.go | 7 +- routers/api/packages/composer/api.go | 22 +- routers/api/v1/misc/licenses.go | 1 - routers/api/v1/repo/branch.go | 38 +- routers/api/v1/repo/issue.go | 2 +- routers/api/v1/repo/pull.go | 14 +- routers/api/v1/repo/repo.go | 3 +- routers/api/v1/utils/hook.go | 1 + routers/common/db.go | 7 +- routers/install/install.go | 4 +- routers/private/hook_pre_receive.go | 2 +- routers/private/hook_verification.go | 10 +- routers/web/admin/config.go | 31 + routers/web/admin/packages.go | 4 +- routers/web/explore/code.go | 4 +- routers/web/explore/org.go | 4 +- routers/web/explore/repo.go | 10 +- routers/web/explore/user.go | 10 +- routers/web/feed/convert.go | 8 +- routers/web/home.go | 4 +- routers/web/org/home.go | 4 +- routers/web/org/members.go | 4 +- routers/web/org/projects.go | 6 +- routers/web/repo/actions/view.go | 30 +- routers/web/repo/blame.go | 2 +- routers/web/repo/commit.go | 27 +- routers/web/repo/compare.go | 24 +- routers/web/repo/editor.go | 2 +- routers/web/repo/githttp.go | 18 +- routers/web/repo/issue_content_history.go | 2 +- routers/web/repo/issue_list.go | 6 +- routers/web/repo/issue_poster.go | 4 +- routers/web/repo/milestone.go | 4 +- routers/web/repo/packages.go | 4 +- routers/web/repo/projects.go | 6 +- routers/web/repo/pull.go | 67 +- routers/web/repo/search.go | 4 +- routers/web/repo/setting/lfs.go | 8 +- routers/web/repo/setting/protected_branch.go | 20 +- routers/web/repo/setting/setting.go | 3 +- routers/web/repo/setting/webhook.go | 1 + routers/web/repo/treelist.go | 32 + routers/web/shared/user/header.go | 4 +- routers/web/user/code.go | 4 +- routers/web/user/home.go | 12 +- routers/web/user/home_test.go | 16 +- routers/web/user/notification.go | 6 +- routers/web/user/package.go | 8 +- routers/web/user/profile.go | 10 +- routers/web/user/search.go | 2 +- routers/web/user/setting/applications.go | 34 +- routers/web/user/setting/profile.go | 8 +- routers/web/web.go | 1 + services/actions/clear_tasks.go | 35 +- services/actions/job_emitter.go | 7 + services/actions/notifier_helper.go | 10 +- services/actions/schedule_tasks.go | 14 +- services/actions/task.go | 8 +- services/actions/workflow.go | 16 +- services/agit/agit.go | 4 +- services/asymkey/sign.go | 8 +- services/context/access_log.go | 2 +- services/context/access_log_test.go | 2 +- services/context/context.go | 11 +- services/convert/git_commit.go | 10 +- services/convert/pull.go | 30 +- services/doctor/dbconsistency.go | 19 + services/doctor/dbversion.go | 3 +- services/doctor/doctor.go | 8 +- services/doctor/heads.go | 6 +- services/doctor/mergebase.go | 10 +- services/doctor/misc.go | 4 +- services/feed/feed.go | 127 + services/feed/feed_test.go | 37 + services/feed/notifier.go | 38 +- services/forms/admin_config_form.go | 44 + services/forms/repo_form.go | 8 +- services/forms/user_form.go | 11 +- services/forms/user_form_test.go | 27 - services/gitdiff/git_diff_tree.go | 4 +- services/gitdiff/gitdiff.go | 505 +- services/gitdiff/gitdiff_test.go | 35 +- services/gitdiff/highlightdiff.go | 94 +- services/gitdiff/highlightdiff_test.go | 147 +- services/issue/reaction_test.go | 10 +- services/mailer/mail.go | 548 +- services/mailer/mail_comment.go | 10 +- services/mailer/mail_issue.go | 109 +- services/mailer/mail_issue_common.go | 336 + services/mailer/mail_release.go | 9 +- services/mailer/mail_repo.go | 3 + services/mailer/mail_team_invite.go | 4 +- services/mailer/mail_test.go | 179 +- services/mailer/mail_user.go | 161 + services/migrations/dump.go | 8 +- services/migrations/gitea_uploader.go | 10 +- services/migrations/gitea_uploader_test.go | 6 +- services/mirror/mirror_pull.go | 34 +- services/mirror/mirror_push.go | 14 +- services/notify/notifier.go | 3 + services/notify/notify.go | 7 + services/notify/null.go | 4 + services/org/user.go | 2 +- services/packages/cargo/index.go | 28 +- services/packages/package_update.go | 17 +- services/pull/check.go | 10 +- services/pull/merge.go | 10 +- services/pull/merge_ff_only.go | 2 +- services/pull/merge_merge.go | 2 +- services/pull/merge_prepare.go | 22 +- services/pull/merge_rebase.go | 12 +- services/pull/merge_squash.go | 6 +- services/pull/patch.go | 24 +- services/pull/patch_unmerged.go | 4 +- services/pull/protected_branch.go | 48 + services/pull/pull.go | 27 +- services/pull/review.go | 2 +- services/pull/reviewer.go | 2 +- services/pull/temp_repo.go | 20 +- services/pull/update_rebase.go | 6 +- services/release/release.go | 14 +- services/repository/adopt.go | 4 +- services/repository/branch.go | 5 +- services/repository/check.go | 4 +- services/repository/contributors_graph.go | 4 +- services/repository/create.go | 12 +- services/repository/files/cherry_pick.go | 14 +- services/repository/files/diff.go | 12 +- services/repository/files/diff_test.go | 5 - services/repository/files/patch.go | 16 +- services/repository/files/temp_repo.go | 88 +- services/repository/files/update.go | 28 +- services/repository/files/upload.go | 24 +- services/repository/fork.go | 8 +- services/repository/generate.go | 8 +- services/repository/gitgraph/graph.go | 10 +- services/repository/gitgraph/graph_test.go | 2 +- services/repository/init.go | 12 +- services/repository/license.go | 49 +- services/repository/license_test.go | 10 +- services/repository/migrate.go | 14 +- services/repository/push.go | 4 +- services/repository/setting.go | 3 +- services/versioned_migration/migration.go | 24 + services/webhook/deliver.go | 23 +- services/webhook/dingtalk.go | 6 + services/webhook/discord.go | 6 + services/webhook/feishu.go | 6 + services/webhook/general.go | 41 +- services/webhook/matrix.go | 13 +- services/webhook/msteams.go | 14 + services/webhook/notifier.go | 114 + services/webhook/packagist.go | 4 + services/webhook/payloader.go | 5 +- services/webhook/slack.go | 6 + services/webhook/telegram.go | 6 + services/webhook/wechatwork.go | 6 + services/webtheme/webtheme.go | 136 +- services/webtheme/webtheme_test.go | 37 + services/wiki/wiki.go | 2 +- templates/admin/config_settings.tmpl | 116 + templates/admin/org/list.tmpl | 2 +- templates/base/alert.tmpl | 16 +- templates/base/head.tmpl | 6 - templates/base/paginate.tmpl | 2 +- templates/org/home.tmpl | 2 +- templates/package/shared/list.tmpl | 4 +- templates/package/shared/versionlist.tmpl | 2 +- templates/package/view.tmpl | 4 +- templates/projects/list.tmpl | 4 +- templates/repo/actions/list.tmpl | 2 +- templates/repo/actions/runs_list.tmpl | 2 +- templates/repo/branch_dropdown.tmpl | 3 +- templates/repo/clone_panel.tmpl | 1 + templates/repo/commits_list.tmpl | 4 +- templates/repo/create.tmpl | 6 +- templates/repo/diff/blob_excerpt.tmpl | 6 +- templates/repo/diff/box.tmpl | 40 +- templates/repo/diff/image_diff.tmpl | 12 +- templates/repo/diff/options_dropdown.tmpl | 1 - templates/repo/diff/section_split.tmpl | 8 +- templates/repo/diff/section_unified.tmpl | 2 +- templates/repo/editor/edit.tmpl | 4 +- templates/repo/graph/commits.tmpl | 2 +- templates/repo/issue/card.tmpl | 4 +- templates/repo/issue/fields/markdown.tmpl | 2 +- templates/repo/issue/filter_actions.tmpl | 2 +- templates/repo/issue/milestone_issues.tmpl | 2 +- templates/repo/issue/milestones.tmpl | 4 +- templates/repo/issue/new_form.tmpl | 7 +- .../issue/sidebar/allow_maintainer_edit.tmpl | 15 +- .../repo/issue/sidebar/assignee_list.tmpl | 2 +- .../issue/sidebar/issue_dependencies.tmpl | 47 +- .../repo/issue/sidebar/participant_list.tmpl | 2 +- .../repo/issue/sidebar/reviewer_list.tmpl | 2 +- templates/repo/issue/sidebar/wip_switch.tmpl | 8 +- .../repo/issue/view_content/add_reaction.tmpl | 2 +- .../repo/issue/view_content/comments.tmpl | 8 +- .../repo/issue/view_content/context_menu.tmpl | 6 +- .../repo/issue/view_content/conversation.tmpl | 2 +- templates/repo/issue/view_content/pull.tmpl | 4 +- .../view_content/pull_merge_instruction.tmpl | 98 +- .../repo/issue/view_content/reactions.tmpl | 8 +- .../view_content/update_branch_by_merge.tmpl | 2 +- templates/repo/issue/view_title.tmpl | 8 +- templates/repo/latest_commit.tmpl | 4 +- templates/repo/migrate/codebase.tmpl | 6 +- templates/repo/migrate/codecommit.tmpl | 6 +- templates/repo/migrate/git.tmpl | 6 +- templates/repo/migrate/gitbucket.tmpl | 6 +- templates/repo/migrate/gitea.tmpl | 6 +- templates/repo/migrate/github.tmpl | 6 +- templates/repo/migrate/gitlab.tmpl | 6 +- templates/repo/migrate/gogs.tmpl | 6 +- templates/repo/migrate/onedev.tmpl | 6 +- templates/repo/pulls/fork.tmpl | 6 +- templates/repo/pulls/tab_menu.tmpl | 6 +- templates/repo/release/list.tmpl | 5 +- templates/repo/search_name.tmpl | 2 +- templates/repo/settings/lfs_file.tmpl | 4 +- templates/repo/settings/tags.tmpl | 2 +- templates/repo/settings/webhook/settings.tmpl | 14 + templates/repo/view_file.tmpl | 4 +- templates/repo/view_list.tmpl | 4 +- templates/repo/wiki/view.tmpl | 8 +- templates/shared/combomarkdowneditor.tmpl | 2 +- templates/shared/issuelist.tmpl | 6 +- templates/shared/search/code/results.tmpl | 2 +- templates/shared/user/authorlink.tmpl | 2 +- templates/shared/user/blocked_users.tmpl | 2 +- templates/shared/user/namelink.tmpl | 2 +- templates/shared/user/profile_big_avatar.tmpl | 2 +- templates/status/500.tmpl | 1 + templates/swagger/v1_json.tmpl | 6 + templates/user/auth/signin_inner.tmpl | 2 + templates/user/dashboard/feeds.tmpl | 2 +- templates/user/dashboard/milestones.tmpl | 6 +- templates/user/dashboard/navbar.tmpl | 6 +- templates/user/profile.tmpl | 2 +- templates/user/settings/appearance.tmpl | 2 +- templates/user/settings/applications.tmpl | 76 +- .../settings/applications_oauth2_list.tmpl | 54 +- .../api_activitypub_person_test.go | 53 +- tests/integration/api_admin_org_test.go | 53 +- tests/integration/api_admin_test.go | 4 +- .../api_helper_for_declarative_test.go | 4 + tests/integration/api_issue_test.go | 8 +- tests/integration/api_nodeinfo_test.go | 34 +- .../integration/api_packages_composer_test.go | 35 + tests/integration/api_pull_test.go | 40 +- tests/integration/api_repo_git_blobs_test.go | 2 +- tests/integration/api_repo_git_tags_test.go | 4 +- tests/integration/api_repo_git_trees_test.go | 2 +- tests/integration/git_general_test.go | 24 +- .../git_helper_for_declarative_test.go | 16 +- tests/integration/git_lfs_ssh_test.go | 9 +- tests/integration/git_misc_test.go | 12 +- tests/integration/git_push_test.go | 4 +- tests/integration/integration_test.go | 50 +- tests/integration/issue_test.go | 12 +- .../migration-test/migration_test.go | 7 +- tests/integration/org_count_test.go | 7 +- tests/integration/pull_commit_test.go | 41 +- tests/integration/pull_create_test.go | 2 +- tests/integration/pull_merge_test.go | 18 +- tests/integration/repo_tag_test.go | 22 +- tests/integration/repo_test.go | 12 +- tests/integration/repo_webhook_test.go | 155 +- tests/integration/setting_test.go | 20 +- tests/integration/user_avatar_test.go | 91 +- tests/mssql.ini.tmpl | 1 + tests/mysql.ini.tmpl | 1 + tests/pgsql.ini.tmpl | 1 + tests/sqlite.ini.tmpl | 1 + tools/generate-svg-vscode-extensions.json | 570 + tools/generate-svg.js | 86 +- web_src/css/admin.css | 8 + web_src/css/editor/fileeditor.css | 9 - web_src/css/form.css | 4 + web_src/css/index.css | 2 +- web_src/css/markup/content.css | 2 +- web_src/css/modules/checkbox.css | 10 + web_src/css/modules/select.css | 25 - web_src/css/modules/svg.css | 4 + web_src/css/modules/tab.css | 7 + web_src/css/repo.css | 4 - web_src/css/repo/release-tag.css | 2 +- web_src/css/shared/milestone.css | 2 +- ...eme-gitea-auto-protanopia-deuteranopia.css | 4 + web_src/css/themes/theme-gitea-auto.css | 4 + ...eme-gitea-dark-protanopia-deuteranopia.css | 4 + web_src/css/themes/theme-gitea-dark.css | 4 + ...me-gitea-light-protanopia-deuteranopia.css | 4 + web_src/css/themes/theme-gitea-light.css | 4 + web_src/fomantic/.npmrc | 7 - web_src/fomantic/build/components/api.js | 1169 ++ .../fomantic/build/components/dropdown.css | 1755 +++ web_src/fomantic/build/components/dropdown.js | 4239 ++++++ web_src/fomantic/build/components/form.css | 1643 +++ web_src/fomantic/build/components/modal.css | 703 + web_src/fomantic/build/components/modal.js | 1209 ++ web_src/fomantic/build/components/search.css | 520 + web_src/fomantic/build/components/search.js | 1565 +++ web_src/fomantic/build/fomantic.css | 4 + web_src/fomantic/build/fomantic.js | 6 + web_src/fomantic/build/semantic.css | 5250 -------- web_src/fomantic/build/semantic.js | 11238 ---------------- .../themes/default/assets/fonts/icons.woff2 | Bin 79444 -> 0 bytes .../default/assets/fonts/outline-icons.woff2 | Bin 13584 -> 0 bytes web_src/fomantic/package-lock.json | 8777 ------------ web_src/fomantic/package.json | 5 - web_src/fomantic/theme.config.less | 19 +- web_src/js/components/DiffFileList.vue | 60 - web_src/js/components/DiffFileTree.vue | 72 +- web_src/js/components/DiffFileTreeItem.vue | 67 +- .../components/ScopedAccessTokenSelector.vue | 81 - web_src/js/features/admin/common.ts | 199 +- web_src/js/features/autofocus-end.ts | 6 - web_src/js/features/common-button.ts | 25 +- web_src/js/features/common-page.ts | 100 +- web_src/js/features/comp/ReactionSelector.ts | 48 +- web_src/js/features/copycontent.ts | 12 +- web_src/js/features/imagediff.ts | 2 +- web_src/js/features/repo-commit.ts | 15 +- web_src/js/features/repo-common.ts | 49 +- web_src/js/features/repo-diff-filetree.ts | 9 - web_src/js/features/repo-diff.ts | 189 +- web_src/js/features/repo-editor.ts | 4 +- web_src/js/features/repo-graph.ts | 5 +- web_src/js/features/repo-issue-edit.ts | 3 - web_src/js/features/repo-issue.ts | 237 +- web_src/js/features/repo-legacy.ts | 17 +- web_src/js/features/repo-settings.ts | 78 +- web_src/js/features/repo-wiki.ts | 4 +- web_src/js/features/scoped-access-token.ts | 20 - web_src/js/features/user-auth-webauthn.ts | 11 +- web_src/js/globals.d.ts | 11 +- web_src/js/index.ts | 84 +- web_src/js/markup/asciicast.ts | 18 +- web_src/js/markup/codecopy.ts | 17 +- web_src/js/markup/content.ts | 25 +- web_src/js/markup/math.ts | 42 +- web_src/js/markup/mermaid.ts | 126 +- web_src/js/markup/tasklist.ts | 124 +- web_src/js/modules/dirauto.ts | 44 - web_src/js/modules/fomantic.ts | 6 +- web_src/js/modules/fomantic/api.ts | 41 - web_src/js/modules/fomantic/tab.ts | 19 + web_src/js/modules/init.ts | 26 + web_src/js/modules/observer.ts | 110 + web_src/js/modules/stores.ts | 9 +- web_src/js/render/pdf.ts | 10 +- web_src/js/standalone/swagger.ts | 4 +- web_src/js/utils.test.ts | 8 +- web_src/js/utils.ts | 6 + web_src/js/utils/dom.ts | 2 +- web_src/js/utils/filetree.test.ts | 86 + web_src/js/utils/filetree.ts | 85 + web_src/svg/material-folder-generic.svg | 1 + web_src/svg/material-folder-symlink.svg | 1 + webpack.config.js | 4 +- 1246 files changed, 30540 insertions(+), 70188 deletions(-) delete mode 100644 build/generate-licenses.go delete mode 100644 build/license/aliasgenerator.go delete mode 100644 build/license/aliasgenerator_test.go create mode 100644 models/migrations/fixtures/Test_MigrateIniToDatabase/system_setting.yml create mode 100644 models/migrations/v1_24/main_test.go create mode 100644 models/migrations/v1_24/v314.go create mode 100644 models/migrations/v1_24/v315.go create mode 100644 models/migrations/v1_24/v315_test.go create mode 100644 modules/fileicon/basic.go create mode 100644 modules/fileicon/material.go create mode 100644 modules/fileicon/material_test.go create mode 100644 modules/lfstransfer/backend/util_test.go delete mode 100644 modules/translation/i18n/errors.go create mode 100644 options/fileicon/material-icon-rules.json create mode 100644 options/fileicon/material-icon-svgs.json delete mode 100644 options/license/389-exception delete mode 100644 options/license/3D-Slicer-1.0 delete mode 100644 options/license/AAL delete mode 100644 options/license/ADSL delete mode 100644 options/license/AFL-1.1 delete mode 100644 options/license/AFL-1.2 delete mode 100644 options/license/AFL-2.0 delete mode 100644 options/license/AFL-2.1 delete mode 100644 options/license/AFL-3.0 delete mode 100644 options/license/AGPL-1.0-only delete mode 100644 options/license/AGPL-1.0-or-later rename options/license/{AGPL-3.0-only => AGPL-3.0} (100%) delete mode 100644 options/license/AGPL-3.0-or-later delete mode 100644 options/license/AMD-newlib delete mode 100644 options/license/AMDPLPA delete mode 100644 options/license/AML delete mode 100644 options/license/AML-glslang delete mode 100644 options/license/AMPAS delete mode 100644 options/license/ANTLR-PD delete mode 100644 options/license/ANTLR-PD-fallback delete mode 100644 options/license/APAFML delete mode 100644 options/license/APL-1.0 delete mode 100644 options/license/APSL-1.0 delete mode 100644 options/license/APSL-1.1 delete mode 100644 options/license/APSL-1.2 delete mode 100644 options/license/APSL-2.0 delete mode 100644 options/license/ASWF-Digital-Assets-1.0 delete mode 100644 options/license/ASWF-Digital-Assets-1.1 delete mode 100644 options/license/Abstyles delete mode 100644 options/license/AdaCore-doc delete mode 100644 options/license/Adobe-2006 delete mode 100644 options/license/Adobe-Display-PostScript delete mode 100644 options/license/Adobe-Glyph delete mode 100644 options/license/Adobe-Utopia delete mode 100644 options/license/Afmparse delete mode 100644 options/license/Aladdin delete mode 100644 options/license/Apache-1.0 delete mode 100644 options/license/Apache-1.1 delete mode 100644 options/license/App-s2p delete mode 100644 options/license/Arphic-1999 delete mode 100644 options/license/Artistic-1.0 delete mode 100644 options/license/Artistic-1.0-Perl delete mode 100644 options/license/Artistic-1.0-cl8 delete mode 100644 options/license/Artistic-2.0 delete mode 100644 options/license/Asterisk-exception delete mode 100644 options/license/Asterisk-linking-protocols-exception delete mode 100644 options/license/Autoconf-exception-2.0 delete mode 100644 options/license/Autoconf-exception-3.0 delete mode 100644 options/license/Autoconf-exception-generic delete mode 100644 options/license/Autoconf-exception-generic-3.0 delete mode 100644 options/license/Autoconf-exception-macro delete mode 100644 options/license/BSD-1-Clause delete mode 100644 options/license/BSD-2-Clause-Darwin delete mode 100644 options/license/BSD-2-Clause-Patent delete mode 100644 options/license/BSD-2-Clause-Views delete mode 100644 options/license/BSD-2-Clause-first-lines delete mode 100644 options/license/BSD-3-Clause-Attribution delete mode 100644 options/license/BSD-3-Clause-HP delete mode 100644 options/license/BSD-3-Clause-LBNL delete mode 100644 options/license/BSD-3-Clause-Modification delete mode 100644 options/license/BSD-3-Clause-No-Military-License delete mode 100644 options/license/BSD-3-Clause-No-Nuclear-License delete mode 100644 options/license/BSD-3-Clause-No-Nuclear-License-2014 delete mode 100644 options/license/BSD-3-Clause-No-Nuclear-Warranty delete mode 100644 options/license/BSD-3-Clause-Open-MPI delete mode 100644 options/license/BSD-3-Clause-Sun delete mode 100644 options/license/BSD-3-Clause-acpica delete mode 100644 options/license/BSD-3-Clause-flex delete mode 100644 options/license/BSD-4-Clause delete mode 100644 options/license/BSD-4-Clause-Shortened delete mode 100644 options/license/BSD-4-Clause-UC delete mode 100644 options/license/BSD-4.3RENO delete mode 100644 options/license/BSD-4.3TAHOE delete mode 100644 options/license/BSD-Advertising-Acknowledgement delete mode 100644 options/license/BSD-Attribution-HPND-disclaimer delete mode 100644 options/license/BSD-Inferno-Nettverk delete mode 100644 options/license/BSD-Protection delete mode 100644 options/license/BSD-Source-Code delete mode 100644 options/license/BSD-Source-beginning-file delete mode 100644 options/license/BSD-Systemics delete mode 100644 options/license/BSD-Systemics-W3Works delete mode 100644 options/license/BUSL-1.1 delete mode 100644 options/license/Baekmuk delete mode 100644 options/license/Bahyph delete mode 100644 options/license/Barr delete mode 100644 options/license/Beerware delete mode 100644 options/license/Bison-exception-1.24 delete mode 100644 options/license/Bison-exception-2.2 delete mode 100644 options/license/BitTorrent-1.0 delete mode 100644 options/license/BitTorrent-1.1 delete mode 100644 options/license/Bitstream-Charter delete mode 100644 options/license/Bitstream-Vera delete mode 100644 options/license/BlueOak-1.0.0 delete mode 100644 options/license/Boehm-GC delete mode 100644 options/license/Boehm-GC-without-fee delete mode 100644 options/license/Bootloader-exception delete mode 100644 options/license/Borceux delete mode 100644 options/license/Brian-Gladman-2-Clause delete mode 100644 options/license/Brian-Gladman-3-Clause delete mode 100644 options/license/C-UDA-1.0 delete mode 100644 options/license/CAL-1.0 delete mode 100644 options/license/CAL-1.0-Combined-Work-Exception delete mode 100644 options/license/CATOSL-1.1 delete mode 100644 options/license/CC-BY-1.0 delete mode 100644 options/license/CC-BY-2.0 delete mode 100644 options/license/CC-BY-2.5 delete mode 100644 options/license/CC-BY-2.5-AU delete mode 100644 options/license/CC-BY-3.0 delete mode 100644 options/license/CC-BY-3.0-AT delete mode 100644 options/license/CC-BY-3.0-AU delete mode 100644 options/license/CC-BY-3.0-DE delete mode 100644 options/license/CC-BY-3.0-IGO delete mode 100644 options/license/CC-BY-3.0-NL delete mode 100644 options/license/CC-BY-3.0-US delete mode 100644 options/license/CC-BY-NC-1.0 delete mode 100644 options/license/CC-BY-NC-2.0 delete mode 100644 options/license/CC-BY-NC-2.5 delete mode 100644 options/license/CC-BY-NC-3.0 delete mode 100644 options/license/CC-BY-NC-3.0-DE delete mode 100644 options/license/CC-BY-NC-4.0 delete mode 100644 options/license/CC-BY-NC-ND-1.0 delete mode 100644 options/license/CC-BY-NC-ND-2.0 delete mode 100644 options/license/CC-BY-NC-ND-2.5 delete mode 100644 options/license/CC-BY-NC-ND-3.0 delete mode 100644 options/license/CC-BY-NC-ND-3.0-DE delete mode 100644 options/license/CC-BY-NC-ND-3.0-IGO delete mode 100644 options/license/CC-BY-NC-ND-4.0 delete mode 100644 options/license/CC-BY-NC-SA-1.0 delete mode 100644 options/license/CC-BY-NC-SA-2.0 delete mode 100644 options/license/CC-BY-NC-SA-2.0-DE delete mode 100644 options/license/CC-BY-NC-SA-2.0-FR delete mode 100644 options/license/CC-BY-NC-SA-2.0-UK delete mode 100644 options/license/CC-BY-NC-SA-2.5 delete mode 100644 options/license/CC-BY-NC-SA-3.0 delete mode 100644 options/license/CC-BY-NC-SA-3.0-DE delete mode 100644 options/license/CC-BY-NC-SA-3.0-IGO delete mode 100644 options/license/CC-BY-NC-SA-4.0 delete mode 100644 options/license/CC-BY-ND-1.0 delete mode 100644 options/license/CC-BY-ND-2.0 delete mode 100644 options/license/CC-BY-ND-2.5 delete mode 100644 options/license/CC-BY-ND-3.0 delete mode 100644 options/license/CC-BY-ND-3.0-DE delete mode 100644 options/license/CC-BY-ND-4.0 delete mode 100644 options/license/CC-BY-SA-1.0 delete mode 100644 options/license/CC-BY-SA-2.0 delete mode 100644 options/license/CC-BY-SA-2.0-UK delete mode 100644 options/license/CC-BY-SA-2.1-JP delete mode 100644 options/license/CC-BY-SA-2.5 delete mode 100644 options/license/CC-BY-SA-3.0 delete mode 100644 options/license/CC-BY-SA-3.0-AT delete mode 100644 options/license/CC-BY-SA-3.0-DE delete mode 100644 options/license/CC-BY-SA-3.0-IGO delete mode 100644 options/license/CC-PDDC delete mode 100644 options/license/CC-PDM-1.0 delete mode 100644 options/license/CC-SA-1.0 delete mode 100644 options/license/CDDL-1.0 delete mode 100644 options/license/CDDL-1.1 delete mode 100644 options/license/CDL-1.0 delete mode 100644 options/license/CDLA-Permissive-1.0 delete mode 100644 options/license/CDLA-Permissive-2.0 delete mode 100644 options/license/CDLA-Sharing-1.0 delete mode 100644 options/license/CECILL-1.0 delete mode 100644 options/license/CECILL-1.1 delete mode 100644 options/license/CECILL-2.0 delete mode 100644 options/license/CECILL-2.1 delete mode 100644 options/license/CECILL-B delete mode 100644 options/license/CECILL-C delete mode 100644 options/license/CERN-OHL-1.1 delete mode 100644 options/license/CERN-OHL-1.2 delete mode 100644 options/license/CERN-OHL-P-2.0 delete mode 100644 options/license/CERN-OHL-S-2.0 delete mode 100644 options/license/CERN-OHL-W-2.0 delete mode 100644 options/license/CFITSIO delete mode 100644 options/license/CGAL-linking-exception delete mode 100644 options/license/CLISP-exception-2.0 delete mode 100644 options/license/CMU-Mach delete mode 100644 options/license/CMU-Mach-nodoc delete mode 100644 options/license/CNRI-Jython delete mode 100644 options/license/CNRI-Python delete mode 100644 options/license/CNRI-Python-GPL-Compatible delete mode 100644 options/license/COIL-1.0 delete mode 100644 options/license/CPAL-1.0 delete mode 100644 options/license/CPL-1.0 delete mode 100644 options/license/CPOL-1.02 delete mode 100644 options/license/CUA-OPL-1.0 delete mode 100644 options/license/Caldera delete mode 100644 options/license/Caldera-no-preamble delete mode 100644 options/license/Catharon delete mode 100644 options/license/ClArtistic delete mode 100644 options/license/Classpath-exception-2.0 delete mode 100644 options/license/Clips delete mode 100644 options/license/Community-Spec-1.0 delete mode 100644 options/license/Condor-1.1 delete mode 100644 options/license/Cornell-Lossless-JPEG delete mode 100644 options/license/Cronyx delete mode 100644 options/license/Crossword delete mode 100644 options/license/CrystalStacker delete mode 100644 options/license/Cube delete mode 100644 options/license/D-FSL-1.0 delete mode 100644 options/license/DEC-3-Clause delete mode 100644 options/license/DL-DE-BY-2.0 delete mode 100644 options/license/DL-DE-ZERO-2.0 delete mode 100644 options/license/DOC delete mode 100644 options/license/DRL-1.0 delete mode 100644 options/license/DRL-1.1 delete mode 100644 options/license/DSDP delete mode 100644 options/license/DigiRule-FOSS-exception delete mode 100644 options/license/DocBook-Schema delete mode 100644 options/license/DocBook-Stylesheet delete mode 100644 options/license/DocBook-XML delete mode 100644 options/license/Dotseqn delete mode 100644 options/license/ECL-1.0 delete mode 100644 options/license/ECL-2.0 delete mode 100644 options/license/EFL-1.0 delete mode 100644 options/license/EFL-2.0 delete mode 100644 options/license/EPICS delete mode 100644 options/license/EUDatagrid delete mode 100644 options/license/EUPL-1.0 delete mode 100644 options/license/EUPL-1.1 delete mode 100644 options/license/Elastic-2.0 delete mode 100644 options/license/Entessa delete mode 100644 options/license/ErlPL-1.1 delete mode 100644 options/license/Eurosym delete mode 100644 options/license/FBM delete mode 100644 options/license/FDK-AAC delete mode 100644 options/license/FLTK-exception delete mode 100644 options/license/FSFAP delete mode 100644 options/license/FSFAP-no-warranty-disclaimer delete mode 100644 options/license/FSFUL delete mode 100644 options/license/FSFULLR delete mode 100644 options/license/FSFULLRWD delete mode 100644 options/license/FTL delete mode 100644 options/license/Fair delete mode 100644 options/license/Fawkes-Runtime-exception delete mode 100644 options/license/Ferguson-Twofish delete mode 100644 options/license/Font-exception-2.0 delete mode 100644 options/license/Frameworx-1.0 delete mode 100644 options/license/FreeBSD-DOC delete mode 100644 options/license/FreeImage delete mode 100644 options/license/Furuseth delete mode 100644 options/license/GCC-exception-2.0 delete mode 100644 options/license/GCC-exception-2.0-note delete mode 100644 options/license/GCC-exception-3.1 delete mode 100644 options/license/GCR-docs delete mode 100644 options/license/GD delete mode 100644 options/license/GFDL-1.1-invariants-only delete mode 100644 options/license/GFDL-1.1-invariants-or-later delete mode 100644 options/license/GFDL-1.1-no-invariants-only delete mode 100644 options/license/GFDL-1.1-no-invariants-or-later delete mode 100644 options/license/GFDL-1.1-only delete mode 100644 options/license/GFDL-1.1-or-later delete mode 100644 options/license/GFDL-1.2-invariants-only delete mode 100644 options/license/GFDL-1.2-invariants-or-later delete mode 100644 options/license/GFDL-1.2-no-invariants-only delete mode 100644 options/license/GFDL-1.2-no-invariants-or-later delete mode 100644 options/license/GFDL-1.2-only delete mode 100644 options/license/GFDL-1.2-or-later delete mode 100644 options/license/GFDL-1.3-invariants-only delete mode 100644 options/license/GFDL-1.3-invariants-or-later delete mode 100644 options/license/GFDL-1.3-no-invariants-only delete mode 100644 options/license/GFDL-1.3-no-invariants-or-later delete mode 100644 options/license/GFDL-1.3-only delete mode 100644 options/license/GFDL-1.3-or-later delete mode 100644 options/license/GL2PS delete mode 100644 options/license/GLWTPL delete mode 100644 options/license/GNAT-exception delete mode 100644 options/license/GNOME-examples-exception delete mode 100644 options/license/GNU-compiler-exception delete mode 100644 options/license/GPL-1.0-only delete mode 100644 options/license/GPL-1.0-or-later rename options/license/{GPL-2.0-only => GPL-2.0} (100%) delete mode 100644 options/license/GPL-2.0-or-later rename options/license/{GPL-3.0-only => GPL-3.0} (100%) delete mode 100644 options/license/GPL-3.0-389-ds-base-exception delete mode 100644 options/license/GPL-3.0-interface-exception delete mode 100644 options/license/GPL-3.0-linking-exception delete mode 100644 options/license/GPL-3.0-linking-source-exception delete mode 100644 options/license/GPL-3.0-or-later delete mode 100644 options/license/GPL-CC-1.0 delete mode 100644 options/license/GStreamer-exception-2005 delete mode 100644 options/license/GStreamer-exception-2008 delete mode 100644 options/license/Giftware delete mode 100644 options/license/Glide delete mode 100644 options/license/Glulxe delete mode 100644 options/license/Gmsh-exception delete mode 100644 options/license/Graphics-Gems delete mode 100644 options/license/Gutmann delete mode 100644 options/license/HIDAPI delete mode 100644 options/license/HP-1986 delete mode 100644 options/license/HP-1989 delete mode 100644 options/license/HPND delete mode 100644 options/license/HPND-DEC delete mode 100644 options/license/HPND-Fenneberg-Livingston delete mode 100644 options/license/HPND-INRIA-IMAG delete mode 100644 options/license/HPND-Intel delete mode 100644 options/license/HPND-Kevlin-Henney delete mode 100644 options/license/HPND-MIT-disclaimer delete mode 100644 options/license/HPND-Markus-Kuhn delete mode 100644 options/license/HPND-Netrek delete mode 100644 options/license/HPND-Pbmplus delete mode 100644 options/license/HPND-UC delete mode 100644 options/license/HPND-UC-export-US delete mode 100644 options/license/HPND-doc delete mode 100644 options/license/HPND-doc-sell delete mode 100644 options/license/HPND-export-US delete mode 100644 options/license/HPND-export-US-acknowledgement delete mode 100644 options/license/HPND-export-US-modify delete mode 100644 options/license/HPND-export2-US delete mode 100644 options/license/HPND-merchantability-variant delete mode 100644 options/license/HPND-sell-MIT-disclaimer-xserver delete mode 100644 options/license/HPND-sell-regexpr delete mode 100644 options/license/HPND-sell-variant delete mode 100644 options/license/HPND-sell-variant-MIT-disclaimer delete mode 100644 options/license/HPND-sell-variant-MIT-disclaimer-rev delete mode 100644 options/license/HTMLTIDY delete mode 100644 options/license/HaskellReport delete mode 100644 options/license/Hippocratic-2.1 delete mode 100644 options/license/IBM-pibs delete mode 100644 options/license/ICU delete mode 100644 options/license/IEC-Code-Components-EULA delete mode 100644 options/license/IJG delete mode 100644 options/license/IJG-short delete mode 100644 options/license/IPA delete mode 100644 options/license/IPL-1.0 delete mode 100644 options/license/ISC-Veillard delete mode 100644 options/license/ImageMagick delete mode 100644 options/license/Imlib2 delete mode 100644 options/license/Independent-modules-exception delete mode 100644 options/license/Info-ZIP delete mode 100644 options/license/Inner-Net-2.0 delete mode 100644 options/license/InnoSetup delete mode 100644 options/license/Intel delete mode 100644 options/license/Intel-ACPI delete mode 100644 options/license/Interbase-1.0 delete mode 100644 options/license/JPL-image delete mode 100644 options/license/JPNIC delete mode 100644 options/license/JSON delete mode 100644 options/license/Jam delete mode 100644 options/license/JasPer-2.0 delete mode 100644 options/license/Kastrup delete mode 100644 options/license/Kazlib delete mode 100644 options/license/KiCad-libraries-exception delete mode 100644 options/license/Knuth-CTAN delete mode 100644 options/license/LAL-1.2 delete mode 100644 options/license/LAL-1.3 delete mode 100644 options/license/LGPL-2.0-only delete mode 100644 options/license/LGPL-2.0-or-later rename options/license/{LGPL-2.1-only => LGPL-2.1} (100%) delete mode 100644 options/license/LGPL-2.1-or-later rename options/license/{LGPL-3.0-only => LGPL-3.0} (100%) delete mode 100644 options/license/LGPL-3.0-linking-exception delete mode 100644 options/license/LGPL-3.0-or-later delete mode 100644 options/license/LGPLLR delete mode 100644 options/license/LLGPL delete mode 100644 options/license/LLVM-exception delete mode 100644 options/license/LOOP delete mode 100644 options/license/LPD-document delete mode 100644 options/license/LPL-1.0 delete mode 100644 options/license/LPL-1.02 delete mode 100644 options/license/LPPL-1.0 delete mode 100644 options/license/LPPL-1.1 delete mode 100644 options/license/LPPL-1.2 delete mode 100644 options/license/LPPL-1.3a delete mode 100644 options/license/LPPL-1.3c delete mode 100644 options/license/LZMA-SDK-9.11-to-9.20 delete mode 100644 options/license/LZMA-SDK-9.22 delete mode 100644 options/license/LZMA-exception delete mode 100644 options/license/Latex2e delete mode 100644 options/license/Latex2e-translated-notice delete mode 100644 options/license/Leptonica delete mode 100644 options/license/LiLiQ-P-1.1 delete mode 100644 options/license/LiLiQ-R-1.1 delete mode 100644 options/license/LiLiQ-Rplus-1.1 delete mode 100644 options/license/Libpng delete mode 100644 options/license/Libtool-exception delete mode 100644 options/license/Linux-OpenIB delete mode 100644 options/license/Linux-man-pages-1-para delete mode 100644 options/license/Linux-man-pages-copyleft delete mode 100644 options/license/Linux-man-pages-copyleft-2-para delete mode 100644 options/license/Linux-man-pages-copyleft-var delete mode 100644 options/license/Linux-syscall-note delete mode 100644 options/license/Lucida-Bitmap-Fonts delete mode 100644 options/license/MIPS delete mode 100644 options/license/MIT-CMU delete mode 100644 options/license/MIT-Click delete mode 100644 options/license/MIT-Festival delete mode 100644 options/license/MIT-Khronos-old delete mode 100644 options/license/MIT-Modern-Variant delete mode 100644 options/license/MIT-Wu delete mode 100644 options/license/MIT-advertising delete mode 100644 options/license/MIT-enna delete mode 100644 options/license/MIT-feh delete mode 100644 options/license/MIT-open-group delete mode 100644 options/license/MIT-testregex delete mode 100644 options/license/MITNFA delete mode 100644 options/license/MMIXware delete mode 100644 options/license/MPEG-SSG delete mode 100644 options/license/MPL-1.0 delete mode 100644 options/license/MPL-1.1 delete mode 100644 options/license/MPL-2.0-no-copyleft-exception delete mode 100644 options/license/MS-LPL delete mode 100644 options/license/MS-PL delete mode 100644 options/license/MS-RL delete mode 100644 options/license/MTLL delete mode 100644 options/license/Mackerras-3-Clause delete mode 100644 options/license/Mackerras-3-Clause-acknowledgment delete mode 100644 options/license/MakeIndex delete mode 100644 options/license/Martin-Birgmeier delete mode 100644 options/license/McPhee-slideshow delete mode 100644 options/license/Minpack delete mode 100644 options/license/MirOS delete mode 100644 options/license/Motosoto delete mode 100644 options/license/MulanPSL-1.0 delete mode 100644 options/license/Multics delete mode 100644 options/license/Mup delete mode 100644 options/license/NAIST-2003 delete mode 100644 options/license/NASA-1.3 delete mode 100644 options/license/NBPL-1.0 delete mode 100644 options/license/NCBI-PD delete mode 100644 options/license/NCGL-UK-2.0 delete mode 100644 options/license/NCL delete mode 100644 options/license/NCSA delete mode 100644 options/license/NGPL delete mode 100644 options/license/NICTA-1.0 delete mode 100644 options/license/NIST-PD delete mode 100644 options/license/NIST-PD-fallback delete mode 100644 options/license/NIST-Software delete mode 100644 options/license/NLOD-1.0 delete mode 100644 options/license/NLOD-2.0 delete mode 100644 options/license/NLPL delete mode 100644 options/license/NOSL delete mode 100644 options/license/NPL-1.0 delete mode 100644 options/license/NPL-1.1 delete mode 100644 options/license/NPOSL-3.0 delete mode 100644 options/license/NRL delete mode 100644 options/license/NTP delete mode 100644 options/license/NTP-0 delete mode 100644 options/license/Naumen delete mode 100644 options/license/NetCDF delete mode 100644 options/license/Newsletr delete mode 100644 options/license/Nokia delete mode 100644 options/license/Nokia-Qt-exception-1.1 delete mode 100644 options/license/Noweb delete mode 100644 options/license/O-UDA-1.0 delete mode 100644 options/license/OAR delete mode 100644 options/license/OCCT-PL delete mode 100644 options/license/OCCT-exception-1.0 delete mode 100644 options/license/OCLC-2.0 delete mode 100644 options/license/OCaml-LGPL-linking-exception delete mode 100644 options/license/ODC-By-1.0 delete mode 100644 options/license/ODbL-1.0 delete mode 100644 options/license/OFFIS delete mode 100644 options/license/OFL-1.0 delete mode 100644 options/license/OFL-1.0-RFN delete mode 100644 options/license/OFL-1.0-no-RFN delete mode 100644 options/license/OFL-1.1-RFN delete mode 100644 options/license/OFL-1.1-no-RFN delete mode 100644 options/license/OGC-1.0 delete mode 100644 options/license/OGDL-Taiwan-1.0 delete mode 100644 options/license/OGL-Canada-2.0 delete mode 100644 options/license/OGL-UK-1.0 delete mode 100644 options/license/OGL-UK-2.0 delete mode 100644 options/license/OGL-UK-3.0 delete mode 100644 options/license/OGTSL delete mode 100644 options/license/OLDAP-1.1 delete mode 100644 options/license/OLDAP-1.2 delete mode 100644 options/license/OLDAP-1.3 delete mode 100644 options/license/OLDAP-1.4 delete mode 100644 options/license/OLDAP-2.0 delete mode 100644 options/license/OLDAP-2.0.1 delete mode 100644 options/license/OLDAP-2.1 delete mode 100644 options/license/OLDAP-2.2 delete mode 100644 options/license/OLDAP-2.2.1 delete mode 100644 options/license/OLDAP-2.2.2 delete mode 100644 options/license/OLDAP-2.3 delete mode 100644 options/license/OLDAP-2.4 delete mode 100644 options/license/OLDAP-2.5 delete mode 100644 options/license/OLDAP-2.6 delete mode 100644 options/license/OLDAP-2.7 delete mode 100644 options/license/OLDAP-2.8 delete mode 100644 options/license/OLFL-1.3 delete mode 100644 options/license/OML delete mode 100644 options/license/OPL-1.0 delete mode 100644 options/license/OPL-UK-3.0 delete mode 100644 options/license/OPUBL-1.0 delete mode 100644 options/license/OSET-PL-2.1 delete mode 100644 options/license/OSL-1.0 delete mode 100644 options/license/OSL-1.1 delete mode 100644 options/license/OSL-2.0 delete mode 100644 options/license/OSL-2.1 delete mode 100644 options/license/OpenJDK-assembly-exception-1.0 delete mode 100644 options/license/OpenPBS-2.3 delete mode 100644 options/license/OpenSSL delete mode 100644 options/license/OpenSSL-standalone delete mode 100644 options/license/OpenVision delete mode 100644 options/license/PADL delete mode 100644 options/license/PCRE2-exception delete mode 100644 options/license/PDDL-1.0 delete mode 100644 options/license/PHP-3.0 delete mode 100644 options/license/PHP-3.01 delete mode 100644 options/license/PPL delete mode 100644 options/license/PS-or-PDF-font-exception-20170817 delete mode 100644 options/license/PSF-2.0 delete mode 100644 options/license/Parity-6.0.0 delete mode 100644 options/license/Parity-7.0.0 delete mode 100644 options/license/Pixar delete mode 100644 options/license/Plexus delete mode 100644 options/license/PolyForm-Noncommercial-1.0.0 delete mode 100644 options/license/PolyForm-Small-Business-1.0.0 delete mode 100644 options/license/PostgreSQL delete mode 100644 options/license/Python-2.0 delete mode 100644 options/license/Python-2.0.1 delete mode 100644 options/license/QPL-1.0 delete mode 100644 options/license/QPL-1.0-INRIA-2004 delete mode 100644 options/license/QPL-1.0-INRIA-2004-exception delete mode 100644 options/license/Qhull delete mode 100644 options/license/Qt-GPL-exception-1.0 delete mode 100644 options/license/Qt-LGPL-exception-1.1 delete mode 100644 options/license/Qwt-exception-1.0 delete mode 100644 options/license/RHeCos-1.1 delete mode 100644 options/license/RPL-1.1 delete mode 100644 options/license/RPL-1.5 delete mode 100644 options/license/RPSL-1.0 delete mode 100644 options/license/RRDtool-FLOSS-exception-2.0 delete mode 100644 options/license/RSA-MD delete mode 100644 options/license/RSCPL delete mode 100644 options/license/Rdisc delete mode 100644 options/license/Ruby delete mode 100644 options/license/Ruby-pty delete mode 100644 options/license/SANE-exception delete mode 100644 options/license/SAX-PD delete mode 100644 options/license/SAX-PD-2.0 delete mode 100644 options/license/SCEA delete mode 100644 options/license/SGI-B-1.0 delete mode 100644 options/license/SGI-B-1.1 delete mode 100644 options/license/SGI-B-2.0 delete mode 100644 options/license/SGI-OpenGL delete mode 100644 options/license/SGP4 delete mode 100644 options/license/SHL-0.5 delete mode 100644 options/license/SHL-0.51 delete mode 100644 options/license/SHL-2.0 delete mode 100644 options/license/SHL-2.1 delete mode 100644 options/license/SISSL delete mode 100644 options/license/SISSL-1.2 delete mode 100644 options/license/SL delete mode 100644 options/license/SMAIL-GPL delete mode 100644 options/license/SMLNJ delete mode 100644 options/license/SMPPL delete mode 100644 options/license/SNIA delete mode 100644 options/license/SPL-1.0 delete mode 100644 options/license/SSH-OpenSSH delete mode 100644 options/license/SSH-short delete mode 100644 options/license/SSLeay-standalone delete mode 100644 options/license/SSPL-1.0 delete mode 100644 options/license/SWI-exception delete mode 100644 options/license/SWL delete mode 100644 options/license/Saxpath delete mode 100644 options/license/SchemeReport delete mode 100644 options/license/Sendmail delete mode 100644 options/license/Sendmail-8.23 delete mode 100644 options/license/Sendmail-Open-Source-1.1 delete mode 100644 options/license/SimPL-2.0 delete mode 100644 options/license/Sleepycat delete mode 100644 options/license/Soundex delete mode 100644 options/license/Spencer-86 delete mode 100644 options/license/Spencer-94 delete mode 100644 options/license/Spencer-99 delete mode 100644 options/license/SugarCRM-1.1.3 delete mode 100644 options/license/Sun-PPP delete mode 100644 options/license/Sun-PPP-2000 delete mode 100644 options/license/SunPro delete mode 100644 options/license/Swift-exception delete mode 100644 options/license/Symlinks delete mode 100644 options/license/TAPR-OHL-1.0 delete mode 100644 options/license/TCL delete mode 100644 options/license/TCP-wrappers delete mode 100644 options/license/TGPPL-1.0 delete mode 100644 options/license/TMate delete mode 100644 options/license/TORQUE-1.1 delete mode 100644 options/license/TOSL delete mode 100644 options/license/TPDL delete mode 100644 options/license/TPL-1.0 delete mode 100644 options/license/TTWL delete mode 100644 options/license/TTYP0 delete mode 100644 options/license/TU-Berlin-1.0 delete mode 100644 options/license/TU-Berlin-2.0 delete mode 100644 options/license/TermReadKey delete mode 100644 options/license/Texinfo-exception delete mode 100644 options/license/ThirdEye delete mode 100644 options/license/TrustedQSL delete mode 100644 options/license/UBDL-exception delete mode 100644 options/license/UCAR delete mode 100644 options/license/UCL-1.0 delete mode 100644 options/license/UMich-Merit delete mode 100644 options/license/URT-RLE delete mode 100644 options/license/Ubuntu-font-1.0 delete mode 100644 options/license/Unicode-3.0 delete mode 100644 options/license/Unicode-DFS-2015 delete mode 100644 options/license/Unicode-DFS-2016 delete mode 100644 options/license/Unicode-TOU delete mode 100644 options/license/Universal-FOSS-exception-1.0 delete mode 100644 options/license/UnixCrypt delete mode 100644 options/license/VOSTROM delete mode 100644 options/license/VSL-1.0 delete mode 100644 options/license/Vim delete mode 100644 options/license/W3C delete mode 100644 options/license/W3C-19980720 delete mode 100644 options/license/W3C-20150513 delete mode 100644 options/license/Watcom-1.0 delete mode 100644 options/license/Widget-Workshop delete mode 100644 options/license/Wsuipa delete mode 100644 options/license/WxWindows-exception-3.1 delete mode 100644 options/license/X11 delete mode 100644 options/license/X11-distribute-modifications-variant delete mode 100644 options/license/X11-swapped delete mode 100644 options/license/XFree86-1.1 delete mode 100644 options/license/XSkat delete mode 100644 options/license/Xdebug-1.03 delete mode 100644 options/license/Xerox delete mode 100644 options/license/Xfig delete mode 100644 options/license/Xnet delete mode 100644 options/license/YPL-1.0 delete mode 100644 options/license/YPL-1.1 delete mode 100644 options/license/ZPL-1.1 delete mode 100644 options/license/ZPL-2.0 delete mode 100644 options/license/ZPL-2.1 delete mode 100644 options/license/Zed delete mode 100644 options/license/Zeeff delete mode 100644 options/license/Zend-2.0 delete mode 100644 options/license/Zimbra-1.3 delete mode 100644 options/license/Zimbra-1.4 delete mode 100644 options/license/any-OSI delete mode 100644 options/license/any-OSI-perl-modules delete mode 100644 options/license/bcrypt-Solar-Designer delete mode 100644 options/license/blessing delete mode 100644 options/license/bzip2-1.0.6 delete mode 100644 options/license/check-cvs delete mode 100644 options/license/checkmk delete mode 100644 options/license/copyleft-next-0.3.0 delete mode 100644 options/license/copyleft-next-0.3.1 delete mode 100644 options/license/cryptsetup-OpenSSL-exception delete mode 100644 options/license/curl delete mode 100644 options/license/cve-tou delete mode 100644 options/license/diffmark delete mode 100644 options/license/dtoa delete mode 100644 options/license/dvipdfm delete mode 100644 options/license/eCos-exception-2.0 delete mode 100644 options/license/eGenix delete mode 100644 options/license/erlang-otp-linking-exception delete mode 100644 options/license/etalab-2.0 delete mode 100644 options/license/etc/license-aliases.json delete mode 100644 options/license/fmt-exception delete mode 100644 options/license/freertos-exception-2.0 delete mode 100644 options/license/fwlw delete mode 100644 options/license/gSOAP-1.3b delete mode 100644 options/license/generic-xts delete mode 100644 options/license/gnu-javamail-exception delete mode 100644 options/license/gnuplot delete mode 100644 options/license/gtkbook delete mode 100644 options/license/harbour-exception delete mode 100644 options/license/hdparm delete mode 100644 options/license/i2p-gpl-java-exception delete mode 100644 options/license/iMatix delete mode 100644 options/license/libpng-2.0 delete mode 100644 options/license/libpri-OpenH323-exception delete mode 100644 options/license/libselinux-1.0 delete mode 100644 options/license/libtiff delete mode 100644 options/license/libutil-David-Nugent delete mode 100644 options/license/lsof delete mode 100644 options/license/magaz delete mode 100644 options/license/mailprio delete mode 100644 options/license/metamail delete mode 100644 options/license/mif-exception delete mode 100644 options/license/mpi-permissive delete mode 100644 options/license/mpich2 delete mode 100644 options/license/mplus delete mode 100644 options/license/mxml-exception delete mode 100644 options/license/openvpn-openssl-exception delete mode 100644 options/license/pkgconf delete mode 100644 options/license/pnmstitch delete mode 100644 options/license/psfrag delete mode 100644 options/license/psutils delete mode 100644 options/license/python-ldap delete mode 100644 options/license/radvd delete mode 100644 options/license/romic-exception delete mode 100644 options/license/snprintf delete mode 100644 options/license/softSurfer delete mode 100644 options/license/ssh-keyscan delete mode 100644 options/license/stunnel-exception delete mode 100644 options/license/swrule delete mode 100644 options/license/threeparttable delete mode 100644 options/license/u-boot-exception-2.0 delete mode 100644 options/license/ulem delete mode 100644 options/license/vsftpd-openssl-exception delete mode 100644 options/license/w3m delete mode 100644 options/license/wwl delete mode 100644 options/license/x11vnc-openssl-exception delete mode 100644 options/license/xinetd delete mode 100644 options/license/xkeyboard-config-Zinoviev delete mode 100644 options/license/xlock delete mode 100644 options/license/xpp delete mode 100644 options/license/xzoom delete mode 100644 options/license/zlib-acknowledgement create mode 100644 public/assets/img/svg/material-folder-generic.svg create mode 100644 public/assets/img/svg/material-folder-symlink.svg create mode 100644 services/forms/admin_config_form.go create mode 100644 services/mailer/mail_issue_common.go create mode 100644 services/mailer/mail_user.go create mode 100644 services/pull/protected_branch.go create mode 100644 services/versioned_migration/migration.go create mode 100644 services/webtheme/webtheme_test.go create mode 100644 tools/generate-svg-vscode-extensions.json delete mode 100644 web_src/css/modules/select.css create mode 100644 web_src/css/modules/tab.css delete mode 100644 web_src/fomantic/.npmrc create mode 100644 web_src/fomantic/build/components/api.js create mode 100644 web_src/fomantic/build/components/dropdown.css create mode 100644 web_src/fomantic/build/components/dropdown.js create mode 100644 web_src/fomantic/build/components/form.css create mode 100644 web_src/fomantic/build/components/modal.css create mode 100644 web_src/fomantic/build/components/modal.js create mode 100644 web_src/fomantic/build/components/search.css create mode 100644 web_src/fomantic/build/components/search.js create mode 100644 web_src/fomantic/build/fomantic.css create mode 100644 web_src/fomantic/build/fomantic.js delete mode 100644 web_src/fomantic/build/semantic.css delete mode 100644 web_src/fomantic/build/semantic.js delete mode 100644 web_src/fomantic/build/themes/default/assets/fonts/icons.woff2 delete mode 100644 web_src/fomantic/build/themes/default/assets/fonts/outline-icons.woff2 delete mode 100644 web_src/fomantic/package-lock.json delete mode 100644 web_src/fomantic/package.json delete mode 100644 web_src/js/components/DiffFileList.vue delete mode 100644 web_src/js/components/ScopedAccessTokenSelector.vue delete mode 100644 web_src/js/features/autofocus-end.ts delete mode 100644 web_src/js/features/scoped-access-token.ts delete mode 100644 web_src/js/modules/dirauto.ts delete mode 100644 web_src/js/modules/fomantic/api.ts create mode 100644 web_src/js/modules/fomantic/tab.ts create mode 100644 web_src/js/modules/init.ts create mode 100644 web_src/js/modules/observer.ts create mode 100644 web_src/js/utils/filetree.test.ts create mode 100644 web_src/js/utils/filetree.ts create mode 100644 web_src/svg/material-folder-generic.svg create mode 100644 web_src/svg/material-folder-symlink.svg diff --git a/.dockerignore b/.dockerignore index b696e1603cca7..94aca6b8d303a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -79,18 +79,6 @@ cpu.out /public/assets/fonts /public/assets/img/avatar /vendor -/web_src/fomantic/node_modules -/web_src/fomantic/build/* -!/web_src/fomantic/build/semantic.js -!/web_src/fomantic/build/semantic.css -!/web_src/fomantic/build/themes -/web_src/fomantic/build/themes/* -!/web_src/fomantic/build/themes/default -/web_src/fomantic/build/themes/default/assets/* -!/web_src/fomantic/build/themes/default/assets/fonts -/web_src/fomantic/build/themes/default/assets/fonts/* -!/web_src/fomantic/build/themes/default/assets/fonts/icons.woff2 -!/web_src/fomantic/build/themes/default/assets/fonts/outline-icons.woff2 /VERSION /.air /.go-licenses diff --git a/.gitattributes b/.gitattributes index 9fb4a4e83dd71..52695f70c2dd7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,7 +5,5 @@ /public/assets/img/svg/*.svg linguist-generated /templates/swagger/v1_json.tmpl linguist-generated /vendor/** -text -eol linguist-vendored -/web_src/fomantic/build/** linguist-generated -/web_src/fomantic/_site/globals/site.variables linguist-language=Less /web_src/js/vendor/** -text -eol linguist-vendored Dockerfile.* linguist-language=Dockerfile diff --git a/.github/workflows/cron-licenses.yml b/.github/workflows/cron-licenses.yml index 33cbc507d9677..c34066d31875c 100644 --- a/.github/workflows/cron-licenses.yml +++ b/.github/workflows/cron-licenses.yml @@ -15,7 +15,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - run: make generate-license generate-gitignore + - run: make generate-gitignore timeout-minutes: 40 - name: push translations to repo uses: appleboy/git-push-action@v0.0.3 diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index 7e988e04492ea..64090d6490541 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -95,7 +95,7 @@ jobs: go-version-file: go.mod check-latest: true - run: make deps-backend deps-tools - - run: make lint-go-windows lint-go-vet + - run: make lint-go-windows lint-go-gitea-vet env: TAGS: bindata sqlite sqlite_unlock_notify GOOS: windows diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml index 0b23de0a66c01..6e879053d3982 100644 --- a/.github/workflows/pull-db-tests.yml +++ b/.github/workflows/pull-db-tests.yml @@ -202,12 +202,10 @@ jobs: test-mssql: if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' needs: files-changed - # specifying the version of ubuntu in use as mssql fails on newer kernels - # pending resolution from vendor - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest services: mssql: - image: mcr.microsoft.com/mssql/server:2017-latest + image: mcr.microsoft.com/mssql/server:2019-latest env: ACCEPT_EULA: Y MSSQL_PID: Standard diff --git a/.gitignore b/.gitignore index d215468377880..703be8f681ade 100644 --- a/.gitignore +++ b/.gitignore @@ -84,18 +84,6 @@ cpu.out /public/assets/fonts /public/assets/licenses.txt /vendor -/web_src/fomantic/node_modules -/web_src/fomantic/build/* -!/web_src/fomantic/build/semantic.js -!/web_src/fomantic/build/semantic.css -!/web_src/fomantic/build/themes -/web_src/fomantic/build/themes/* -!/web_src/fomantic/build/themes/default -/web_src/fomantic/build/themes/default/assets/* -!/web_src/fomantic/build/themes/default/assets/fonts -/web_src/fomantic/build/themes/default/assets/fonts/* -!/web_src/fomantic/build/themes/default/assets/fonts/icons.woff2 -!/web_src/fomantic/build/themes/default/assets/fonts/outline-icons.woff2 /VERSION /.air /.go-licenses diff --git a/CHANGELOG.md b/CHANGELOG.md index c32915c1dca4a..7541bccb2ab3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ This changelog goes through the changes that have been made in each release without substantial changes to our git log; to see the highlights of what has been added to each release, please refer to the [blog](https://blog.gitea.com). +## [1.23.5](https://github.com/go-gitea/gitea/releases/tag/v1.23.5) - 2025-03-04 + +* SECURITY + * Bump x/oauth2 & x/crypto (#33704) (#33727) +* PERFORMANCE + * Optimize user dashboard loading (#33686) (#33708) +* BUGFIXES + * Fix navbar dropdown item align (#33782) + * Fix inconsistent closed issue list icon (#33722) (#33728) + * Fix for Maven Package Naming Convention Handling (#33678) (#33679) + * Improve Open-with URL encoding (#33666) (#33680) + * Deleting repository should unlink all related packages (#33653) (#33673) + * Fix omitempty bug (#33663) (#33670) + * Upgrade go-crypto from 1.1.4 to 1.1.6 (#33745) (#33754) + * Fix OCI image.version annotation for releases to use full semver (#33698) (#33701) + * Try to fix ACME path when renew (#33668) (#33693) + * Fix mCaptcha bug (#33659) (#33661) + * Git graph: don't show detached commits (#33645) (#33650) + * Use MatchPhraseQuery for bleve code search (#33628) + * Adjust appearence of commit status webhook (#33778) #33789 + * Upgrade golang net from 0.35.0 -> 0.36.0 (#33795) #33796 + ## [1.23.4](https://github.com/go-gitea/gitea/releases/tag/v1.23.4) - 2025-02-16 * SECURITY diff --git a/Makefile b/Makefile index e38fb801c318a..6c8798318c988 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,7 @@ EXTRA_GOFLAGS ?= MAKE_VERSION := $(shell "$(MAKE)" -v | cat | head -n 1) MAKE_EVIDENCE_DIR := .make_evidence +GOTESTFLAGS ?= ifeq ($(RACE_ENABLED),true) GOFLAGS += -race GOTESTFLAGS += -race @@ -114,8 +115,6 @@ LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64 GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/)) MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) -FOMANTIC_WORK_DIR := web_src/fomantic - WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f) WEBPACK_CONFIGS := webpack.config.js tailwind.config.js WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css @@ -139,7 +138,7 @@ TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags TEST_TAGS ?= $(TAGS_SPLIT) sqlite sqlite_unlock_notify -TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR) +TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR) GO_DIRS := build cmd models modules routers services tests WEB_DIRS := web_src/js web_src/css @@ -311,10 +310,10 @@ lint-frontend: lint-js lint-css ## lint frontend files lint-frontend-fix: lint-js-fix lint-css-fix ## lint frontend files and fix issues .PHONY: lint-backend -lint-backend: lint-go lint-go-vet lint-go-gopls lint-editorconfig ## lint backend files +lint-backend: lint-go lint-go-gitea-vet lint-go-gopls lint-editorconfig ## lint backend files .PHONY: lint-backend-fix -lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig ## lint backend files and fix issues +lint-backend-fix: lint-go-fix lint-go-gitea-vet lint-editorconfig ## lint backend files and fix issues .PHONY: lint-js lint-js: node_modules ## lint js files @@ -365,9 +364,9 @@ lint-go-windows: @GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE) golangci-lint run -.PHONY: lint-go-vet -lint-go-vet: ## lint go files with vet - @echo "Running go vet..." +.PHONY: lint-go-gitea-vet +lint-go-gitea-vet: ## lint go files with gitea-vet + @echo "Running gitea-vet..." @GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet @$(GO) vet -vettool=gitea-vet ./... @@ -470,7 +469,9 @@ tidy-check: tidy go-licenses: $(GO_LICENSE_FILE) ## regenerate go licenses $(GO_LICENSE_FILE): go.mod go.sum - -$(GO) run $(GO_LICENSES_PACKAGE) save . --force --save_path=$(GO_LICENSE_TMP_DIR) 2>/dev/null + @rm -rf $(GO_LICENSE_FILE) + $(GO) install $(GO_LICENSES_PACKAGE) + -GOOS=linux CGO_ENABLED=1 go-licenses save . --force --save_path=$(GO_LICENSE_TMP_DIR) 2>/dev/null $(GO) run build/generate-go-licenses.go $(GO_LICENSE_TMP_DIR) $(GO_LICENSE_FILE) @rm -rf $(GO_LICENSE_TMP_DIR) @@ -844,19 +845,6 @@ update-py: node-check | node_modules ## update py dependencies poetry install @touch .venv -.PHONY: fomantic -fomantic: ## build fomantic files - rm -rf $(FOMANTIC_WORK_DIR)/build - cd $(FOMANTIC_WORK_DIR) && npm install --no-save - cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config - cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/ - $(SED_INPLACE) -e 's/ overrideBrowserslist\r/ overrideBrowserslist: ["defaults"]\r/g' $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/tasks/config/tasks.js - cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build - # fomantic uses "touchstart" as click event for some browsers, it's not ideal, so we force fomantic to always use "click" as click event - $(SED_INPLACE) -e 's/clickEvent[ \t]*=/clickEvent = "click", unstableClickEvent =/g' $(FOMANTIC_WORK_DIR)/build/semantic.js - $(SED_INPLACE) -e 's/\r//g' $(FOMANTIC_WORK_DIR)/build/semantic.css $(FOMANTIC_WORK_DIR)/build/semantic.js - rm -f $(FOMANTIC_WORK_DIR)/build/*.min.* - .PHONY: webpack webpack: $(WEBPACK_DEST) ## build webpack files @@ -903,10 +891,6 @@ update-translations: mv ./translations/*.ini ./options/locale/ rmdir ./translations -.PHONY: generate-license -generate-license: ## update license files - $(GO) run build/generate-licenses.go - .PHONY: generate-gitignore generate-gitignore: ## update gitignore files $(GO) run build/generate-gitignores.go diff --git a/build/generate-licenses.go b/build/generate-licenses.go deleted file mode 100644 index 66e1d3775515e..0000000000000 --- a/build/generate-licenses.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2017 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -//go:build ignore - -package main - -import ( - "archive/tar" - "compress/gzip" - "crypto/md5" - "encoding/hex" - "flag" - "fmt" - "io" - "log" - "net/http" - "os" - "path" - "path/filepath" - "strings" - - "code.gitea.io/gitea/build/license" - "code.gitea.io/gitea/modules/json" - "code.gitea.io/gitea/modules/util" -) - -func main() { - var ( - prefix = "gitea-licenses" - url = "https://api.github.com/repos/spdx/license-list-data/tarball" - githubApiToken = "" - githubUsername = "" - destination = "" - ) - - flag.StringVar(&destination, "dest", "options/license/", "destination for the licenses") - flag.StringVar(&githubUsername, "username", "", "github username") - flag.StringVar(&githubApiToken, "token", "", "github api token") - flag.Parse() - - file, err := os.CreateTemp(os.TempDir(), prefix) - if err != nil { - log.Fatalf("Failed to create temp file. %s", err) - } - - defer util.Remove(file.Name()) - - if err := os.RemoveAll(destination); err != nil { - log.Fatalf("Cannot clean destination folder: %v", err) - } - - if err := os.MkdirAll(destination, 0o755); err != nil { - log.Fatalf("Cannot create destination: %v", err) - } - - req, err := http.NewRequest("GET", url, nil) - if err != nil { - log.Fatalf("Failed to download archive. %s", err) - } - - if len(githubApiToken) > 0 && len(githubUsername) > 0 { - req.SetBasicAuth(githubUsername, githubApiToken) - } - - resp, err := http.DefaultClient.Do(req) - if err != nil { - log.Fatalf("Failed to download archive. %s", err) - } - - defer resp.Body.Close() - - if _, err := io.Copy(file, resp.Body); err != nil { - log.Fatalf("Failed to copy archive to file. %s", err) - } - - if _, err := file.Seek(0, 0); err != nil { - log.Fatalf("Failed to reset seek on archive. %s", err) - } - - gz, err := gzip.NewReader(file) - if err != nil { - log.Fatalf("Failed to gunzip the archive. %s", err) - } - - tr := tar.NewReader(gz) - aliasesFiles := make(map[string][]string) - for { - hdr, err := tr.Next() - - if err == io.EOF { - break - } - - if err != nil { - log.Fatalf("Failed to iterate archive. %s", err) - } - - if !strings.Contains(hdr.Name, "/text/") { - continue - } - - if filepath.Ext(hdr.Name) != ".txt" { - continue - } - - fileBaseName := filepath.Base(hdr.Name) - licenseName := strings.TrimSuffix(fileBaseName, ".txt") - - if strings.HasPrefix(fileBaseName, "README") { - continue - } - - if strings.HasPrefix(fileBaseName, "deprecated_") { - continue - } - out, err := os.Create(path.Join(destination, licenseName)) - if err != nil { - log.Fatalf("Failed to create new file. %s", err) - } - - defer out.Close() - - // some license files have same content, so we need to detect these files and create a convert map into a json file - // Later we use this convert map to avoid adding same license content with different license name - h := md5.New() - // calculate md5 and write file in the same time - r := io.TeeReader(tr, h) - if _, err := io.Copy(out, r); err != nil { - log.Fatalf("Failed to write new file. %s", err) - } else { - fmt.Printf("Written %s\n", out.Name()) - - md5 := hex.EncodeToString(h.Sum(nil)) - aliasesFiles[md5] = append(aliasesFiles[md5], licenseName) - } - } - - // generate convert license name map - licenseAliases := make(map[string]string) - for _, fileNames := range aliasesFiles { - if len(fileNames) > 1 { - licenseName := license.GetLicenseNameFromAliases(fileNames) - if licenseName == "" { - // license name should not be empty as expected - // if it is empty, we need to rewrite the logic of GetLicenseNameFromAliases - log.Fatalf("GetLicenseNameFromAliases: license name is empty") - } - for _, fileName := range fileNames { - licenseAliases[fileName] = licenseName - } - } - } - // save convert license name map to file - b, err := json.Marshal(licenseAliases) - if err != nil { - log.Fatalf("Failed to create json bytes. %s", err) - } - - licenseAliasesDestination := filepath.Join(destination, "etc", "license-aliases.json") - if err := os.MkdirAll(filepath.Dir(licenseAliasesDestination), 0o755); err != nil { - log.Fatalf("Failed to create directory for license aliases json file. %s", err) - } - - f, err := os.Create(licenseAliasesDestination) - if err != nil { - log.Fatalf("Failed to create license aliases json file. %s", err) - } - defer f.Close() - - if _, err = f.Write(b); err != nil { - log.Fatalf("Failed to write license aliases json file. %s", err) - } - - fmt.Println("Done") -} diff --git a/build/license/aliasgenerator.go b/build/license/aliasgenerator.go deleted file mode 100644 index 7de1e6fbd6b5a..0000000000000 --- a/build/license/aliasgenerator.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package license - -import "strings" - -func GetLicenseNameFromAliases(fnl []string) string { - if len(fnl) == 0 { - return "" - } - - shortestItem := func(list []string) string { - s := list[0] - for _, l := range list[1:] { - if len(l) < len(s) { - s = l - } - } - return s - } - allHasPrefix := func(list []string, s string) bool { - for _, l := range list { - if !strings.HasPrefix(l, s) { - return false - } - } - return true - } - - sl := shortestItem(fnl) - slv := strings.Split(sl, "-") - var result string - for i := len(slv); i >= 0; i-- { - result = strings.Join(slv[:i], "-") - if allHasPrefix(fnl, result) { - return result - } - } - return "" -} diff --git a/build/license/aliasgenerator_test.go b/build/license/aliasgenerator_test.go deleted file mode 100644 index 239181b7365ae..0000000000000 --- a/build/license/aliasgenerator_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package license - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestGetLicenseNameFromAliases(t *testing.T) { - tests := []struct { - target string - inputs []string - }{ - { - // real case which you can find in license-aliases.json - target: "AGPL-1.0", - inputs: []string{ - "AGPL-1.0-only", - "AGPL-1.0-or-late", - }, - }, - { - target: "", - inputs: []string{ - "APSL-1.0", - "AGPL-1.0-only", - "AGPL-1.0-or-late", - }, - }, - } - - for _, tt := range tests { - result := GetLicenseNameFromAliases(tt.inputs) - assert.Equal(t, result, tt.target) - } -} diff --git a/cmd/doctor.go b/cmd/doctor.go index e433f4adc5d3c..52699cc4ddbbe 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -4,6 +4,7 @@ package cmd import ( + "context" "fmt" golog "log" "os" @@ -130,8 +131,8 @@ func runRecreateTable(ctx *cli.Context) error { } recreateTables := migrate_base.RecreateTables(beans...) - return db.InitEngineWithMigration(stdCtx, func(x *xorm.Engine) error { - if err := migrations.EnsureUpToDate(x); err != nil { + return db.InitEngineWithMigration(stdCtx, func(ctx context.Context, x *xorm.Engine) error { + if err := migrations.EnsureUpToDate(ctx, x); err != nil { return err } return recreateTables(x) diff --git a/cmd/hook.go b/cmd/hook.go index 578380ab40db6..41e3c3ce340f3 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -316,7 +316,7 @@ func runHookPostReceive(c *cli.Context) error { setup(ctx, c.Bool("debug")) // First of all run update-server-info no matter what - if _, _, err := git.NewCommand(ctx, "update-server-info").RunStdString(nil); err != nil { + if _, _, err := git.NewCommand("update-server-info").RunStdString(ctx, nil); err != nil { return fmt.Errorf("Failed to call 'git update-server-info': %w", err) } diff --git a/cmd/migrate.go b/cmd/migrate.go index 459805a76d732..25d8b50c45c61 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -7,9 +7,9 @@ import ( "context" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/migrations" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/versioned_migration" "github.com/urfave/cli/v2" ) @@ -36,7 +36,7 @@ func runMigrate(ctx *cli.Context) error { log.Info("Log path: %s", setting.Log.RootPath) log.Info("Configuration file: %s", setting.CustomConf) - if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil { + if err := db.InitEngineWithMigration(context.Background(), versioned_migration.Migrate); err != nil { log.Fatal("Failed to initialize ORM engine: %v", err) return err } diff --git a/cmd/migrate_storage.go b/cmd/migrate_storage.go index 2e3aba021d2ee..f9ed140395f60 100644 --- a/cmd/migrate_storage.go +++ b/cmd/migrate_storage.go @@ -13,7 +13,6 @@ import ( actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/models/migrations" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -21,6 +20,7 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" + "code.gitea.io/gitea/services/versioned_migration" "github.com/urfave/cli/v2" ) @@ -227,7 +227,7 @@ func runMigrateStorage(ctx *cli.Context) error { log.Info("Log path: %s", setting.Log.RootPath) log.Info("Configuration file: %s", setting.CustomConf) - if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil { + if err := db.InitEngineWithMigration(context.Background(), versioned_migration.Migrate); err != nil { log.Fatal("Failed to initialize ORM engine: %v", err) return err } diff --git a/cmd/web_acme.go b/cmd/web_acme.go index bca4ae021217b..172dde913b6c6 100644 --- a/cmd/web_acme.go +++ b/cmd/web_acme.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "github.com/caddyserver/certmagic" ) @@ -68,9 +69,15 @@ func runACME(listenAddr string, m http.Handler) error { // And one more thing, no idea why we should set the global default variables here // But it seems that the current ACME code needs these global variables to make renew work. // Otherwise, "renew" will use incorrect storage path + oldDefaultACME := certmagic.DefaultACME certmagic.Default.Storage = &certmagic.FileStorage{Path: setting.AcmeLiveDirectory} certmagic.DefaultACME = certmagic.ACMEIssuer{ - CA: setting.AcmeURL, + // try to use the default values provided by DefaultACME + CA: util.IfZero(setting.AcmeURL, oldDefaultACME.CA), + TestCA: oldDefaultACME.TestCA, + Logger: oldDefaultACME.Logger, + HTTPProxy: oldDefaultACME.HTTPProxy, + TrustedRoots: certPool, Email: setting.AcmeEmail, Agreed: setting.AcmeTOS, diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 899209874f7cc..443d179cc11b4 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1258,24 +1258,31 @@ LEVEL = Info ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Number of repositories that are displayed on one explore page +;; Deprecated in v1.24 ;EXPLORE_PAGING_NUM = 20 ;; ;; Number of issues that are displayed on one page +;; Deprecated in v1.24 ;ISSUE_PAGING_NUM = 20 ;; ;; Number of maximum commits displayed in one activity feed +;; Deprecated in v1.24 ;FEED_MAX_COMMIT_NUM = 5 ;; ;; Number of items that are displayed in home feed +;; Deprecated in v1.24 ;FEED_PAGING_NUM = 20 ;; ;; Number of items that are displayed in a single subsitemap +;; Deprecated in v1.24 ;SITEMAP_PAGING_NUM = 20 ;; ;; Number of maximum commits displayed in commit graph. +;; Deprecated in v1.24 ;GRAPH_MAX_COMMIT_NUM = 100 ;; ;; Number of line of codes shown for a code comment +;; Deprecated in v1.24 ;CODE_COMMENT_LINES = 4 ;; ;; Max size of files to be displayed (default is 8MiB) @@ -1285,6 +1292,7 @@ LEVEL = Info ;AMBIGUOUS_UNICODE_DETECTION = true ;; ;; Whether the email of the user should be shown in the Explore Users page +;; Deprecated in v1.24 ;SHOW_USER_EMAIL = true ;; ;; Set the default theme for the Gitea install @@ -1294,12 +1302,16 @@ LEVEL = Info ;; Leave it empty to allow users to select any theme from "{CustomPath}/public/assets/css/theme-*.css" ;THEMES = ;; +;; The icons for file list (basic/material), this is a temporary option which will be replaced by a user setting in the future. +;FILE_ICON_THEME = material +;; ;; All available reactions users can choose on issues/prs and comments. ;; Values can be emoji alias (:smile:) or a unicode emoji. ;; For custom reactions, add a tightly cropped square image to public/assets/img/emoji/reaction_name.png ;REACTIONS = +1, -1, laugh, hooray, confused, heart, rocket, eyes ;; ;; Change the number of users that are displayed in reactions tooltip (triggered by mouse hover). +;; Deprecated in v1.24 ;REACTION_MAX_USER_NUM = 10 ;; ;; Additional Emojis not defined in the utf8 standard @@ -1308,17 +1320,21 @@ LEVEL = Info ;CUSTOM_EMOJIS = gitea, codeberg, gitlab, git, github, gogs ;; ;; Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used. +;; Deprecated in v1.24 ;DEFAULT_SHOW_FULL_NAME = false ;; ;; Whether to search within description at repository search on explore page. +;; Deprecated in v1.24 ;SEARCH_REPO_DESCRIPTION = true ;; ;; Whether to only show relevant repos on the explore page when no keyword is specified and default sorting is used. ;; A repo is considered irrelevant if it's a fork or if it has no metadata (no description, no icon, no topic). +;; Deprecated in v1.24 ;ONLY_SHOW_RELEVANT_REPOS = false ;; ;; Change the sort type of the explore pages. ;; Default is "recentupdate", but you also have "alphabetically", "reverselastlogin", "newest", "oldest". +;; Deprecated in v1.24 ;EXPLORE_PAGING_DEFAULT_SORT = recentupdate ;; ;; The tense all timestamps should be rendered in. Possible values are `absolute` time (i.e. 1970-01-01, 11:59) and `mixed`. @@ -1767,6 +1783,9 @@ LEVEL = Info ;; ;; convert \r\n to \n for Sendmail ;SENDMAIL_CONVERT_CRLF = true +;; +;; convert links of attached images to inline images. Only for images hosted in this gitea instance. +;EMBED_ATTACHMENT_IMAGES = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/go.mod b/go.mod index f2213b584e806..0a544a9100d6f 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ go 1.24 godebug x509negativeserial=1 require ( - code.gitea.io/actions-proto-go v0.4.0 + code.gitea.io/actions-proto-go v0.4.1 code.gitea.io/gitea-vet v0.2.3 code.gitea.io/sdk/gitea v0.20.0 codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 @@ -24,7 +24,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 - github.com/ProtonMail/go-crypto v1.1.5 + github.com/ProtonMail/go-crypto v1.1.6 github.com/PuerkitoBio/goquery v1.10.2 github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.3 github.com/alecthomas/chroma/v2 v2.15.0 @@ -119,7 +119,7 @@ require ( gitlab.com/gitlab-org/api/client-go v0.123.0 golang.org/x/crypto v0.35.0 golang.org/x/image v0.24.0 - golang.org/x/net v0.35.0 + golang.org/x/net v0.36.0 golang.org/x/oauth2 v0.27.0 golang.org/x/sync v0.11.0 golang.org/x/sys v0.30.0 @@ -318,7 +318,7 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 -replace github.com/nektos/act => gitea.com/gitea/act v0.261.3 +replace github.com/nektos/act => gitea.com/gitea/act v0.261.4 // TODO: the only difference is in `PutObject`: the fork doesn't use `NewVerifyingReader(r, sha256.New(), oid, expectedSize)`, need to figure out why replace github.com/charmbracelet/git-lfs-transfer => gitea.com/gitea/git-lfs-transfer v0.2.0 diff --git a/go.sum b/go.sum index 4047c846e4aae..6e0b0bde0721d 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU= -code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas= +code.gitea.io/actions-proto-go v0.4.1 h1:l0EYhjsgpUe/1VABo2eK7zcoNX2W44WOnb0MSLrKfls= +code.gitea.io/actions-proto-go v0.4.1/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas= code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI= code.gitea.io/gitea-vet v0.2.3/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= code.gitea.io/sdk/gitea v0.20.0 h1:Zm/QDwwZK1awoM4AxdjeAQbxolzx2rIP8dDfmKu+KoU= @@ -16,8 +16,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg= git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs= -gitea.com/gitea/act v0.261.3 h1:BhiYpGJQKGq0XMYYICCYAN4KnsEWHyLbA6dxhZwFcV4= -gitea.com/gitea/act v0.261.3/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok= +gitea.com/gitea/act v0.261.4 h1:Tf9eLlvsYFtKcpuxlMvf9yT3g4Hshb2Beqw6C1STuH8= +gitea.com/gitea/act v0.261.4/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok= gitea.com/gitea/git-lfs-transfer v0.2.0 h1:baHaNoBSRaeq/xKayEXwiDQtlIjps4Ac/Ll4KqLMB40= gitea.com/gitea/git-lfs-transfer v0.2.0/go.mod h1:UrXUCm3xLQkq15fu7qlXHUMlrhdlXHoi13KH2Dfiits= gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed h1:EZZBtilMLSZNWtHHcgq2mt6NSGhJSZBuduAlinMEmso= @@ -71,8 +71,8 @@ github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSC github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= -github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= +github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/PuerkitoBio/goquery v1.10.2 h1:7fh2BdHcG6VFZsK7toXBT/Bh1z5Wmy8Q9MV9HqT2AM8= github.com/PuerkitoBio/goquery v1.10.2/go.mod h1:0guWGjcLu9AYC7C1GHnpysHy056u9aEkUHwhdnePMCU= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= @@ -867,8 +867,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/models/actions/run.go b/models/actions/run.go index 60fbbcd3233ef..89f7f3e64031d 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -194,7 +194,7 @@ func updateRepoRunsNumbers(ctx context.Context, repo *repo_model.Repository) err // CancelPreviousJobs cancels all previous jobs of the same repository, reference, workflow, and event. // It's useful when a new run is triggered, and all previous runs needn't be continued anymore. -func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID string, event webhook_module.HookEventType) error { +func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID string, event webhook_module.HookEventType) ([]*ActionRunJob, error) { // Find all runs in the specified repository, reference, and workflow with non-final status runs, total, err := db.FindAndCount[ActionRun](ctx, FindRunOptions{ RepoID: repoID, @@ -204,14 +204,16 @@ func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID strin Status: []Status{StatusRunning, StatusWaiting, StatusBlocked}, }) if err != nil { - return err + return nil, err } // If there are no runs found, there's no need to proceed with cancellation, so return nil. if total == 0 { - return nil + return nil, nil } + cancelledJobs := make([]*ActionRunJob, 0, total) + // Iterate over each found run and cancel its associated jobs. for _, run := range runs { // Find all jobs associated with the current run. @@ -219,7 +221,7 @@ func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID strin RunID: run.ID, }) if err != nil { - return err + return cancelledJobs, err } // Iterate over each job and attempt to cancel it. @@ -238,27 +240,29 @@ func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID strin // Update the job's status and stopped time in the database. n, err := UpdateRunJob(ctx, job, builder.Eq{"task_id": 0}, "status", "stopped") if err != nil { - return err + return cancelledJobs, err } // If the update affected 0 rows, it means the job has changed in the meantime, so we need to try again. if n == 0 { - return fmt.Errorf("job has changed, try again") + return cancelledJobs, fmt.Errorf("job has changed, try again") } + cancelledJobs = append(cancelledJobs, job) // Continue with the next job. continue } // If the job has an associated task, try to stop the task, effectively cancelling the job. if err := StopTask(ctx, job.TaskID, StatusCancelled); err != nil { - return err + return cancelledJobs, err } + cancelledJobs = append(cancelledJobs, job) } } // Return nil to indicate successful cancellation of all running and waiting jobs. - return nil + return cancelledJobs, nil } // InsertRun inserts a run diff --git a/models/actions/run_list.go b/models/actions/run_list.go index b9b9324e0754f..5cd6af8d12162 100644 --- a/models/actions/run_list.go +++ b/models/actions/run_list.go @@ -134,6 +134,6 @@ func GetActors(ctx context.Context, repoID int64) ([]*user_model.User, error) { GroupBy("`action_run`.trigger_user_id"). Where(builder.Eq{"`action_run`.repo_id": repoID}))). Cols("id", "name", "full_name", "avatar", "avatar_email", "use_custom_avatar"). - OrderBy(user_model.GetOrderByName()). + OrderBy(user_model.GetOrderByName(ctx)). Find(&actors) } diff --git a/models/actions/runner.go b/models/actions/runner.go index 798a647180335..97db0ca7eac2f 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -337,3 +337,17 @@ func FixRunnersWithoutBelongingRepo(ctx context.Context) (int64, error) { } return res.RowsAffected() } + +func CountWrongRepoLevelRunners(ctx context.Context) (int64, error) { + var result int64 + _, err := db.GetEngine(ctx).SQL("SELECT count(`id`) FROM `action_runner` WHERE `repo_id` > 0 AND `owner_id` > 0").Get(&result) + return result, err +} + +func UpdateWrongRepoLevelRunners(ctx context.Context) (int64, error) { + result, err := db.GetEngine(ctx).Exec("UPDATE `action_runner` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0") + if err != nil { + return 0, err + } + return result.RowsAffected() +} diff --git a/models/actions/schedule.go b/models/actions/schedule.go index e2cc32eedca54..2edf483fe0d54 100644 --- a/models/actions/schedule.go +++ b/models/actions/schedule.go @@ -43,15 +43,12 @@ func init() { // GetSchedulesMapByIDs returns the schedules by given id slice. func GetSchedulesMapByIDs(ctx context.Context, ids []int64) (map[int64]*ActionSchedule, error) { schedules := make(map[int64]*ActionSchedule, len(ids)) + if len(ids) == 0 { + return schedules, nil + } return schedules, db.GetEngine(ctx).In("id", ids).Find(&schedules) } -// GetReposMapByIDs returns the repos by given id slice. -func GetReposMapByIDs(ctx context.Context, ids []int64) (map[int64]*repo_model.Repository, error) { - repos := make(map[int64]*repo_model.Repository, len(ids)) - return repos, db.GetEngine(ctx).In("id", ids).Find(&repos) -} - // CreateScheduleTask creates new schedule task. func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error { // Return early if there are no rows to insert @@ -120,21 +117,22 @@ func DeleteScheduleTaskByRepo(ctx context.Context, id int64) error { return committer.Commit() } -func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository) error { +func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository) ([]*ActionRunJob, error) { // If actions disabled when there is schedule task, this will remove the outdated schedule tasks // There is no other place we can do this because the app.ini will be changed manually if err := DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil { - return fmt.Errorf("DeleteCronTaskByRepo: %v", err) + return nil, fmt.Errorf("DeleteCronTaskByRepo: %v", err) } // cancel running cron jobs of this repository and delete old schedules - if err := CancelPreviousJobs( + jobs, err := CancelPreviousJobs( ctx, repo.ID, repo.DefaultBranch, "", webhook_module.HookEventSchedule, - ); err != nil { - return fmt.Errorf("CancelPreviousJobs: %v", err) + ) + if err != nil { + return jobs, fmt.Errorf("CancelPreviousJobs: %v", err) } - return nil + return jobs, nil } diff --git a/models/actions/schedule_spec_list.go b/models/actions/schedule_spec_list.go index f7dac72f8b38e..e26b2c11206f6 100644 --- a/models/actions/schedule_spec_list.go +++ b/models/actions/schedule_spec_list.go @@ -32,7 +32,7 @@ func (specs SpecList) LoadSchedules(ctx context.Context) error { } repoIDs := specs.GetRepoIDs() - repos, err := GetReposMapByIDs(ctx, repoIDs) + repos, err := repo_model.GetRepositoriesMapByIDs(ctx, repoIDs) if err != nil { return err } diff --git a/models/actions/variable.go b/models/actions/variable.go index 163bb12c9360c..1929cffbd8623 100644 --- a/models/actions/variable.go +++ b/models/actions/variable.go @@ -147,3 +147,17 @@ func GetVariablesOfRun(ctx context.Context, run *ActionRun) (map[string]string, return variables, nil } + +func CountWrongRepoLevelVariables(ctx context.Context) (int64, error) { + var result int64 + _, err := db.GetEngine(ctx).SQL("SELECT count(`id`) FROM `action_variable` WHERE `repo_id` > 0 AND `owner_id` > 0").Get(&result) + return result, err +} + +func UpdateWrongRepoLevelVariables(ctx context.Context) (int64, error) { + result, err := db.GetEngine(ctx).Exec("UPDATE `action_variable` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0") + if err != nil { + return 0, err + } + return result.RowsAffected() +} diff --git a/models/activities/action.go b/models/activities/action.go index 52dffe07fdc93..96ea63f54c3a3 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -16,9 +16,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" - access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" @@ -200,15 +198,13 @@ func (a *Action) LoadActUser(ctx context.Context) { } } -func (a *Action) LoadRepo(ctx context.Context) { +func (a *Action) LoadRepo(ctx context.Context) error { if a.Repo != nil { - return + return nil } var err error a.Repo, err = repo_model.GetRepositoryByID(ctx, a.RepoID) - if err != nil { - log.Error("repo_model.GetRepositoryByID(%d): %v", a.RepoID, err) - } + return err } // GetActFullName gets the action's user full name. @@ -231,7 +227,7 @@ func (a *Action) ShortActUserName(ctx context.Context) string { // GetActDisplayName gets the action's display name based on DEFAULT_SHOW_FULL_NAME, or falls back to the username if it is blank. func (a *Action) GetActDisplayName(ctx context.Context) string { - if setting.UI.DefaultShowFullName { + if setting.Config().UI.DefaultShowFullName.Value(ctx) { trimmedFullName := strings.TrimSpace(a.GetActFullName(ctx)) if len(trimmedFullName) > 0 { return trimmedFullName @@ -242,7 +238,7 @@ func (a *Action) GetActDisplayName(ctx context.Context) string { // GetActDisplayNameTitle gets the action's display name used for the title (tooltip) based on DEFAULT_SHOW_FULL_NAME func (a *Action) GetActDisplayNameTitle(ctx context.Context) string { - if setting.UI.DefaultShowFullName { + if setting.Config().UI.DefaultShowFullName.Value(ctx) { return a.ShortActUserName(ctx) } return a.GetActFullName(ctx) @@ -250,7 +246,7 @@ func (a *Action) GetActDisplayNameTitle(ctx context.Context) string { // GetRepoUserName returns the name of the action repository owner. func (a *Action) GetRepoUserName(ctx context.Context) string { - a.LoadRepo(ctx) + _ = a.LoadRepo(ctx) if a.Repo == nil { return "(non-existing-repo)" } @@ -265,7 +261,7 @@ func (a *Action) ShortRepoUserName(ctx context.Context) string { // GetRepoName returns the name of the action repository. func (a *Action) GetRepoName(ctx context.Context) string { - a.LoadRepo(ctx) + _ = a.LoadRepo(ctx) if a.Repo == nil { return "(non-existing-repo)" } @@ -529,8 +525,8 @@ func ActivityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder. } if opts.RequestedTeam != nil { - env := repo_model.AccessibleTeamReposEnv(ctx, organization.OrgFromUser(opts.RequestedUser), opts.RequestedTeam) - teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos) + env := repo_model.AccessibleTeamReposEnv(organization.OrgFromUser(opts.RequestedUser), opts.RequestedTeam) + teamRepoIDs, err := env.RepoIDs(ctx, 1, opts.RequestedUser.NumRepos) if err != nil { return nil, fmt.Errorf("GetTeamRepositories: %w", err) } @@ -567,130 +563,6 @@ func DeleteOldActions(ctx context.Context, olderThan time.Duration) (err error) return err } -// NotifyWatchers creates batch of actions for every watcher. -// It could insert duplicate actions for a repository action, like this: -// * Original action: UserID=1 (the real actor), ActUserID=1 -// * Organization action: UserID=100 (the repo's org), ActUserID=1 -// * Watcher action: UserID=20 (a user who is watching a repo), ActUserID=1 -func NotifyWatchers(ctx context.Context, actions ...*Action) error { - var watchers []*repo_model.Watch - var repo *repo_model.Repository - var err error - var permCode []bool - var permIssue []bool - var permPR []bool - - e := db.GetEngine(ctx) - - for _, act := range actions { - repoChanged := repo == nil || repo.ID != act.RepoID - - if repoChanged { - // Add feeds for user self and all watchers. - watchers, err = repo_model.GetWatchers(ctx, act.RepoID) - if err != nil { - return fmt.Errorf("get watchers: %w", err) - } - } - - // Add feed for actioner. - act.UserID = act.ActUserID - if _, err = e.Insert(act); err != nil { - return fmt.Errorf("insert new actioner: %w", err) - } - - if repoChanged { - act.LoadRepo(ctx) - repo = act.Repo - - // check repo owner exist. - if err := act.Repo.LoadOwner(ctx); err != nil { - return fmt.Errorf("can't get repo owner: %w", err) - } - } else if act.Repo == nil { - act.Repo = repo - } - - // Add feed for organization - if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID { - act.ID = 0 - act.UserID = act.Repo.Owner.ID - if err = db.Insert(ctx, act); err != nil { - return fmt.Errorf("insert new actioner: %w", err) - } - } - - if repoChanged { - permCode = make([]bool, len(watchers)) - permIssue = make([]bool, len(watchers)) - permPR = make([]bool, len(watchers)) - for i, watcher := range watchers { - user, err := user_model.GetUserByID(ctx, watcher.UserID) - if err != nil { - permCode[i] = false - permIssue[i] = false - permPR[i] = false - continue - } - perm, err := access_model.GetUserRepoPermission(ctx, repo, user) - if err != nil { - permCode[i] = false - permIssue[i] = false - permPR[i] = false - continue - } - permCode[i] = perm.CanRead(unit.TypeCode) - permIssue[i] = perm.CanRead(unit.TypeIssues) - permPR[i] = perm.CanRead(unit.TypePullRequests) - } - } - - for i, watcher := range watchers { - if act.ActUserID == watcher.UserID { - continue - } - act.ID = 0 - act.UserID = watcher.UserID - act.Repo.Units = nil - - switch act.OpType { - case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch: - if !permCode[i] { - continue - } - case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue: - if !permIssue[i] { - continue - } - case ActionCreatePullRequest, ActionCommentPull, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest, ActionAutoMergePullRequest: - if !permPR[i] { - continue - } - } - - if err = db.Insert(ctx, act); err != nil { - return fmt.Errorf("insert new action: %w", err) - } - } - } - return nil -} - -// NotifyWatchersActions creates batch of actions for every watcher. -func NotifyWatchersActions(ctx context.Context, acts []*Action) error { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - for _, act := range acts { - if err := NotifyWatchers(ctx, act); err != nil { - return err - } - } - return committer.Commit() -} - // DeleteIssueActions delete all actions related with issueID func DeleteIssueActions(ctx context.Context, repoID, issueID, issueIndex int64) error { // delete actions assigned to this issue diff --git a/models/activities/action_test.go b/models/activities/action_test.go index 9cfe98165686c..ee2a225a3e4cc 100644 --- a/models/activities/action_test.go +++ b/models/activities/action_test.go @@ -82,43 +82,6 @@ func TestActivityReadable(t *testing.T) { } } -func TestNotifyWatchers(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - action := &activities_model.Action{ - ActUserID: 8, - RepoID: 1, - OpType: activities_model.ActionStarRepo, - } - assert.NoError(t, activities_model.NotifyWatchers(db.DefaultContext, action)) - - // One watchers are inactive, thus action is only created for user 8, 1, 4, 11 - unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ - ActUserID: action.ActUserID, - UserID: 8, - RepoID: action.RepoID, - OpType: action.OpType, - }) - unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ - ActUserID: action.ActUserID, - UserID: 1, - RepoID: action.RepoID, - OpType: action.OpType, - }) - unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ - ActUserID: action.ActUserID, - UserID: 4, - RepoID: action.RepoID, - OpType: action.OpType, - }) - unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ - ActUserID: action.ActUserID, - UserID: 11, - RepoID: action.RepoID, - OpType: action.OpType, - }) -} - func TestConsistencyUpdateAction(t *testing.T) { if !setting.Database.Type.IsSQLite3() { t.Skip("Test is only for SQLite database.") diff --git a/models/asymkey/error.go b/models/asymkey/error.go index 2e65d76612982..1ed6edd71acb7 100644 --- a/models/asymkey/error.go +++ b/models/asymkey/error.go @@ -25,7 +25,7 @@ func (err ErrKeyUnableVerify) Error() string { } // ErrKeyIsPrivate is returned when the provided key is a private key not a public key -var ErrKeyIsPrivate = util.NewSilentWrapErrorf(util.ErrInvalidArgument, "the provided key is a private key") +var ErrKeyIsPrivate = util.ErrorWrap(util.ErrInvalidArgument, "the provided key is a private key") // ErrKeyNotExist represents a "KeyNotExist" kind of error. type ErrKeyNotExist struct { diff --git a/models/auth/access_token_scope.go b/models/auth/access_token_scope.go index 897ff3fc9ee3d..0e5b2e96e6602 100644 --- a/models/auth/access_token_scope.go +++ b/models/auth/access_token_scope.go @@ -5,6 +5,7 @@ package auth import ( "fmt" + "slices" "strings" "code.gitea.io/gitea/models/perm" @@ -14,7 +15,7 @@ import ( type AccessTokenScopeCategory int const ( - AccessTokenScopeCategoryActivityPub = iota + AccessTokenScopeCategoryActivityPub AccessTokenScopeCategory = iota AccessTokenScopeCategoryAdmin AccessTokenScopeCategoryMisc // WARN: this is now just a placeholder, don't remove it which will change the following values AccessTokenScopeCategoryNotification @@ -193,6 +194,14 @@ var accessTokenScopes = map[AccessTokenScopeLevel]map[AccessTokenScopeCategory]A }, } +func GetAccessTokenCategories() (res []string) { + for _, cat := range accessTokenScopes[Read] { + res = append(res, strings.TrimPrefix(string(cat), "read:")) + } + slices.Sort(res) + return res +} + // GetRequiredScopes gets the specific scopes for a given level and categories func GetRequiredScopes(level AccessTokenScopeLevel, scopeCategories ...AccessTokenScopeCategory) []AccessTokenScope { scopes := make([]AccessTokenScope, 0, len(scopeCategories)) @@ -270,6 +279,9 @@ func (s AccessTokenScope) parse() (accessTokenScopeBitmap, error) { // StringSlice returns the AccessTokenScope as a []string func (s AccessTokenScope) StringSlice() []string { + if s == "" { + return nil + } return strings.Split(string(s), ",") } diff --git a/models/auth/access_token_scope_test.go b/models/auth/access_token_scope_test.go index a6097e45d7f59..9e4aa83633736 100644 --- a/models/auth/access_token_scope_test.go +++ b/models/auth/access_token_scope_test.go @@ -17,6 +17,7 @@ type scopeTestNormalize struct { } func TestAccessTokenScope_Normalize(t *testing.T) { + assert.Equal(t, []string{"activitypub", "admin", "issue", "misc", "notification", "organization", "package", "repository", "user"}, GetAccessTokenCategories()) tests := []scopeTestNormalize{ {"", "", nil}, {"write:misc,write:notification,read:package,write:notification,public-only", "public-only,write:misc,write:notification,read:package", nil}, @@ -25,7 +26,7 @@ func TestAccessTokenScope_Normalize(t *testing.T) { {"write:activitypub,write:admin,write:misc,write:notification,write:organization,write:package,write:issue,write:repository,write:user,public-only", "public-only,all", nil}, } - for _, scope := range []string{"activitypub", "admin", "misc", "notification", "organization", "package", "issue", "repository", "user"} { + for _, scope := range GetAccessTokenCategories() { tests = append(tests, scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%s", scope)), AccessTokenScope(fmt.Sprintf("read:%s", scope)), nil}, scopeTestNormalize{AccessTokenScope(fmt.Sprintf("write:%s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, @@ -59,7 +60,7 @@ func TestAccessTokenScope_HasScope(t *testing.T) { {"public-only", "read:issue", false, nil}, } - for _, scope := range []string{"activitypub", "admin", "misc", "notification", "organization", "package", "issue", "repository", "user"} { + for _, scope := range GetAccessTokenCategories() { tests = append(tests, scopeTestHasScope{ AccessTokenScope(fmt.Sprintf("read:%s", scope)), diff --git a/models/db/context.go b/models/db/context.go index 51627712b1167..4b98796ef0223 100644 --- a/models/db/context.go +++ b/models/db/context.go @@ -289,6 +289,9 @@ func FindIDs(ctx context.Context, tableName, idCol string, cond builder.Cond) ([ // DecrByIDs decreases the given column for entities of the "bean" type with one of the given ids by one // Timestamps of the entities won't be updated func DecrByIDs(ctx context.Context, ids []int64, decrCol string, bean any) error { + if len(ids) == 0 { + return nil + } _, err := GetEngine(ctx).Decr(decrCol).In("id", ids).NoAutoCondition().NoAutoTime().Update(bean) return err } diff --git a/models/db/engine_hook.go b/models/db/engine_hook.go index 2c9fc09c99da7..8709a2c2a1393 100644 --- a/models/db/engine_hook.go +++ b/models/db/engine_hook.go @@ -41,7 +41,7 @@ func (h *EngineHook) AfterProcess(c *contexts.ContextHook) error { // 8 is the amount of skips passed to runtime.Caller, so that in the log the correct function // is being displayed (the function that ultimately wants to execute the query in the code) // instead of the function of the slow query hook being called. - h.Logger.Log(8, log.WARN, "[Slow SQL Query] %s %v - %v", c.SQL, c.Args, c.ExecuteTime) + h.Logger.Log(8, &log.Event{Level: log.WARN}, "[Slow SQL Query] %s %v - %v", c.SQL, c.Args, c.ExecuteTime) } return nil } diff --git a/models/db/engine_init.go b/models/db/engine_init.go index edca6979342df..7a071fa29b918 100644 --- a/models/db/engine_init.go +++ b/models/db/engine_init.go @@ -105,7 +105,7 @@ func UnsetDefaultEngine() { // When called from the "doctor" command, the migration function is a version check // that prevents the doctor from fixing anything in the database if the migration level // is different from the expected value. -func InitEngineWithMigration(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err error) { +func InitEngineWithMigration(ctx context.Context, migrateFunc func(context.Context, *xorm.Engine) error) (err error) { if err = InitEngine(ctx); err != nil { return err } @@ -122,7 +122,7 @@ func InitEngineWithMigration(ctx context.Context, migrateFunc func(*xorm.Engine) // Installation should only be being re-run if users want to recover an old database. // However, we should think carefully about should we support re-install on an installed instance, // as there may be other problems due to secret reinitialization. - if err = migrateFunc(xormEngine); err != nil { + if err = migrateFunc(ctx, xormEngine); err != nil { return fmt.Errorf("migrate: %w", err) } diff --git a/models/db/log.go b/models/db/log.go index 307788ea2e49f..a9df6f541dbf7 100644 --- a/models/db/log.go +++ b/models/db/log.go @@ -29,7 +29,7 @@ const stackLevel = 8 // Log a message with defined skip and at logging level func (l *XORMLogBridge) Log(skip int, level log.Level, format string, v ...any) { - l.logger.Log(skip+1, level, format, v...) + l.logger.Log(skip+1, &log.Event{Level: level}, format, v...) } // Debug show debug log diff --git a/models/db/name.go b/models/db/name.go index e2165fd76bbad..0e11c78372308 100644 --- a/models/db/name.go +++ b/models/db/name.go @@ -77,7 +77,7 @@ func (err ErrNameCharsNotAllowed) Unwrap() error { func IsUsableName(reservedNames, reservedPatterns []string, name string) error { name = strings.TrimSpace(strings.ToLower(name)) if utf8.RuneCountInString(name) == 0 { - return util.SilentWrap{Message: "name is empty", Err: util.ErrInvalidArgument} + return util.NewInvalidArgumentErrorf("name is empty") } for i := range reservedNames { diff --git a/models/issues/issue.go b/models/issues/issue.go index 7e72bb776c6b9..5204f27faffbe 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -595,6 +595,9 @@ func GetIssueByID(ctx context.Context, id int64) (*Issue, error) { // If keepOrder is true, the order of the returned issues will be the same as the given IDs. func GetIssuesByIDs(ctx context.Context, issueIDs []int64, keepOrder ...bool) (IssueList, error) { issues := make([]*Issue, 0, len(issueIDs)) + if len(issueIDs) == 0 { + return issues, nil + } if err := db.GetEngine(ctx).In("id", issueIDs).Find(&issues); err != nil { return nil, err diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index 6c74b533b3c54..4b1d495b10507 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -251,7 +251,7 @@ func (issues IssueList) LoadAssignees(ctx context.Context) error { } rows, err := db.GetEngine(ctx).Table("issue_assignees"). Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id"). - In("`issue_assignees`.issue_id", issueIDs[:limit]).OrderBy(user_model.GetOrderByName()). + In("`issue_assignees`.issue_id", issueIDs[:limit]).OrderBy(user_model.GetOrderByName(ctx)). Rows(new(AssigneeIssue)) if err != nil { return err diff --git a/models/issues/label.go b/models/issues/label.go index b9d24bbe99166..8a5d9321cc03d 100644 --- a/models/issues/label.go +++ b/models/issues/label.go @@ -299,6 +299,9 @@ func GetLabelByID(ctx context.Context, labelID int64) (*Label, error) { // GetLabelsByIDs returns a list of labels by IDs func GetLabelsByIDs(ctx context.Context, labelIDs []int64, cols ...string) ([]*Label, error) { labels := make([]*Label, 0, len(labelIDs)) + if len(labelIDs) == 0 { + return labels, nil + } return labels, db.GetEngine(ctx).Table("label"). In("id", labelIDs). Asc("name"). @@ -375,6 +378,9 @@ func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder { // it silently ignores label IDs that do not belong to the repository. func GetLabelsInRepoByIDs(ctx context.Context, repoID int64, labelIDs []int64) ([]*Label, error) { labels := make([]*Label, 0, len(labelIDs)) + if len(labelIDs) == 0 { + return labels, nil + } return labels, db.GetEngine(ctx). Where("repo_id = ?", repoID). In("id", labelIDs). @@ -447,6 +453,9 @@ func GetLabelInOrgByID(ctx context.Context, orgID, labelID int64) (*Label, error // it silently ignores label IDs that do not belong to the organization. func GetLabelsInOrgByIDs(ctx context.Context, orgID int64, labelIDs []int64) ([]*Label, error) { labels := make([]*Label, 0, len(labelIDs)) + if len(labelIDs) == 0 { + return labels, nil + } return labels, db.GetEngine(ctx). Where("org_id = ?", orgID). In("id", labelIDs). diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index 28cd0c028b8af..bd3dee3f7a9c3 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -98,7 +98,7 @@ func TestGetMilestones(t *testing.T) { milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, - PageSize: setting.UI.IssuePagingNum, + PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()), }, RepoID: repo.ID, IsClosed: optional.Some(false), @@ -115,7 +115,7 @@ func TestGetMilestones(t *testing.T) { milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, - PageSize: setting.UI.IssuePagingNum, + PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()), }, RepoID: repo.ID, IsClosed: optional.Some(true), @@ -231,7 +231,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { openMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, - PageSize: setting.UI.IssuePagingNum, + PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()), }, RepoIDs: []int64{repo1.ID, repo2.ID}, IsClosed: optional.Some(false), @@ -249,7 +249,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, - PageSize: setting.UI.IssuePagingNum, + PageSize: setting.Config().UI.IssuePagingNum.Value(t.Context()), }, RepoIDs: []int64{repo1.ID, repo2.ID}, IsClosed: optional.Some(true), diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go index 1ddb94e566b37..b685175f8e324 100644 --- a/models/issues/pull_list.go +++ b/models/issues/pull_list.go @@ -28,11 +28,16 @@ type PullRequestsOptions struct { Labels []int64 MilestoneID int64 PosterID int64 + BaseBranch string } func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullRequestsOptions) *xorm.Session { sess := db.GetEngine(ctx).Where("pull_request.base_repo_id=?", baseRepoID) + if opts.BaseBranch != "" { + sess.And("pull_request.base_branch=?", opts.BaseBranch) + } + sess.Join("INNER", "issue", "pull_request.issue_id = issue.id") switch opts.State { case "closed", "open": @@ -56,7 +61,7 @@ func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullR } // GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged -func GetUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch string) ([]*PullRequest, error) { +func GetUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch string) (PullRequestList, error) { prs := make([]*PullRequest, 0, 2) sess := db.GetEngine(ctx). Join("INNER", "issue", "issue.id = pull_request.issue_id"). @@ -111,7 +116,7 @@ func HasUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch // GetUnmergedPullRequestsByBaseInfo returns all pull requests that are open and has not been merged // by given base information (repo and branch). -func GetUnmergedPullRequestsByBaseInfo(ctx context.Context, repoID int64, branch string) ([]*PullRequest, error) { +func GetUnmergedPullRequestsByBaseInfo(ctx context.Context, repoID int64, branch string) (PullRequestList, error) { prs := make([]*PullRequest, 0, 2) return prs, db.GetEngine(ctx). Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?", diff --git a/models/issues/pull_list_test.go b/models/issues/pull_list_test.go index c7a898ca4e8b8..f5553e7885778 100644 --- a/models/issues/pull_list_test.go +++ b/models/issues/pull_list_test.go @@ -16,11 +16,11 @@ import ( func TestPullRequestList_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs := []*issues_model.PullRequest{ + prs := issues_model.PullRequestList{ unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}), } - assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes(db.DefaultContext)) + assert.NoError(t, prs.LoadAttributes(db.DefaultContext)) for _, pr := range prs { assert.NotNil(t, pr.Issue) assert.Equal(t, pr.IssueID, pr.Issue.ID) @@ -32,11 +32,11 @@ func TestPullRequestList_LoadAttributes(t *testing.T) { func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs := []*issues_model.PullRequest{ + prs := issues_model.PullRequestList{ unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}), } - reviewComments, err := issues_model.PullRequestList(prs).LoadReviewCommentsCounts(db.DefaultContext) + reviewComments, err := prs.LoadReviewCommentsCounts(db.DefaultContext) assert.NoError(t, err) assert.Len(t, reviewComments, 2) for _, pr := range prs { @@ -47,11 +47,11 @@ func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) { func TestPullRequestList_LoadReviews(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs := []*issues_model.PullRequest{ + prs := issues_model.PullRequestList{ unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}), unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}), } - reviewList, err := issues_model.PullRequestList(prs).LoadReviews(db.DefaultContext) + reviewList, err := prs.LoadReviews(db.DefaultContext) assert.NoError(t, err) // 1, 7, 8, 9, 10, 22 assert.Len(t, reviewList, 6) diff --git a/models/issues/reaction.go b/models/issues/reaction.go index f24001fd23156..f56ef758dd94f 100644 --- a/models/issues/reaction.go +++ b/models/issues/reaction.go @@ -355,9 +355,9 @@ func (list ReactionList) LoadUsers(ctx context.Context, repo *repo_model.Reposit } // GetFirstUsers returns first reacted user display names separated by comma -func (list ReactionList) GetFirstUsers() string { +func (list ReactionList) GetFirstUsers(ctx context.Context) string { var buffer bytes.Buffer - rem := setting.UI.ReactionMaxUserNum + rem := setting.Config().UI.ReactionMaxUserNum.Value(ctx) for _, reaction := range list { if buffer.Len() > 0 { buffer.WriteString(", ") @@ -371,9 +371,9 @@ func (list ReactionList) GetFirstUsers() string { } // GetMoreUserCount returns count of not shown users in reaction tooltip -func (list ReactionList) GetMoreUserCount() int { - if len(list) <= setting.UI.ReactionMaxUserNum { +func (list ReactionList) GetMoreUserCount(ctx context.Context) int { + if len(list) <= setting.Config().UI.ReactionMaxUserNum.Value(ctx) { return 0 } - return len(list) - setting.UI.ReactionMaxUserNum + return len(list) - setting.Config().UI.ReactionMaxUserNum.Value(ctx) } diff --git a/models/migrations/fixtures/Test_MigrateIniToDatabase/system_setting.yml b/models/migrations/fixtures/Test_MigrateIniToDatabase/system_setting.yml new file mode 100644 index 0000000000000..f62e50bc69a2d --- /dev/null +++ b/models/migrations/fixtures/Test_MigrateIniToDatabase/system_setting.yml @@ -0,0 +1,24 @@ +# type Setting struct { +# ID int64 `xorm:"pk autoincr"` +# SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase +# SettingValue string `xorm:"text"` +# Version int `xorm:"version"` +# Created timeutil.TimeStamp `xorm:"created"` +# Updated timeutil.TimeStamp `xorm:"updated"` +# } +- + id: 1 + setting_key: revision + version: 1 + +- + id: 2 + setting_key: picture.enable_federated_avatar + setting_value: false + version: 1 + +- + id: 3 + setting_key: picture.disable_gravatar + setting_value: true + version: 1 diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 87d674a440999..a8550253dcba4 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -374,6 +374,8 @@ func prepareMigrationTasks() []*migration { // Gitea 1.23.0-rc0 ends at migration ID number 311 (database version 312) newMigration(312, "Add DeleteBranchAfterMerge to AutoMerge", v1_24.AddDeleteBranchAfterMergeForAutoMerge), newMigration(313, "Move PinOrder from issue table to a new table issue_pin", v1_24.MovePinOrderToTableIssuePin), + newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables), + newMigration(315, "Migrate the configuration of the ui section of the ini configuration file to the system setting table.", v1_24.MigrateIniToDatabase), } return preparedMigrations } @@ -412,7 +414,7 @@ func ExpectedDBVersion() int64 { } // EnsureUpToDate will check if the db is at the correct version -func EnsureUpToDate(x *xorm.Engine) error { +func EnsureUpToDate(ctx context.Context, x *xorm.Engine) error { currentDB, err := GetCurrentDBVersion(x) if err != nil { return err diff --git a/models/migrations/v1_12/v128.go b/models/migrations/v1_12/v128.go index 44d44a26c549f..cba64711d0976 100644 --- a/models/migrations/v1_12/v128.go +++ b/models/migrations/v1_12/v128.go @@ -82,17 +82,17 @@ func FixMergeBase(x *xorm.Engine) error { if !pr.HasMerged { var err error - pr.MergeBase, _, err = git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(&git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) if err != nil { var err2 error - pr.MergeBase, _, err2 = git.NewCommand(git.DefaultContext, "rev-parse").AddDynamicArguments(git.BranchPrefix + pr.BaseBranch).RunStdString(&git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) if err2 != nil { log.Error("Unable to get merge base for PR ID %d, Index %d in %s/%s. Error: %v & %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err, err2) continue } } } else { - parentsString, _, err := git.NewCommand(git.DefaultContext, "rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(&git.RunOpts{Dir: repoPath}) + parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue @@ -104,9 +104,9 @@ func FixMergeBase(x *xorm.Engine) error { refs := append([]string{}, parents[1:]...) refs = append(refs, gitRefName) - cmd := git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(refs...) + cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) - pr.MergeBase, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue diff --git a/models/migrations/v1_12/v134.go b/models/migrations/v1_12/v134.go index 3d1c82f09e164..a918d38757919 100644 --- a/models/migrations/v1_12/v134.go +++ b/models/migrations/v1_12/v134.go @@ -79,7 +79,7 @@ func RefixMergeBase(x *xorm.Engine) error { gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index) - parentsString, _, err := git.NewCommand(git.DefaultContext, "rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(&git.RunOpts{Dir: repoPath}) + parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue @@ -92,9 +92,9 @@ func RefixMergeBase(x *xorm.Engine) error { // we should recalculate refs := append([]string{}, parents[1:]...) refs = append(refs, gitRefName) - cmd := git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(refs...) + cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) - pr.MergeBase, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = cmd.RunStdString(git.DefaultContext, &git.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue diff --git a/models/migrations/v1_24/main_test.go b/models/migrations/v1_24/main_test.go new file mode 100644 index 0000000000000..53050554d47ee --- /dev/null +++ b/models/migrations/v1_24/main_test.go @@ -0,0 +1,14 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_24 //nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func TestMain(m *testing.M) { + base.MainTest(m) +} diff --git a/models/migrations/v1_24/v314.go b/models/migrations/v1_24/v314.go new file mode 100644 index 0000000000000..e537be13b5c35 --- /dev/null +++ b/models/migrations/v1_24/v314.go @@ -0,0 +1,19 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_24 //nolint + +import ( + "xorm.io/xorm" +) + +func UpdateOwnerIDOfRepoLevelActionsTables(x *xorm.Engine) error { + if _, err := x.Exec("UPDATE `action_runner` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0"); err != nil { + return err + } + if _, err := x.Exec("UPDATE `action_variable` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0"); err != nil { + return err + } + _, err := x.Exec("UPDATE `secret` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0") + return err +} diff --git a/models/migrations/v1_24/v315.go b/models/migrations/v1_24/v315.go new file mode 100644 index 0000000000000..8157f48f0ae84 --- /dev/null +++ b/models/migrations/v1_24/v315.go @@ -0,0 +1,98 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_24 //nolint + +import ( + "math" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" + + "xorm.io/xorm" +) + +const keyRevision = "revision" + +type Setting struct { + ID int64 `xorm:"pk autoincr"` + SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase + SettingValue string `xorm:"text"` + Version int `xorm:"version"` + Created timeutil.TimeStamp `xorm:"created"` + Updated timeutil.TimeStamp `xorm:"updated"` +} + +// TableName sets the table name for the settings struct +func (s *Setting) TableName() string { + return "system_setting" +} + +func MigrateIniToDatabase(x *xorm.Engine) error { + uiMap, err := util.ConfigSectionToMap( + setting.UI, "ui", + []string{ + "Reactions", "CustomEmojis", "MaxDisplayFileSize", "DefaultTheme", "Themes", + "FileIconTheme", "PreferredTimestampTense", "AmbiguousUnicodeDetection", + }..., + ) + if err != nil { + return err + } + + sess := x.NewSession() + defer sess.Close() + + if err = sess.Begin(); err != nil { + return err + } + + if err = sess.Sync(new(Setting)); err != nil { + return err + } + + _ = getRevision(sess) // prepare the "revision" key ahead + + _, err = sess.Exec("UPDATE system_setting SET version=version+1 WHERE setting_key=?", keyRevision) + if err != nil { + return err + } + for k, v := range uiMap { + res, err := sess.Exec("UPDATE system_setting SET version=version+1, setting_value=? WHERE setting_key=?", v, k) + if err != nil { + return err + } + rows, _ := res.RowsAffected() + if rows == 0 { // if no existing row, insert a new row + if _, err = sess.Insert(&Setting{SettingKey: k, SettingValue: v}); err != nil { + return err + } + } + } + + return sess.Commit() +} + +func getRevision(sess *xorm.Session) int { + revision := &Setting{} + exist, err := sess.Where("setting_key = ?", keyRevision).Get(revision) + if err != nil { + return 0 + } else if !exist { + _, err = sess.Insert(&Setting{SettingKey: keyRevision, Version: 1}) + if err != nil { + return 0 + } + return 1 + } + + if revision.Version <= 0 || revision.Version >= math.MaxInt-1 { + _, err = sess.Exec("UPDATE system_setting SET version=1 WHERE setting_key=?", keyRevision) + if err != nil { + return 0 + } + return 1 + } + return revision.Version +} diff --git a/models/migrations/v1_24/v315_test.go b/models/migrations/v1_24/v315_test.go new file mode 100644 index 0000000000000..2a930bc353248 --- /dev/null +++ b/models/migrations/v1_24/v315_test.go @@ -0,0 +1,27 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_24 //nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" + + "github.com/stretchr/testify/assert" +) + +func Test_MigrateIniToDatabase(t *testing.T) { + // Prepare and load the testing database + x, deferable := base.PrepareTestEnv(t, 0, new(Setting)) + defer deferable() + if x == nil || t.Failed() { + return + } + + assert.NoError(t, MigrateIniToDatabase(x)) + + cnt, err := x.Table("system_setting").Where("setting_key LIKE 'ui.%'").Count() + assert.NoError(t, err) + assert.EqualValues(t, 16, cnt) +} diff --git a/models/organization/org.go b/models/organization/org.go index 3e55a36758963..fff8cc8b4ff6b 100644 --- a/models/organization/org.go +++ b/models/organization/org.go @@ -169,8 +169,8 @@ func (org *Organization) OrganisationLink() string { } // ShortName ellipses username to length -func (org *Organization) ShortName(length int) string { - return org.AsUser().ShortName(length) +func (org *Organization) ShortName(ctx context.Context, length int) string { + return org.AsUser().ShortName(ctx, length) } // HomeLink returns the user or organization home page link. diff --git a/models/organization/org_test.go b/models/organization/org_test.go index b882a25be328a..6638abd8e07a3 100644 --- a/models/organization/org_test.go +++ b/models/organization/org_test.go @@ -320,7 +320,7 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) { testSuccess := func(userID, expectedCount int64) { env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) - count, err := env.CountRepos() + count, err := env.CountRepos(db.DefaultContext) assert.NoError(t, err) assert.EqualValues(t, expectedCount, count) } @@ -334,7 +334,7 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) { testSuccess := func(userID int64, expectedRepoIDs []int64) { env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) - repoIDs, err := env.RepoIDs(1, 100) + repoIDs, err := env.RepoIDs(db.DefaultContext, 1, 100) assert.NoError(t, err) assert.Equal(t, expectedRepoIDs, repoIDs) } @@ -348,7 +348,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) { testSuccess := func(userID int64, expectedRepoIDs []int64) { env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) - repos, err := env.Repos(1, 100) + repos, err := env.Repos(db.DefaultContext, 1, 100) assert.NoError(t, err) expectedRepos := make(repo_model.RepositoryList, len(expectedRepoIDs)) for i, repoID := range expectedRepoIDs { @@ -367,7 +367,7 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { testSuccess := func(userID int64, expectedRepoIDs []int64) { env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) - repos, err := env.MirrorRepos() + repos, err := env.MirrorRepos(db.DefaultContext) assert.NoError(t, err) expectedRepos := make(repo_model.RepositoryList, len(expectedRepoIDs)) for i, repoID := range expectedRepoIDs { diff --git a/models/organization/org_user.go b/models/organization/org_user.go index 08d936d922f05..d9b14b57f45f1 100644 --- a/models/organization/org_user.go +++ b/models/organization/org_user.go @@ -163,7 +163,7 @@ func GetOrgAssignees(ctx context.Context, orgID int64) (_ []*user_model.User, er if len(userIDs) > 0 { if err = e.In("id", uniqueUserIDs.Values()). Where(builder.Eq{"`user`.is_active": true}). - OrderBy(user_model.GetOrderByName()). + OrderBy(user_model.GetOrderByName(ctx)). Find(&users); err != nil { return nil, err } diff --git a/models/organization/team_list.go b/models/organization/team_list.go index 6f2a922e954d9..0274f9c5ba4cc 100644 --- a/models/organization/team_list.go +++ b/models/organization/team_list.go @@ -133,5 +133,8 @@ func GetTeamsByOrgIDs(ctx context.Context, orgIDs []int64) (TeamList, error) { func GetTeamsByIDs(ctx context.Context, teamIDs []int64) (map[int64]*Team, error) { teams := make(map[int64]*Team, len(teamIDs)) + if len(teamIDs) == 0 { + return teams, nil + } return teams, db.GetEngine(ctx).Where(builder.In("`id`", teamIDs)).Find(&teams) } diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go index 803b73c968995..d251fcc4a90df 100644 --- a/models/packages/descriptor.go +++ b/models/packages/descriptor.go @@ -110,9 +110,12 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc if err != nil { return nil, err } - repository, err := repo_model.GetRepositoryByID(ctx, p.RepoID) - if err != nil && !repo_model.IsErrRepoNotExist(err) { - return nil, err + var repository *repo_model.Repository + if p.RepoID > 0 { + repository, err = repo_model.GetRepositoryByID(ctx, p.RepoID) + if err != nil && !repo_model.IsErrRepoNotExist(err) { + return nil, err + } } creator, err := user_model.GetUserByID(ctx, pv.CreatorID) if err != nil { diff --git a/models/project/column.go b/models/project/column.go index 5f581b58804cb..77ff5ef83e025 100644 --- a/models/project/column.go +++ b/models/project/column.go @@ -336,6 +336,9 @@ func UpdateColumnSorting(ctx context.Context, cl ColumnList) error { func GetColumnsByIDs(ctx context.Context, projectID int64, columnsIDs []int64) (ColumnList, error) { columns := make([]*Column, 0, 5) + if len(columnsIDs) == 0 { + return columns, nil + } if err := db.GetEngine(ctx). Where("project_id =?", projectID). In("id", columnsIDs). diff --git a/models/repo/archiver.go b/models/repo/archiver.go index 5a3eac9f148c0..d06e94e5ac113 100644 --- a/models/repo/archiver.go +++ b/models/repo/archiver.go @@ -50,15 +50,15 @@ func (archiver *RepoArchiver) RelativePath() string { func repoArchiverForRelativePath(relativePath string) (*RepoArchiver, error) { parts := strings.SplitN(relativePath, "/", 3) if len(parts) != 3 { - return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument} + return nil, util.NewInvalidArgumentErrorf("invalid storage path: must have 3 parts") } repoID, err := strconv.ParseInt(parts[0], 10, 64) if err != nil { - return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument} + return nil, util.NewInvalidArgumentErrorf("invalid storage path: invalid repo id") } commitID, archiveType := git.SplitArchiveNameType(parts[2]) if archiveType == git.ArchiveUnknown { - return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument} + return nil, util.NewInvalidArgumentErrorf("invalid storage path: invalid archive type") } return &RepoArchiver{RepoID: repoID, CommitID: commitID, Type: archiveType}, nil } diff --git a/models/repo/org_repo.go b/models/repo/org_repo.go index 5f0af2d475abd..fa519d25b1980 100644 --- a/models/repo/org_repo.go +++ b/models/repo/org_repo.go @@ -47,10 +47,10 @@ func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (Repo // AccessibleReposEnvironment operations involving the repositories that are // accessible to a particular user type AccessibleReposEnvironment interface { - CountRepos() (int64, error) - RepoIDs(page, pageSize int) ([]int64, error) - Repos(page, pageSize int) (RepositoryList, error) - MirrorRepos() (RepositoryList, error) + CountRepos(ctx context.Context) (int64, error) + RepoIDs(ctx context.Context, page, pageSize int) ([]int64, error) + Repos(ctx context.Context, page, pageSize int) (RepositoryList, error) + MirrorRepos(ctx context.Context) (RepositoryList, error) AddKeyword(keyword string) SetSort(db.SearchOrderBy) } @@ -60,7 +60,6 @@ type accessibleReposEnv struct { user *user_model.User team *org_model.Team teamIDs []int64 - ctx context.Context keyword string orderBy db.SearchOrderBy } @@ -86,18 +85,16 @@ func AccessibleReposEnv(ctx context.Context, org *org_model.Organization, userID org: org, user: user, teamIDs: teamIDs, - ctx: ctx, orderBy: db.SearchOrderByRecentUpdated, }, nil } // AccessibleTeamReposEnv an AccessibleReposEnvironment for the repositories in `org` // that are accessible to the specified team. -func AccessibleTeamReposEnv(ctx context.Context, org *org_model.Organization, team *org_model.Team) AccessibleReposEnvironment { +func AccessibleTeamReposEnv(org *org_model.Organization, team *org_model.Team) AccessibleReposEnvironment { return &accessibleReposEnv{ org: org, team: team, - ctx: ctx, orderBy: db.SearchOrderByRecentUpdated, } } @@ -123,8 +120,8 @@ func (env *accessibleReposEnv) cond() builder.Cond { return cond } -func (env *accessibleReposEnv) CountRepos() (int64, error) { - repoCount, err := db.GetEngine(env.ctx). +func (env *accessibleReposEnv) CountRepos(ctx context.Context) (int64, error) { + repoCount, err := db.GetEngine(ctx). Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). Where(env.cond()). Distinct("`repository`.id"). @@ -135,13 +132,13 @@ func (env *accessibleReposEnv) CountRepos() (int64, error) { return repoCount, nil } -func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) { +func (env *accessibleReposEnv) RepoIDs(ctx context.Context, page, pageSize int) ([]int64, error) { if page <= 0 { page = 1 } repoIDs := make([]int64, 0, pageSize) - return repoIDs, db.GetEngine(env.ctx). + return repoIDs, db.GetEngine(ctx). Table("repository"). Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). Where(env.cond()). @@ -152,8 +149,8 @@ func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) { Find(&repoIDs) } -func (env *accessibleReposEnv) Repos(page, pageSize int) (RepositoryList, error) { - repoIDs, err := env.RepoIDs(page, pageSize) +func (env *accessibleReposEnv) Repos(ctx context.Context, page, pageSize int) (RepositoryList, error) { + repoIDs, err := env.RepoIDs(ctx, page, pageSize) if err != nil { return nil, fmt.Errorf("GetUserRepositoryIDs: %w", err) } @@ -163,15 +160,15 @@ func (env *accessibleReposEnv) Repos(page, pageSize int) (RepositoryList, error) return repos, nil } - return repos, db.GetEngine(env.ctx). + return repos, db.GetEngine(ctx). In("`repository`.id", repoIDs). OrderBy(string(env.orderBy)). Find(&repos) } -func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) { +func (env *accessibleReposEnv) MirrorRepoIDs(ctx context.Context) ([]int64, error) { repoIDs := make([]int64, 0, 10) - return repoIDs, db.GetEngine(env.ctx). + return repoIDs, db.GetEngine(ctx). Table("repository"). Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true). Where(env.cond()). @@ -181,8 +178,8 @@ func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) { Find(&repoIDs) } -func (env *accessibleReposEnv) MirrorRepos() (RepositoryList, error) { - repoIDs, err := env.MirrorRepoIDs() +func (env *accessibleReposEnv) MirrorRepos(ctx context.Context) (RepositoryList, error) { + repoIDs, err := env.MirrorRepoIDs(ctx) if err != nil { return nil, fmt.Errorf("MirrorRepoIDs: %w", err) } @@ -192,7 +189,7 @@ func (env *accessibleReposEnv) MirrorRepos() (RepositoryList, error) { return repos, nil } - return repos, db.GetEngine(env.ctx). + return repos, db.GetEngine(ctx). In("`repository`.id", repoIDs). Find(&repos) } diff --git a/models/repo/repo.go b/models/repo/repo.go index 4e27dbaf1467e..13473699f38d4 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -646,13 +646,15 @@ func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML { type CloneLink struct { SSH string HTTPS string + Tea string } -// ComposeHTTPSCloneURL returns HTTPS clone URL based on given owner and repository name. +// ComposeHTTPSCloneURL returns HTTPS clone URL based on the given owner and repository name. func ComposeHTTPSCloneURL(ctx context.Context, owner, repo string) string { return fmt.Sprintf("%s%s/%s.git", httplib.GuessCurrentAppURL(ctx), url.PathEscape(owner), url.PathEscape(repo)) } +// ComposeSSHCloneURL returns SSH clone URL based on the given owner and repository name. func ComposeSSHCloneURL(doer *user_model.User, ownerName, repoName string) string { sshUser := setting.SSH.User sshDomain := setting.SSH.Domain @@ -686,11 +688,17 @@ func ComposeSSHCloneURL(doer *user_model.User, ownerName, repoName string) strin return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) } +// ComposeTeaCloneCommand returns Tea CLI clone command based on the given owner and repository name. +func ComposeTeaCloneCommand(ctx context.Context, owner, repo string) string { + return fmt.Sprintf("tea clone %s/%s", url.PathEscape(owner), url.PathEscape(repo)) +} + func (repo *Repository) cloneLink(ctx context.Context, doer *user_model.User, repoPathName string) *CloneLink { - cl := new(CloneLink) - cl.SSH = ComposeSSHCloneURL(doer, repo.OwnerName, repoPathName) - cl.HTTPS = ComposeHTTPSCloneURL(ctx, repo.OwnerName, repoPathName) - return cl + return &CloneLink{ + SSH: ComposeSSHCloneURL(doer, repo.OwnerName, repoPathName), + HTTPS: ComposeHTTPSCloneURL(ctx, repo.OwnerName, repoPathName), + Tea: ComposeTeaCloneCommand(ctx, repo.OwnerName, repoPathName), + } } // CloneLink returns clone URLs of repository. @@ -831,6 +839,9 @@ func GetRepositoryByID(ctx context.Context, id int64) (*Repository, error) { // GetRepositoriesMapByIDs returns the repositories by given id slice. func GetRepositoriesMapByIDs(ctx context.Context, ids []int64) (map[int64]*Repository, error) { repos := make(map[int64]*Repository, len(ids)) + if len(ids) == 0 { + return repos, nil + } return repos, db.GetEngine(ctx).In("id", ids).Find(&repos) } diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 9bed2e919723b..02c228e8a0e3a 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -21,11 +21,6 @@ import ( "xorm.io/builder" ) -// FindReposMapByIDs find repos as map -func FindReposMapByIDs(ctx context.Context, repoIDs []int64, res map[int64]*Repository) error { - return db.GetEngine(ctx).In("id", repoIDs).Find(&res) -} - // RepositoryListDefaultPageSize is the default number of repositories // to load in memory when running administrative tasks on all (or almost // all) of them. diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go index 232087d86594e..9630974688010 100644 --- a/models/repo/user_repo.go +++ b/models/repo/user_repo.go @@ -134,7 +134,7 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us if len(uniqueUserIDs) > 0 { if err = e.In("id", uniqueUserIDs.Values()). Where(builder.Eq{"`user`.is_active": true}). - OrderBy(user_model.GetOrderByName()). + OrderBy(user_model.GetOrderByName(ctx)). Find(&users); err != nil { return nil, err } diff --git a/models/secret/secret.go b/models/secret/secret.go index ce0ad65a799e4..eab9cf0712d83 100644 --- a/models/secret/secret.go +++ b/models/secret/secret.go @@ -165,3 +165,17 @@ func GetSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[ return secrets, nil } + +func CountWrongRepoLevelSecrets(ctx context.Context) (int64, error) { + var result int64 + _, err := db.GetEngine(ctx).SQL("SELECT count(`id`) FROM `secret` WHERE `repo_id` > 0 AND `owner_id` > 0").Get(&result) + return result, err +} + +func UpdateWrongRepoLevelSecrets(ctx context.Context) (int64, error) { + result, err := db.GetEngine(ctx).Exec("UPDATE `secret` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0") + if err != nil { + return 0, err + } + return result.RowsAffected() +} diff --git a/models/user/must_change_password.go b/models/user/must_change_password.go index 7eab08de8923c..686847c7d7cf6 100644 --- a/models/user/must_change_password.go +++ b/models/user/must_change_password.go @@ -34,7 +34,7 @@ func SetMustChangePassword(ctx context.Context, all, mustChangePassword bool, in if !all { include = sliceTrimSpaceDropEmpty(include) if len(include) == 0 { - return 0, util.NewSilentWrapErrorf(util.ErrInvalidArgument, "no users to include provided") + return 0, util.ErrorWrap(util.ErrInvalidArgument, "no users to include provided") } cond = cond.And(builder.In("lower_name", include)) diff --git a/models/user/user.go b/models/user/user.go index 3c72aa7cc4abb..e32632ef50ca2 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -440,8 +440,8 @@ func (u *User) EmailTo() string { // GetDisplayName returns full name if it's not empty and DEFAULT_SHOW_FULL_NAME is set, // returns username otherwise. -func (u *User) GetDisplayName() string { - if setting.UI.DefaultShowFullName { +func (u *User) GetDisplayName(ctx context.Context) string { + if setting.Config().UI.DefaultShowFullName.Value(ctx) { trimmed := strings.TrimSpace(u.FullName) if len(trimmed) > 0 { return trimmed @@ -482,8 +482,8 @@ func (u *User) GitName() string { } // ShortName ellipses username to length -func (u *User) ShortName(length int) string { - if setting.UI.DefaultShowFullName && len(u.FullName) > 0 { +func (u *User) ShortName(ctx context.Context, length int) string { + if setting.Config().UI.DefaultShowFullName.Value(ctx) && len(u.FullName) > 0 { return util.EllipsisDisplayString(u.FullName, length) } return util.EllipsisDisplayString(u.Name, length) @@ -1393,8 +1393,8 @@ func FixWrongUserType(ctx context.Context) (int64, error) { return db.GetEngine(ctx).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&User{Type: 1}) } -func GetOrderByName() string { - if setting.UI.DefaultShowFullName { +func GetOrderByName(ctx context.Context) string { + if setting.Config().UI.DefaultShowFullName.Value(ctx) { return "full_name, name" } return "name" diff --git a/models/user/user_list.go b/models/user/user_list.go index c66d59f0d9245..4241905058401 100644 --- a/models/user/user_list.go +++ b/models/user/user_list.go @@ -11,6 +11,10 @@ import ( func GetUsersMapByIDs(ctx context.Context, userIDs []int64) (map[int64]*User, error) { userMaps := make(map[int64]*User, len(userIDs)) + if len(userIDs) == 0 { + return userMaps, nil + } + left := len(userIDs) for left > 0 { limit := db.DefaultMaxInSize diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go index f2a26efbb949f..6ff77a380dd8d 100644 --- a/models/webhook/webhook_test.go +++ b/models/webhook/webhook_test.go @@ -73,7 +73,7 @@ func TestWebhook_EventsArray(t *testing.T) { "pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone", "pull_request_comment", "pull_request_review_approved", "pull_request_review_rejected", "pull_request_review_comment", "pull_request_sync", "pull_request_review_request", "wiki", "repository", "release", - "package", "status", + "package", "status", "workflow_job", }, (&Webhook{ HookEvent: &webhook_module.HookEvent{SendEverything: true}, diff --git a/modules/base/tool.go b/modules/base/tool.go index b6ed8cbf9a5a7..02ca85569e1da 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -17,7 +17,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -139,24 +138,3 @@ func Int64sToStrings(ints []int64) []string { } return strs } - -// EntryIcon returns the octicon name for displaying files/directories -func EntryIcon(entry *git.TreeEntry) string { - switch { - case entry.IsLink(): - te, err := entry.FollowLink() - if err != nil { - return "file-symlink-file" - } - if te.IsDir() { - return "file-directory-symlink" - } - return "file-symlink-file" - case entry.IsDir(): - return "file-directory-fill" - case entry.IsSubModule(): - return "file-submodule" - } - - return "file" -} diff --git a/modules/fileicon/basic.go b/modules/fileicon/basic.go new file mode 100644 index 0000000000000..040a8e87de063 --- /dev/null +++ b/modules/fileicon/basic.go @@ -0,0 +1,27 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package fileicon + +import ( + "html/template" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/svg" +) + +func BasicThemeIcon(entry *git.TreeEntry) template.HTML { + svgName := "octicon-file" + switch { + case entry.IsLink(): + svgName = "octicon-file-symlink-file" + if te, err := entry.FollowLink(); err == nil && te.IsDir() { + svgName = "octicon-file-directory-symlink" + } + case entry.IsDir(): + svgName = "octicon-file-directory-fill" + case entry.IsSubModule(): + svgName = "octicon-file-submodule" + } + return svg.RenderHTML(svgName) +} diff --git a/modules/fileicon/material.go b/modules/fileicon/material.go new file mode 100644 index 0000000000000..adea625c06a8c --- /dev/null +++ b/modules/fileicon/material.go @@ -0,0 +1,157 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package fileicon + +import ( + "html/template" + "path" + "strings" + "sync" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/options" + "code.gitea.io/gitea/modules/reqctx" + "code.gitea.io/gitea/modules/svg" +) + +type materialIconRulesData struct { + FileNames map[string]string `json:"fileNames"` + FolderNames map[string]string `json:"folderNames"` + FileExtensions map[string]string `json:"fileExtensions"` + LanguageIDs map[string]string `json:"languageIds"` +} + +type MaterialIconProvider struct { + once sync.Once + rules *materialIconRulesData + svgs map[string]string +} + +var materialIconProvider MaterialIconProvider + +func DefaultMaterialIconProvider() *MaterialIconProvider { + materialIconProvider.once.Do(materialIconProvider.loadData) + return &materialIconProvider +} + +func (m *MaterialIconProvider) loadData() { + buf, err := options.AssetFS().ReadFile("fileicon/material-icon-rules.json") + if err != nil { + log.Error("Failed to read material icon rules: %v", err) + return + } + err = json.Unmarshal(buf, &m.rules) + if err != nil { + log.Error("Failed to unmarshal material icon rules: %v", err) + return + } + + buf, err = options.AssetFS().ReadFile("fileicon/material-icon-svgs.json") + if err != nil { + log.Error("Failed to read material icon rules: %v", err) + return + } + err = json.Unmarshal(buf, &m.svgs) + if err != nil { + log.Error("Failed to unmarshal material icon rules: %v", err) + return + } + log.Debug("Loaded material icon rules and SVG images") +} + +func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name, svg string) template.HTML { + data := ctx.GetData() + renderedSVGs, _ := data["_RenderedSVGs"].(map[string]bool) + if renderedSVGs == nil { + renderedSVGs = make(map[string]bool) + data["_RenderedSVGs"] = renderedSVGs + } + // This part is a bit hacky, but it works really well. It should be safe to do so because all SVG icons are generated by us. + // Will try to refactor this in the future. + if !strings.HasPrefix(svg, "