diff --git a/Makefile b/Makefile index 722db6bbc6..b8cea6b891 100644 --- a/Makefile +++ b/Makefile @@ -150,7 +150,7 @@ ESLINT_CONCURRENCY ?= 2 SWAGGER_SPEC := templates/swagger/v1_json.tmpl SWAGGER_SPEC_INPUT := templates/swagger/v1_input.json -SWAGGER_EXCLUDE := code.gitea.io/sdk +SWAGGER_EXCLUDE := gitea.dev/sdk OPENAPI3_SPEC := templates/swagger/v1_openapi3_json.tmpl TEST_MYSQL_HOST ?= mysql:3306 diff --git a/assets/go-licenses.json b/assets/go-licenses.json index 8240ce176b..b2912a3ab3 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -4,16 +4,6 @@ "path": "cloud.google.com/go/compute/metadata/LICENSE", "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" }, - { - "name": "code.gitea.io/actions-proto-go", - "path": "code.gitea.io/actions-proto-go/LICENSE", - "licenseText": "MIT License\n\nCopyright (c) 2022 The Gitea Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" - }, - { - "name": "code.gitea.io/sdk/gitea", - "path": "code.gitea.io/sdk/gitea/LICENSE", - "licenseText": "Copyright (c) 2016 The Gitea Authors\nCopyright (c) 2014 The Gogs Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" - }, { "name": "codeberg.org/gusted/mcaptcha", "path": "codeberg.org/gusted/mcaptcha/LICENSE", @@ -74,11 +64,21 @@ "path": "gitea.com/lunny/levelqueue/LICENSE", "licenseText": "Copyright (c) 2019 Lunny Xiao\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" }, + { + "name": "gitea.dev/actions-proto-go", + "path": "gitea.dev/actions-proto-go/LICENSE", + "licenseText": "MIT License\n\nCopyright (c) 2022 The Gitea Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" + }, { "name": "gitea.dev/modules/lfs", "path": "gitea.dev/modules/lfs/LICENSE", "licenseText": "Copyright (c) 2016 The Gitea Authors\nCopyright (c) GitHub, Inc. and LFS Test Server contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, + { + "name": "gitea.dev/sdk", + "path": "gitea.dev/sdk/LICENSE", + "licenseText": "Copyright (c) 2016 The Gitea Authors\nCopyright (c) 2014 The Gogs Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" + }, { "name": "github.com/42wim/httpsig", "path": "github.com/42wim/httpsig/LICENSE", @@ -440,13 +440,8 @@ "licenseText": "ISC License\n\nCopyright (c) 2012-2016 Dave Collins \u003cdave@davec.name\u003e\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n" }, { - "name": "github.com/dimiro1/reply", - "path": "github.com/dimiro1/reply/LICENSE", - "licenseText": "MIT License\n\nCopyright (c) Discourse\nCopyright (c) Claudemiro\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" - }, - { - "name": "github.com/dlclark/regexp2", - "path": "github.com/dlclark/regexp2/LICENSE", + "name": "github.com/dlclark/regexp2/v2", + "path": "github.com/dlclark/regexp2/v2/LICENSE", "licenseText": "The MIT License (MIT)\n\nCopyright (c) Doug Clark\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, { diff --git a/go.mod b/go.mod index 93c6c78164..e13a10c62f 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,6 @@ module gitea.dev go 1.26.3 require ( - code.gitea.io/actions-proto-go v0.4.1 - code.gitea.io/sdk/gitea v0.25.1 codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 connectrpc.com/connect v1.20.0 gitea.com/gitea/runner v1.0.5 @@ -14,6 +12,8 @@ require ( gitea.com/go-chi/session v0.0.0-20251124165456-68e0254e989e gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 + gitea.dev/actions-proto-go v0.5.0 + gitea.dev/sdk v1.0.1 github.com/42wim/httpsig v1.2.4 github.com/42wim/sshsig v0.0.0-20260317195500-b9f38cf0d432 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 @@ -23,7 +23,7 @@ require ( github.com/ProtonMail/go-crypto v1.4.1 github.com/PuerkitoBio/goquery v1.12.0 github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.8.3 - github.com/alecthomas/chroma/v2 v2.24.1 + github.com/alecthomas/chroma/v2 v2.25.0 github.com/aws/aws-sdk-go-v2/credentials v1.19.16 github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.14 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb @@ -33,8 +33,7 @@ require ( github.com/caddyserver/certmagic v0.25.3 github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20260309112543-12416315a635 github.com/chi-middleware/proxy v1.1.1 - github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 - github.com/dlclark/regexp2 v1.12.0 + github.com/dlclark/regexp2/v2 v2.1.0 github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 github.com/dustin/go-humanize v1.0.1 github.com/editorconfig/editorconfig-core-go/v2 v2.6.4 @@ -178,6 +177,7 @@ require ( github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidmz/go-pageant v1.0.2 // indirect + github.com/dlclark/regexp2 v1.12.0 // indirect github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect github.com/fatih/color v1.19.0 // indirect github.com/fxamacker/cbor/v2 v2.9.2 // indirect diff --git a/go.sum b/go.sum index 0db0bcd66c..c611f238ab 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -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/sdk/gitea v0.25.1 h1:yywxWwoV+SdjHtbC6unBiXojWdZOtoHuGhEazEXeWuE= -code.gitea.io/sdk/gitea v0.25.1/go.mod h1:uDFWYBU8dgZsgOHwe6C/6olxvf8FHguNB3wW1i83fgg= code.pfad.fr/check v1.1.0 h1:GWvjdzhSEgHvEHe2uJujDcpmZoySKuHQNrZMfzfO0bE= code.pfad.fr/check v1.1.0/go.mod h1:NiUH13DtYsb7xp5wll0U4SXx7KhXQVCtRgdC96IPfoM= codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY= @@ -30,6 +26,10 @@ gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 h1:IFT+hup2xejHq gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= +gitea.dev/actions-proto-go v0.5.0 h1:Fc3DI4Fm3B3JBRXFUjegql+usoNAjjAw1cxMansfA2I= +gitea.dev/actions-proto-go v0.5.0/go.mod h1:p4RX+D9oqiEEzzkPMXscw2CmaGuYFPWFc6xIOmDNDqs= +gitea.dev/sdk v1.0.1 h1:CWXQUQvp2I6YKOWkhYo1Flx2sRNfMK1X9Op4oR2awXs= +gitea.dev/sdk v1.0.1/go.mod h1:jCf5Uzz0Jkb61jxNgMxLOCWwle1J1B2nKdcRtxuK9rY= github.com/42wim/httpsig v1.2.4 h1:mI5bH0nm4xn7K18fo1K3okNDRq8CCJ0KbBYWyA6r8lU= github.com/42wim/httpsig v1.2.4/go.mod h1:yKsYfSyTBEohkPik224QPFylmzEBtda/kjyIAJjh3ps= github.com/42wim/sshsig v0.0.0-20260317195500-b9f38cf0d432 h1:3Fcz1QzlS7Jv4FT2KI3cHNSZL+KPN3dXxurn9f3YL/Y= @@ -76,8 +76,8 @@ github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.8.3/go.mod h1:bnXbvnI9Mfqd github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= -github.com/alecthomas/chroma/v2 v2.24.1 h1:m5ffpfZbIb++k8AqFEKy9uVgY12xIQtBsQlc6DfZJQM= -github.com/alecthomas/chroma/v2 v2.24.1/go.mod h1:l+ohZ9xRXIbGe7cIW+YZgOGbvuVLjMps/FYN/CwuabI= +github.com/alecthomas/chroma/v2 v2.25.0 h1:DWkVlxrNpxPf+Qcfe04LBqUArxUiybK8ZQ9T7OFu68E= +github.com/alecthomas/chroma/v2 v2.25.0/go.mod h1:+95AZrRWlpW9g6qXD7S7UdHviopsGP/kCIrtJcU3QoQ= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= @@ -236,13 +236,12 @@ github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454Wv github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 h1:PdsjTl0Cg+ZJgOx/CFV5NNgO1ThTreqdgKYiDCMHJwA= -github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21/go.mod h1:xJvkyD6Y2rZapGvPJLYo9dyx1s5dxBEDPa8T3YTuOk0= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8= github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dlclark/regexp2/v2 v2.1.0 h1:jHXRmHRZGbuQzDZjMlCAXOvQb75iv3HyLDzXGj5H1AY= +github.com/dlclark/regexp2/v2 v2.1.0/go.mod h1:Bz5TMy5d8fPK0ximH0Yi9KvsRHNnvXqUx9XG6a4wB+I= github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4= github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= diff --git a/models/actions/runner.go b/models/actions/runner.go index 8e9400bd3f..ba2b38ee7e 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -10,6 +10,7 @@ import ( "strings" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" "gitea.dev/models/db" repo_model "gitea.dev/models/repo" "gitea.dev/models/shared/types" @@ -21,7 +22,6 @@ import ( "gitea.dev/modules/translation" "gitea.dev/modules/util" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "xorm.io/builder" ) diff --git a/models/actions/status.go b/models/actions/status.go index c9b595d983..22ea0d1555 100644 --- a/models/actions/status.go +++ b/models/actions/status.go @@ -6,9 +6,8 @@ package actions import ( "slices" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" "gitea.dev/modules/translation" - - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" ) // Status represents the status of ActionRun, ActionRunJob, ActionTask, or ActionTaskStep diff --git a/models/actions/status_test.go b/models/actions/status_test.go index 2363101c5d..f1551b2892 100644 --- a/models/actions/status_test.go +++ b/models/actions/status_test.go @@ -6,7 +6,8 @@ package actions import ( "testing" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" + "github.com/stretchr/testify/assert" ) diff --git a/models/actions/task.go b/models/actions/task.go index 0a31a33b15..0332902ccc 100644 --- a/models/actions/task.go +++ b/models/actions/task.go @@ -11,6 +11,7 @@ import ( "strings" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" auth_model "gitea.dev/models/auth" "gitea.dev/models/db" "gitea.dev/models/unit" @@ -20,7 +21,6 @@ import ( "gitea.dev/modules/timeutil" "gitea.dev/modules/util" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" lru "github.com/hashicorp/golang-lru/v2" "google.golang.org/protobuf/types/known/timestamppb" "xorm.io/builder" diff --git a/models/actions/task_test.go b/models/actions/task_test.go index 8d6df629b8..fe4436ec63 100644 --- a/models/actions/task_test.go +++ b/models/actions/task_test.go @@ -7,12 +7,12 @@ import ( "strings" "testing" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" "gitea.dev/models/db" "gitea.dev/models/unittest" "gitea.dev/modules/actions/jobparser" "gitea.dev/modules/timeutil" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/timestamppb" diff --git a/models/issues/pull.go b/models/issues/pull.go index c0e8b983cf..7dbcef0d3f 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -23,7 +23,7 @@ import ( "gitea.dev/modules/timeutil" "gitea.dev/modules/util" - "github.com/dlclark/regexp2" + "github.com/dlclark/regexp2/v2" "xorm.io/builder" ) diff --git a/modules/actions/log.go b/modules/actions/log.go index 269e0c1808..3fbdf4cdeb 100644 --- a/modules/actions/log.go +++ b/modules/actions/log.go @@ -12,12 +12,12 @@ import ( "strings" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" "gitea.dev/models/dbfs" "gitea.dev/modules/log" "gitea.dev/modules/storage" "gitea.dev/modules/zstd" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/options/locale/locale_fr-FR.json b/options/locale/locale_fr-FR.json index f07668d90d..5cfa7498b9 100644 --- a/options/locale/locale_fr-FR.json +++ b/options/locale/locale_fr-FR.json @@ -105,6 +105,7 @@ "copy_error": "Échec de la copie", "copy_type_unsupported": "Ce type de fichier ne peut pas être copié", "copy_filename": "Copier le nom du fichier", + "copy_output": "Copier la sortie", "write": "Écrire", "preview": "Aperçu", "loading": "Chargement…", @@ -3439,7 +3440,7 @@ "action.transfer_repo": "a transféré le dépôt %s vers %s", "action.push_tag": "a poussé l’étiquette %[3]s de %[4]s", "action.delete_tag": "a supprimé l’étiquette %[2]s de %[3]s", - "action.delete_branch": "a supprimée la branche %[2]s de %[3]s", + "action.delete_branch": "a supprimé la branche %[2]s de %[3]s", "action.compare_branch": "Comparer", "action.compare_commits": "Comparer %d révisions", "action.compare_commits_general": "Comparer les révisions", @@ -3758,6 +3759,8 @@ "actions.runners.reset_registration_token_confirm": "Voulez-vous révoquer le jeton actuel et en générer un nouveau ?", "actions.runners.reset_registration_token_success": "Le jeton d’inscription de l’exécuteur a été réinitialisé avec succès", "actions.runs.all_workflows": "Tous les flux de travail", + "actions.runs.other_workflows": "Autres flux de travail", + "actions.runs.other_workflows_tooltip": "Les flux de travail qui ont été exécutés dans ce dépôt mais qui n’existent pas dans la branche par défaut.", "actions.runs.workflow_run_count_1": "%d exécution du workflow", "actions.runs.workflow_run_count_n": "%d exécutions du workflow", "actions.runs.commit": "Révision", @@ -3773,6 +3776,8 @@ "actions.runs.status": "Statut", "actions.runs.actors_no_select": "Tous les acteurs", "actions.runs.status_no_select": "Touts les statuts", + "actions.runs.branch": "Branche", + "actions.runs.branches_no_select": "Toutes les branches", "actions.runs.no_results": "Aucun résultat correspondant.", "actions.runs.no_workflows": "Il n'y a pas encore de workflows.", "actions.runs.no_workflows.quick_start": "Vous découvrez les Actions Gitea ? Consultez le didacticiel.", diff --git a/options/locale/locale_zh-CN.json b/options/locale/locale_zh-CN.json index 6b9ba53878..ba52e2e79d 100644 --- a/options/locale/locale_zh-CN.json +++ b/options/locale/locale_zh-CN.json @@ -105,6 +105,7 @@ "copy_error": "复制失败", "copy_type_unsupported": "无法复制此类型的文件内容", "copy_filename": "复制文件名", + "copy_output": "复制输出", "write": "撰写", "preview": "预览", "loading": "正在加载…", @@ -1321,7 +1322,7 @@ "repo.commits.desc": "浏览代码修改历史", "repo.commits.commits": "次代码提交", "repo.commits.no_commits": "没有共同的提交。「%s」和「%s」的历史完全不同。", - "repo.commits.nothing_to_compare": "这些分支是相同的。", + "repo.commits.nothing_to_compare": "没有差异可显示。", "repo.commits.search.tooltip": "您可以在关键词前加上前缀,如「author:」、「committer:」、「after:」或「before:」,例如「retrin author:Alice before:2019-01-13」。", "repo.commits.search_branch": "此分支", "repo.commits.search_all": "所有分支", @@ -1783,9 +1784,9 @@ "repo.pulls.select_commit_hold_shift_for_range": "选择提交。按住 Shift + 单击选择一个范围", "repo.pulls.review_only_possible_for_full_diff": "只有在查看全部差异时才能进行审核", "repo.pulls.filter_changes_by_commit": "按提交筛选", - "repo.pulls.nothing_to_compare": "分支内容相同,无需创建合并请求。", + "repo.pulls.nothing_to_compare": "没有差异可显示。无需创建合并请求。", "repo.pulls.no_common_history": "这些分支没有共同的合并基点。请选择不同的基点或比较分支。", - "repo.pulls.nothing_to_compare_have_tag": "所选分支 / Git 标签相同。", + "repo.pulls.nothing_to_compare_have_tag": "所选分支或 Git 标签之间没有差异可显示。", "repo.pulls.nothing_to_compare_and_allow_empty_pr": "这些分支是相等的,此合并请求将为空。", "repo.pulls.has_pull_request": "这些分支之间的合并请求已存在:%[2]s#%[3]d", "repo.pulls.create": "创建合并请求", @@ -1819,6 +1820,7 @@ "repo.pulls.required_status_check_failed": "一些必要的检查没有成功", "repo.pulls.required_status_check_missing": "缺少一些必要的检查。", "repo.pulls.required_status_check_administrator": "作为管理员,您仍可合并此合并请求", + "repo.pulls.required_status_check_bypass_allowlist": "您可以在此次合并中绕过分支保护规则。", "repo.pulls.blocked_by_approvals": "此合并请求还没有足够的批准。已获批准数 %d 个,需获批准数 %d 个。", "repo.pulls.blocked_by_approvals_whitelisted": "此合并请求尚未获得足够的批准。已获得 %d/%d 个来自允许列表中用户或团队的批准。", "repo.pulls.blocked_by_rejection": "此合并请求有官方审核员请求的更改。", @@ -2138,7 +2140,9 @@ "repo.settings.pulls_desc": "启用合并请求", "repo.settings.pulls.ignore_whitespace": "忽略空白冲突", "repo.settings.pulls.enable_autodetect_manual_merge": "启用自动检查手动合并(注意:在某些特殊情况下可能会出现误判)", + "repo.settings.pulls.allow_merge_update": "允许通过合并更新合并请求分支", "repo.settings.pulls.allow_rebase_update": "允许通过变基更新合并请求分支", + "repo.settings.pulls.default_update_style": "默认分支更新风格", "repo.settings.pulls.default_target_branch": "新合并请求的默认目标分支", "repo.settings.pulls.default_target_branch_default": "默认分支(%s)", "repo.settings.pulls.default_delete_branch_after_merge": "默认合并后删除合并请求分支", @@ -2413,6 +2417,11 @@ "repo.settings.protect_merge_whitelist_committers_desc": "仅允许白名单用户或团队合并合并请求到此分支。", "repo.settings.protect_merge_whitelist_users": "合并白名单用户:", "repo.settings.protect_merge_whitelist_teams": "合并白名单团队:", + "repo.settings.protect_bypass_allowlist": "绕过分支保护", + "repo.settings.protect_enable_bypass_allowlist": "允许指定用户或团队绕过分支保护", + "repo.settings.protect_enable_bypass_allowlist_desc": "列入白名单的用户或团队可以执行合并或推送操作,即使在通常情况下,这些操作会被所需的审批、状态检查或受保护文件规则所阻挡。", + "repo.settings.protect_bypass_allowlist_users": "允许绕过保护的用户:", + "repo.settings.protect_bypass_allowlist_teams": "允许绕过保护的团队:", "repo.settings.protect_check_status_contexts": "启用状态检查", "repo.settings.protect_status_check_patterns": "状态检查表达式:", "repo.settings.protect_status_check_patterns_desc": "输入表达式以指定在分支合并到匹配此规则的分支之前必须通过哪些状态检查。每一行指定一个表达式且表达式不能为空。", @@ -2454,7 +2463,7 @@ "repo.settings.block_outdated_branch": "如果合并请求已经过时,阻止合并", "repo.settings.block_outdated_branch_desc": "当头部分支落后基础分支时,不能合并。", "repo.settings.block_admin_merge_override": "管理员须遵守分支保护规则", - "repo.settings.block_admin_merge_override_desc": "管理员须遵守分支保护规则,不能规避该规则。", + "repo.settings.block_admin_merge_override_desc": "管理员必须遵守分支保护规则,且不得绕过这些规则。如果启用了绕过白名单功能,位于绕过白名单中的用户或团队仍可绕过这些规则。", "repo.settings.default_branch_desc": "选择一个默认分支用于提交代码。", "repo.settings.default_target_branch_desc": "如果在仓库高级设置的合并请求部分中进行了设置,则合并请求可以使用不同的默认目标分支。", "repo.settings.merge_style_desc": "合并方式", @@ -3483,7 +3492,7 @@ "gpg.default_key": "使用默认密钥签名", "gpg.error.extract_sign": "无法提取签名", "gpg.error.generate_hash": "无法生成提交的哈希", - "gpg.error.no_committer_account": "没有帐户链接到提交者的邮箱", + "gpg.error.no_committer_account": "没有帐户关联到提交者的邮箱", "gpg.error.no_gpg_keys_found": "找不到此签名对应的密钥", "gpg.error.not_signed_commit": "未签名的提交", "gpg.error.failed_retrieval_gpg_keys": "找不到任何与该提交者账号相关的密钥", @@ -3622,7 +3631,13 @@ "packages.terraform.delete.latest": "无法删除最新版本的 Terraform 状态。", "packages.vagrant.install": "若要添加一个 Vagrant box,请运行以下命令:", "packages.settings.link": "将此软件包链接到仓库", - "packages.settings.link.description": "如果您将一个软件包与一个仓库链接起来,软件包将显示在仓库的软件包列表中。", + "packages.settings.link.description": "如果您将软件包与仓库关联,该软件包将显示在仓库的软件包列表中。", + "packages.settings.link.notice1": "仅同一所有者名下的仓库可以进行关联。", + "packages.settings.link.notice2": "关联仓库不会更改软件包的可见性。", + "packages.settings.link.notice3": "留空该字段将删除关联。", + "packages.settings.visibility": "软件包可见性", + "packages.settings.visibility.inherit": "软件包的可见性继承自其所有者,无法在此处单独更改。若要更改,请更新拥有此软件包的用户或组织的可见性设置。", + "packages.settings.visibility.button": "更改所有者可见性", "packages.settings.link.select": "选择仓库", "packages.settings.link.button": "更新仓库链接", "packages.settings.link.success": "仓库链接已成功更新。", @@ -3696,6 +3711,7 @@ "actions.status.success": "成功", "actions.status.failure": "失败", "actions.status.cancelled": "已取消", + "actions.status.cancelling": "取消中", "actions.status.skipped": "已忽略", "actions.status.blocked": "阻塞中", "actions.runners": "运行器", @@ -3743,6 +3759,8 @@ "actions.runners.reset_registration_token_confirm": "是否吊销当前令牌并生成一个新令牌?", "actions.runners.reset_registration_token_success": "成功重置运行器注册令牌", "actions.runs.all_workflows": "所有工作流", + "actions.runs.other_workflows": "其他工作流", + "actions.runs.other_workflows_tooltip": "在此仓库中已执行,但不存在于默认分支上的工作流。", "actions.runs.workflow_run_count_1": "%d 次工作流运行", "actions.runs.workflow_run_count_n": "%d 次工作流运行", "actions.runs.commit": "提交", @@ -3758,6 +3776,8 @@ "actions.runs.status": "状态", "actions.runs.actors_no_select": "所有操作者", "actions.runs.status_no_select": "所有状态", + "actions.runs.branch": "分支", + "actions.runs.branches_no_select": "所有分支", "actions.runs.no_results": "没有匹配的结果。", "actions.runs.no_workflows": "目前还没有工作流。", "actions.runs.no_workflows.quick_start": "不知道如何使用 Gitea 工作流吗?请查看快速开始指南。", diff --git a/renovate.json5 b/renovate.json5 index bf913011fb..7584f56594 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -43,10 +43,6 @@ "matchPackageNames": ["github.com/urfave/cli/v3"], "allowedVersions": "<3.6.2", // v3.6.2 breaks -c flag parsing in help commands }, - { - "matchPackageNames": ["github.com/dlclark/regexp2"], - "allowedVersions": "^1", // v2 fails to build on linux/386: https://github.com/dlclark/regexp2/issues/102 - }, { "matchPackageNames": ["github.com/Azure/azure-sdk-for-go/sdk/azcore"], "allowedVersions": "<1.21.0", // v1.21.0+ uses API version unsupported by Azurite in CI diff --git a/routers/api/actions/ping/ping.go b/routers/api/actions/ping/ping.go index e3ea3e9754..85924f179c 100644 --- a/routers/api/actions/ping/ping.go +++ b/routers/api/actions/ping/ping.go @@ -8,10 +8,10 @@ import ( "fmt" "net/http" + pingv1 "gitea.dev/actions-proto-go/ping/v1" + "gitea.dev/actions-proto-go/ping/v1/pingv1connect" "gitea.dev/modules/log" - pingv1 "code.gitea.io/actions-proto-go/ping/v1" - "code.gitea.io/actions-proto-go/ping/v1/pingv1connect" "connectrpc.com/connect" ) diff --git a/routers/api/actions/ping/ping_test.go b/routers/api/actions/ping/ping_test.go index 98d2dcb820..3b3aec06d8 100644 --- a/routers/api/actions/ping/ping_test.go +++ b/routers/api/actions/ping/ping_test.go @@ -8,8 +8,9 @@ import ( "net/http/httptest" "testing" - pingv1 "code.gitea.io/actions-proto-go/ping/v1" - "code.gitea.io/actions-proto-go/ping/v1/pingv1connect" + pingv1 "gitea.dev/actions-proto-go/ping/v1" + "gitea.dev/actions-proto-go/ping/v1/pingv1connect" + "connectrpc.com/connect" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go index 1a66930c9e..e98aef9515 100644 --- a/routers/api/actions/runner/runner.go +++ b/routers/api/actions/runner/runner.go @@ -9,6 +9,8 @@ import ( "net/http" "slices" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" + "gitea.dev/actions-proto-go/runner/v1/runnerv1connect" actions_model "gitea.dev/models/actions" repo_model "gitea.dev/models/repo" user_model "gitea.dev/models/user" @@ -17,8 +19,6 @@ import ( "gitea.dev/modules/util" actions_service "gitea.dev/services/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "code.gitea.io/actions-proto-go/runner/v1/runnerv1connect" "connectrpc.com/connect" gouuid "github.com/google/uuid" "google.golang.org/grpc/codes" @@ -310,6 +310,15 @@ func (s *Service) UpdateLog( rows = req.Msg.Rows[ack-req.Msg.Index:] } + // Ack a re-sent finalize idempotently. Appending new rows past the seal errors. + if task.LogInStorage { + if len(rows) > 0 { + return nil, status.Errorf(codes.AlreadyExists, "log file has been archived") + } + res.Msg.AckIndex = ack + return res, nil + } + // Bail unless we have new rows or a NoMore to finalize. Even with // NoMore, bail when the runner has outrun the server — archiving a // log with a gap is worse than asking it to retry. @@ -318,10 +327,6 @@ func (s *Service) UpdateLog( return res, nil } - if task.LogInStorage { - return nil, status.Errorf(codes.AlreadyExists, "log file has been archived") - } - // WriteLogs is called even with no rows: with offset==0 it bootstraps // an empty DBFS file so TransferLogs below has something to read when // the runner finalizes a task that produced no log output. diff --git a/routers/api/actions/runner/runner_test.go b/routers/api/actions/runner/runner_test.go index 1a4bce945f..b2ed929087 100644 --- a/routers/api/actions/runner/runner_test.go +++ b/routers/api/actions/runner/runner_test.go @@ -6,9 +6,9 @@ package runner import ( "testing" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" ) diff --git a/services/actions/task.go b/services/actions/task.go index 5581bfd634..ff54281cba 100644 --- a/services/actions/task.go +++ b/services/actions/task.go @@ -8,11 +8,11 @@ import ( "errors" "fmt" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" "gitea.dev/models/db" secret_model "gitea.dev/models/secret" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "google.golang.org/protobuf/types/known/structpb" ) diff --git a/services/convert/convert.go b/services/convert/convert.go index 6837d8a76d..bf029356e2 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -13,6 +13,7 @@ import ( "strconv" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" asymkey_model "gitea.dev/models/asymkey" "gitea.dev/models/auth" @@ -36,7 +37,6 @@ import ( asymkey_service "gitea.dev/services/asymkey" "gitea.dev/services/gitdiff" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "gitea.com/gitea/runner/act/model" ) diff --git a/services/mailer/incoming/incoming.go b/services/mailer/incoming/incoming.go index f690f967b2..eab7ad6c91 100644 --- a/services/mailer/incoming/incoming.go +++ b/services/mailer/incoming/incoming.go @@ -17,7 +17,6 @@ import ( "gitea.dev/modules/setting" "gitea.dev/services/mailer/token" - "github.com/dimiro1/reply" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" "github.com/jhillyerd/enmime/v2" @@ -356,7 +355,7 @@ func getContentFromMailReader(env *enmime.Envelope) *MailContent { } return &MailContent{ - Content: reply.FromText(env.Text), + Content: extractReply(env.Text), Attachments: attachments, } } diff --git a/services/mailer/incoming/incoming_test.go b/services/mailer/incoming/incoming_test.go index bc1decd54a..9588c9021a 100644 --- a/services/mailer/incoming/incoming_test.go +++ b/services/mailer/incoming/incoming_test.go @@ -150,3 +150,56 @@ func TestGetContentFromMailReader(t *testing.T) { assert.Equal(t, "mail content without signature", content.Content) assert.Empty(t, content.Attachments) } + +func TestExtractReply(t *testing.T) { + cases := []struct { + name string + input string + expected string + }{ + {"plain text", "Email with only text.", "Email with only text."}, + {"crlf normalized", "line one\r\nline two\r\n", "line one\nline two"}, + {"trim blank lines", "\n\n\nactual reply\n\n\n", "actual reply"}, + {"signature delimiter", "the reply\n--\nJohn Doe\nAcme", "the reply"}, + {"rfc signature delimiter", "the reply\n-- \nJohn Doe", "the reply"}, + {"mobile signature", "My answer is yes.\n\nSent from my iPhone", "My answer is yes."}, + {"quote only kept", "> Email with only quote.", "> Email with only quote."}, + {"leading quote kept", "> This is a quote.\n\nAnd this is some text.", "> This is a quote.\n\nAnd this is some text."}, + {"trailing quote stripped", "My reply.\n\n> original line 1\n> original line 2", "My reply."}, + {"attribution and quote", "Looks good.\n\nOn Mon, Jan 1, 2024 John wrote:\n> please review", "Looks good."}, + {"attribution without quote marks", "My reply.\n\nOn Wed, Sep 25, 2013, richard wrote:\noriginal text", "My reply."}, + {"original message separator", "Foo\n\n-------- Original Message --------\n\nTHE END.", "Foo"}, + {"outlook header block", "This is the actual reply.\n\nFrom: Some One \nSent: Monday\nTo: Someone\nSubject: hi\n\nquoted body", "This is the actual reply."}, + {"french attribution", "C'est super !\n\nLe 4 janv. 2016 19:03, \"Neil\" a écrit :\n> quoted", "C'est super !"}, + {"german attribution", "Hey :)\n\nAm 03.02.2016 3:35 schrieb Max :\n> quoted", "Hey :)"}, + {"cyrillic wrote verb", "Yes.\n\n6 октября 2014 lidel написал:\n> quoted", "Yes."}, + {"localized signature", "My answer.\n\nEnvoyé depuis mon iPhone", "My answer."}, + {"swedish header block", "Hi everyone!\n\nFrån: Foo \nSkickat: den 5 juni\nTill: x@y.com\nÄmne: hi\n\nbody", "Hi everyone!"}, + {"attribution only is empty", "On Mon, Jan 1, 2024 at 10:00 John wrote:\n> please review", ""}, + {"prose ending in wrote kept", "Hi Bob,\nThanks for the report you wrote\nI'll fix it.", "Hi Bob,\nThanks for the report you wrote\nI'll fix it."}, + {"on with year and no time kept", "Hi,\nOn the 2024 roadmap we have three items.\nPlease review.", "Hi,\nOn the 2024 roadmap we have three items.\nPlease review."}, + {"date prose kept", "Notes:\n5 issues 2024 fixed at 9:15 today\nmore notes", "Notes:\n5 issues 2024 fixed at 9:15 today\nmore notes"}, + {"header needs from first", "Quick note:\nTo: which server?\nFrom: tests pass.\nThanks", "Quick note:\nTo: which server?\nFrom: tests pass.\nThanks"}, + {"indented header block", "Reply text.\n\n From: A \n Sent: Monday\n To: x\n Subject: hi\n\nbody", "Reply text."}, + {"chinese signature", "回复内容\n\n發自我的iPhone", "回复内容"}, + {"japanese signature", "返信します\n\niPhoneから送信", "返信します"}, + {"chinese header block", "回复内容\n\n发件人:张三\n收件人:李四\n主题:你好\n\n原文", "回复内容"}, + {"japanese header block", "本文です\n\n差出人:山田\n宛先:田中\n件名:こんにちは\n\n原文", "本文です"}, + {"name-first attribution", "Okay.\n\nErlend schrieb am Di., 16. Aug. 2016\num 12:52 Uhr:\n> quoted", "Okay."}, + {"chinese attribution", "你好,谢谢回复。\n\n在 2024年1月1日,张三 写道:\n> 原始内容", "你好,谢谢回复。"}, + {"japanese attribution", "了解しました。\n\n田中さんは書きました:\n> 引用", "了解しました。"}, + {"korean attribution", "감사합니다.\n\n홍길동님이 작성:\n> 인용", "감사합니다."}, + {"email mention kept", "I asked Bob and he wrote back yes.\nSo we proceed.", "I asked Bob and he wrote back yes.\nSo we proceed."}, + {"trailing mailbox glyph", "My reply here.\n\nᐧ", "My reply here."}, + {"on with year and time prose kept", "On the 2024 roadmap we should meet at 10:00.\nI'll send invites.", "On the 2024 roadmap we should meet at 10:00.\nI'll send invites."}, + {"spanish year and time prose kept", "El informe del 2024 estará listo a las 10:00.\nGracias.", "El informe del 2024 estará listo a las 10:00.\nGracias."}, + {"chinese prose kept", "谢谢,已测试。\n发自我的内心的感谢", "谢谢,已测试。\n发自我的内心的感谢"}, + {"korean prose kept", "확인했습니다.\n이 문서는 회사에서 보냄", "확인했습니다.\n이 문서는 회사에서 보냄"}, + {"japanese prose kept", "了解しました。\n資料は会議から送信", "了解しました。\n資料は会議から送信"}, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + assert.Equal(t, c.expected, extractReply(c.input)) + }) + } +} diff --git a/services/mailer/incoming/reply.go b/services/mailer/incoming/reply.go new file mode 100644 index 0000000000..3f27909ca0 --- /dev/null +++ b/services/mailer/incoming/reply.go @@ -0,0 +1,137 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package incoming + +import ( + "regexp" + "strings" + "sync" + + "gitea.dev/modules/util" +) + +const ( + yearToken = `\b\d{4}\b` // 4-digit year + timeToken = `\b\d{1,2}[:.]\d{2}\b` // HH:MM or HH.MM + // "wrote" verbs ending an attribution line; CJK ones are matched without a + // preceding word-separator since those scripts don't space their words + wroteVerbs = `wrote|writes|schrieb|skrev|napisał|escreveu|escribió|написал|пише|a écrit` + cjkWroteVerbs = `写道|寫道|書きました|작성` + // device names anchoring CJK mobile signatures, so prose isn't mistaken for one + cjkDevice = `iphone|ipad|ipod|android|galaxy|手机|手機|平板` +) + +// forwarded-mail header fields across the common mail clients/locales. headerFromFields +// (the "From"-equivalents) must begin a block; headerFields is the full set allowed to +// follow. Matched as a prefix by headerLine, so adding a locale is a one-line change. +var ( + headerFromFields = []string{ + "from", "fra", "de", "von", "da", "van", "från", "expéditeur", + "发件人", "寄件者", "差出人", "보낸사람", + } + headerFields = append([]string{ + "to", "cc", "bcc", "sent", "date", "subject", "reply-to", + "til", "emne", "an", "betreff", "gesendet", "para", "assunto", "asunto", + "risposta", "inviato", "oggetto", "destinataire", "objet", "répondre à", + "aan", "onderwerp", "beantwoorden", "skickat", "till", "ämne", + "收件人", "主题", "主旨", "主題", "收件者", "抄送", "日期", "宛先", "件名", "받는사람", "제목", + }, headerFromFields...) +) + +// patterns are compiled on first use so the incoming-mail feature adds nothing to startup. +var patterns = sync.OnceValue(func() (ret struct { + signature, attribution, separator *regexp.Regexp +}, +) { + // "-- " delimiter and common mobile footers with frequent localizations. The CJK + // forms require a device name so ordinary prose like "发自我的内心" or "会議から送信" + // is not mistaken for a signature. + ret.signature = regexp.MustCompile(`(?i)^(--|__|—` + + `|sent (from|via|with) .+|get outlook for .+` + + `|envoyé depuis mon .+|sendt fra min .+|von meinem .+|verzonden (met|vanaf) .+` + + `|(發|发)自我的.*(` + cjkDevice + `).*` + + `|.*(` + cjkDevice + `).*(から送信|에서 보냄|傳送|发送))$`) + + // attribution introducing quoted history: a line ending in a "wrote:" verb + // (Latin/Cyrillic or CJK), a "Name wrote" line, a lead word directly + // followed by a day number or weekday plus a year and a time, or an ISO-date-led + // line. The date phrasing, trailing colon and the email before the verb guard + // against prose (so "On the 2024 roadmap … at 10:00" is not an attribution). + ret.attribution = regexp.MustCompile(`(?i)^>*\s*(` + + `.*[\s">'](` + wroteVerbs + `)\s*[::]` + + `|.*(` + cjkWroteVerbs + `)\s*[::]` + + `|.*<\S+@\S+>\s+(` + wroteVerbs + `)\b.*` + + `|(on|at|le|am|el|em|den|il|op|dnia|w dniu)\b[\s,]*(\d|(?:mon|tue|wed|thu|fri|sat|sun)\b).*` + yearToken + `.*` + timeToken + `.*` + + `|\d{4}-\d{2}-\d{2}\b.*` + timeToken + `.*` + + `)$`) + + // a dash/underscore rule line, or text fenced by dashes such as + // "-------- Original Message --------" or "-----Mensaje original-----" + ret.separator = regexp.MustCompile(`(?i)^\s*\*?\s*([-_]{5,}|-{2,}.+-{2,}|original message|forwarded message)\s*\*?\s*$`) + return ret +}) + +// extractReply returns the user-written part of a plain-text email body, dropping +// quoted history, the reply attribution, signatures and forwarded headers. It is a +// slim, dependency-free reimplementation based on github.com/dimiro1/reply (MIT), +// covering the common mail-client formats and languages; bottom posting and +// forwarded bodies are not handled. +func extractReply(text string) string { + p := patterns() + lines := strings.Split(util.NormalizeStringEOL(text), "\n") + + // cut at the first line that begins quoted history, a signature or a header block + for i := range lines { + trimmed := strings.TrimSpace(lines[i]) + if p.signature.MatchString(trimmed) || p.attribution.MatchString(trimmed) || + p.separator.MatchString(trimmed) || headerBlock(trimmed, lines[i+1:]) { + lines = lines[:i] + break + } + } + + // drop the trailing block of quoted/blank lines, unless the whole body is quoted + end := len(lines) + for end > 0 { + // "ᐧ" is the trailing marker some mobile clients (Mailbox) append + if t := strings.TrimSpace(lines[end-1]); t != "" && t != "ᐧ" && !strings.HasPrefix(t, ">") { + break + } + end-- + } + if end > 0 { + lines = lines[:end] + } + + return strings.TrimSpace(strings.Join(lines, "\n")) +} + +// headerBlock reports whether a forwarded-mail header block starts here: the +// (already-trimmed) first line is a "From" field and the next non-blank line is +// another field, so a lone "Subject:" sentence is not a boundary. +func headerBlock(first string, rest []string) bool { + if !headerLine(first, headerFromFields) { + return false + } + for _, next := range rest { + if t := strings.TrimSpace(next); t != "" { + return headerLine(t, headerFields) + } + } + return false +} + +// headerLine reports whether the already-trimmed line is a "Field:" header for one +// of fields. An ASCII colon must be followed by a space so prose like "To:do this" +// is ignored; the CJK fullwidth colon ":" needs no space. +func headerLine(line string, fields []string) bool { + lower := strings.ToLower(line) + for _, field := range fields { + if rest, ok := strings.CutPrefix(lower, field); ok && + (strings.HasPrefix(rest, ": ") || strings.HasPrefix(rest, ":")) { + return true + } + } + return false +} diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go index af454e797f..c754d70090 100644 --- a/services/migrations/gitea_downloader.go +++ b/services/migrations/gitea_downloader.go @@ -16,8 +16,7 @@ import ( "gitea.dev/modules/log" base "gitea.dev/modules/migration" "gitea.dev/modules/structs" - - gitea_sdk "code.gitea.io/sdk/gitea" + gitea_sdk "gitea.dev/sdk" ) var ( @@ -67,6 +66,7 @@ func (f *GiteaDownloaderFactory) GitServiceType() structs.GitServiceType { // GiteaDownloader implements a Downloader interface to get repository information's type GiteaDownloader struct { base.NullDownloader + ctx context.Context client *gitea_sdk.Client baseURL string repoOwner string @@ -84,7 +84,6 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo baseURL, gitea_sdk.SetToken(token), gitea_sdk.SetBasicAuth(username, password), - gitea_sdk.SetContext(ctx), gitea_sdk.SetHTTPClient(NewMigrationHTTPClient()), ) if err != nil { @@ -95,7 +94,7 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo path := strings.Split(repoPath, "/") paginationSupport := true - if err = giteaClient.CheckServerVersionConstraint(">=1.12"); err != nil { + if err = giteaClient.CheckServerVersionConstraint(ctx, ">=1.12"); err != nil { paginationSupport = false } @@ -103,7 +102,7 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo // (default would be 50 but this can differ) maxPerPage := 10 // gitea instances >=1.13 can tell us what maximum they have - apiConf, _, err := giteaClient.GetGlobalAPISettings() + apiConf, _, err := giteaClient.Settings.GetGlobalAPISettings(ctx) if err != nil { log.Info("Unable to get global API settings. Ignoring these.") log.Debug("giteaClient.GetGlobalAPISettings. Error: %v", err) @@ -113,6 +112,7 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo } return &GiteaDownloader{ + ctx: ctx, client: giteaClient, baseURL: baseURL, repoOwner: path[0], @@ -140,7 +140,7 @@ func (g *GiteaDownloader) GetRepoInfo(_ context.Context) (*base.Repository, erro return nil, errors.New("error: GiteaDownloader is nil") } - repo, _, err := g.client.GetRepo(g.repoOwner, g.repoName) + repo, _, err := g.client.Repositories.GetRepo(g.ctx, g.repoOwner, g.repoName) if err != nil { return nil, err } @@ -159,7 +159,7 @@ func (g *GiteaDownloader) GetRepoInfo(_ context.Context) (*base.Repository, erro // GetTopics return gitea topics func (g *GiteaDownloader) GetTopics(_ context.Context) ([]string, error) { - topics, _, err := g.client.ListRepoTopics(g.repoOwner, g.repoName, gitea_sdk.ListRepoTopicsOptions{}) + topics, _, err := g.client.Repositories.ListRepoTopics(g.ctx, g.repoOwner, g.repoName, gitea_sdk.ListRepoTopicsOptions{}) return topics, err } @@ -175,7 +175,7 @@ func (g *GiteaDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone, default: } - ms, _, err := g.client.ListRepoMilestones(g.repoOwner, g.repoName, gitea_sdk.ListMilestoneOption{ + ms, _, err := g.client.Repositories.ListMilestones(g.ctx, g.repoOwner, g.repoName, gitea_sdk.ListMilestoneOption{ ListOptions: gitea_sdk.ListOptions{ PageSize: g.maxPerPage, Page: i, @@ -240,7 +240,7 @@ func (g *GiteaDownloader) GetLabels(ctx context.Context) ([]*base.Label, error) default: } - ls, _, err := g.client.ListRepoLabels(g.repoOwner, g.repoName, gitea_sdk.ListLabelsOptions{ListOptions: gitea_sdk.ListOptions{ + ls, _, err := g.client.Repositories.ListRepoLabels(g.ctx, g.repoOwner, g.repoName, gitea_sdk.ListLabelsOptions{ListOptions: gitea_sdk.ListOptions{ PageSize: g.maxPerPage, Page: i, }}) @@ -288,7 +288,7 @@ func (g *GiteaDownloader) convertGiteaRelease(rel *gitea_sdk.Release) *base.Rele Created: asset.Created, DownloadURL: &asset.DownloadURL, DownloadFunc: func() (io.ReadCloser, error) { - asset, _, err := g.client.GetReleaseAttachment(g.repoOwner, g.repoName, rel.ID, assetID) + asset, _, err := g.client.Releases.GetReleaseAttachment(g.ctx, g.repoOwner, g.repoName, rel.ID, assetID) if err != nil { return nil, err } @@ -328,7 +328,7 @@ func (g *GiteaDownloader) GetReleases(ctx context.Context) ([]*base.Release, err default: } - rl, _, err := g.client.ListReleases(g.repoOwner, g.repoName, gitea_sdk.ListReleasesOptions{ListOptions: gitea_sdk.ListOptions{ + rl, _, err := g.client.Releases.ListReleases(g.ctx, g.repoOwner, g.repoName, gitea_sdk.ListReleasesOptions{ListOptions: gitea_sdk.ListOptions{ PageSize: g.maxPerPage, Page: i, }}) @@ -347,7 +347,7 @@ func (g *GiteaDownloader) GetReleases(ctx context.Context) ([]*base.Release, err } func (g *GiteaDownloader) getIssueReactions(ctx context.Context, index int64) ([]*base.Reaction, error) { - if err := g.client.CheckServerVersionConstraint(">=1.11"); err != nil { + if err := g.client.CheckServerVersionConstraint(g.ctx, ">=1.11"); err != nil { log.Info("GiteaDownloader: instance to old, skip getIssueReactions") return nil, nil } @@ -362,7 +362,7 @@ func (g *GiteaDownloader) getIssueReactions(ctx context.Context, index int64) ([ default: } - reactions, _, err := g.client.ListIssueReactions(g.repoOwner, g.repoName, index, gitea_sdk.ListIssueReactionsOptions{ListOptions: gitea_sdk.ListOptions{ + reactions, _, err := g.client.Issues.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, index, gitea_sdk.ListIssueReactionsOptions{ListOptions: gitea_sdk.ListOptions{ PageSize: g.maxPerPage, Page: i, }}) @@ -387,11 +387,11 @@ func (g *GiteaDownloader) getIssueReactions(ctx context.Context, index int64) ([ func (g *GiteaDownloader) getCommentReactions(commentID int64) ([]*base.Reaction, error) { var reactions []*base.Reaction - if err := g.client.CheckServerVersionConstraint(">=1.11"); err != nil { + if err := g.client.CheckServerVersionConstraint(g.ctx, ">=1.11"); err != nil { log.Info("GiteaDownloader: instance to old, skip getCommentReactions") return reactions, nil } - rl, _, err := g.client.GetIssueCommentReactions(g.repoOwner, g.repoName, commentID) + rl, _, err := g.client.Issues.GetIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, commentID) if err != nil { return nil, err } @@ -413,7 +413,7 @@ func (g *GiteaDownloader) GetIssues(ctx context.Context, page, perPage int) ([]* } allIssues := make([]*base.Issue, 0, perPage) - issues, _, err := g.client.ListRepoIssues(g.repoOwner, g.repoName, gitea_sdk.ListIssueOption{ + issues, _, err := g.client.Issues.ListRepoIssues(g.ctx, g.repoOwner, g.repoName, gitea_sdk.ListIssueOption{ ListOptions: gitea_sdk.ListOptions{Page: page, PageSize: perPage}, State: gitea_sdk.StateAll, Type: gitea_sdk.IssueTypeIssue, @@ -481,7 +481,7 @@ func (g *GiteaDownloader) GetComments(ctx context.Context, commentable base.Comm default: } - comments, _, err := g.client.ListIssueComments(g.repoOwner, g.repoName, commentable.GetForeignIndex(), gitea_sdk.ListIssueCommentOptions{ListOptions: gitea_sdk.ListOptions{ + comments, _, err := g.client.Issues.ListIssueComments(g.ctx, g.repoOwner, g.repoName, commentable.GetForeignIndex(), gitea_sdk.ListIssueCommentOptions{ListOptions: gitea_sdk.ListOptions{ PageSize: g.maxPerPage, Page: i, }}) @@ -522,7 +522,7 @@ func (g *GiteaDownloader) GetPullRequests(ctx context.Context, page, perPage int } allPRs := make([]*base.PullRequest, 0, perPage) - prs, _, err := g.client.ListRepoPullRequests(g.repoOwner, g.repoName, gitea_sdk.ListPullRequestsOptions{ + prs, _, err := g.client.PullRequests.ListRepoPullRequests(g.ctx, g.repoOwner, g.repoName, gitea_sdk.ListPullRequestsOptions{ ListOptions: gitea_sdk.ListOptions{ Page: page, PageSize: perPage, @@ -637,7 +637,7 @@ func (g *GiteaDownloader) GetPullRequests(ctx context.Context, page, perPage int // GetReviews returns pull requests review func (g *GiteaDownloader) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) { - if err := g.client.CheckServerVersionConstraint(">=1.12"); err != nil { + if err := g.client.CheckServerVersionConstraint(g.ctx, ">=1.12"); err != nil { log.Info("GiteaDownloader: instance to old, skip GetReviews") return nil, nil } @@ -652,7 +652,7 @@ func (g *GiteaDownloader) GetReviews(ctx context.Context, reviewable base.Review default: } - prl, _, err := g.client.ListPullReviews(g.repoOwner, g.repoName, reviewable.GetForeignIndex(), gitea_sdk.ListPullReviewsOptions{ListOptions: gitea_sdk.ListOptions{ + prl, _, err := g.client.PullRequests.ListPullReviews(g.ctx, g.repoOwner, g.repoName, reviewable.GetForeignIndex(), gitea_sdk.ListPullReviewsOptions{ListOptions: gitea_sdk.ListOptions{ Page: i, PageSize: g.maxPerPage, }}) @@ -667,7 +667,7 @@ func (g *GiteaDownloader) GetReviews(ctx context.Context, reviewable base.Review continue } - rcl, _, err := g.client.ListPullReviewComments(g.repoOwner, g.repoName, reviewable.GetForeignIndex(), pr.ID) + rcl, _, err := g.client.PullRequests.ListPullReviewComments(g.ctx, g.repoOwner, g.repoName, reviewable.GetForeignIndex(), pr.ID) if err != nil { return nil, err } diff --git a/tests/e2e/issue-comment.test.ts b/tests/e2e/issue-comment.test.ts index d3de59ba5f..414e0567ce 100644 --- a/tests/e2e/issue-comment.test.ts +++ b/tests/e2e/issue-comment.test.ts @@ -18,7 +18,9 @@ test('comment on and close an issue', async ({page, request}) => { await page.getByRole('button', {name: 'Comment', exact: true}).click(); await expect(page.locator('.comment-body').filter({hasText: body})).toBeVisible(); - // posting reloaded the page with an empty box, so the status button now reads "Close Issue" + // wait for the form to re-initialize (the empty box disables the comment button); a close click + // before that does a native submit which lands on a raw JSON page instead of reloading the issue + await expect(page.getByRole('button', {name: 'Comment', exact: true})).toBeDisabled(); await page.getByRole('button', {name: 'Close Issue'}).click(); await expect(page.getByRole('button', {name: 'Reopen Issue'})).toBeVisible(); }); diff --git a/tests/integration/actions_concurrency_test.go b/tests/integration/actions_concurrency_test.go index cc8b24aead..47b9112534 100644 --- a/tests/integration/actions_concurrency_test.go +++ b/tests/integration/actions_concurrency_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" "gitea.dev/models/db" @@ -24,7 +25,6 @@ import ( actions_web "gitea.dev/routers/web/repo/actions" actions_service "gitea.dev/services/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/tests/integration/actions_delete_run_test.go b/tests/integration/actions_delete_run_test.go index f5e480f7c2..dc8f67d70e 100644 --- a/tests/integration/actions_delete_run_test.go +++ b/tests/integration/actions_delete_run_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" "gitea.dev/models/unittest" @@ -18,7 +19,6 @@ import ( "gitea.dev/modules/json" "gitea.dev/routers/web/repo/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/tests/integration/actions_job_test.go b/tests/integration/actions_job_test.go index 71cf9bdb3e..02d801c582 100644 --- a/tests/integration/actions_job_test.go +++ b/tests/integration/actions_job_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" "gitea.dev/models/db" @@ -26,7 +27,6 @@ import ( "gitea.dev/modules/timeutil" actions_service "gitea.dev/services/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "connectrpc.com/connect" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/tests/integration/actions_log_finalize_test.go b/tests/integration/actions_log_finalize_test.go index 99c42e188b..134f96bda7 100644 --- a/tests/integration/actions_log_finalize_test.go +++ b/tests/integration/actions_log_finalize_test.go @@ -9,6 +9,7 @@ import ( "os" "testing" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" "gitea.dev/models/dbfs" @@ -18,7 +19,6 @@ import ( actions_module "gitea.dev/modules/actions" "gitea.dev/modules/storage" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "connectrpc.com/connect" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -73,5 +73,19 @@ jobs: _, err = dbfs.Open(t.Context(), actions_module.DBFSPrefix+freshTask.LogFilename) assert.ErrorIs(t, err, os.ErrNotExist, "DBFS row must be cleaned up after TransferLogs") + + // The runner re-sends its final UpdateLog when the response was lost. + // A sealed log must ack the re-send and still reject new appended rows. + t.Run("re-sent finalize is idempotent", func(t *testing.T) { + finalize := &runnerv1.UpdateLogRequest{TaskId: task.Id, Index: 0, Rows: nil, NoMore: true} + resp, err := runner.client.runnerServiceClient.UpdateLog(t.Context(), connect.NewRequest(finalize)) + require.NoError(t, err) + assert.EqualValues(t, 0, resp.Msg.AckIndex) + + _, err = runner.client.runnerServiceClient.UpdateLog(t.Context(), connect.NewRequest(&runnerv1.UpdateLogRequest{ + TaskId: task.Id, Index: 0, Rows: []*runnerv1.LogRow{{Content: "late"}}, NoMore: true, + })) + require.Error(t, err, "appending rows past the seal must be rejected") + }) }) } diff --git a/tests/integration/actions_log_test.go b/tests/integration/actions_log_test.go index 79ab6f12a5..a8cbc13058 100644 --- a/tests/integration/actions_log_test.go +++ b/tests/integration/actions_log_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" repo_model "gitea.dev/models/repo" @@ -20,7 +21,6 @@ import ( "gitea.dev/modules/storage" "gitea.dev/modules/test" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/tests/integration/actions_rerun_test.go b/tests/integration/actions_rerun_test.go index 634c2d0e8e..b088a2379a 100644 --- a/tests/integration/actions_rerun_test.go +++ b/tests/integration/actions_rerun_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" "gitea.dev/models/db" @@ -24,7 +25,6 @@ import ( "gitea.dev/modules/timeutil" actions_web "gitea.dev/routers/web/repo/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/tests/integration/actions_route_test.go b/tests/integration/actions_route_test.go index 98786d2684..1591a17ae0 100644 --- a/tests/integration/actions_route_test.go +++ b/tests/integration/actions_route_test.go @@ -9,6 +9,7 @@ import ( "net/url" "testing" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" "gitea.dev/models/db" @@ -17,7 +18,6 @@ import ( "gitea.dev/modules/setting" actions_web "gitea.dev/routers/web/repo/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/tests/integration/actions_runner_test.go b/tests/integration/actions_runner_test.go index dc2e203228..017b3a3f1b 100644 --- a/tests/integration/actions_runner_test.go +++ b/tests/integration/actions_runner_test.go @@ -10,13 +10,13 @@ import ( "testing" "time" + pingv1 "gitea.dev/actions-proto-go/ping/v1" + "gitea.dev/actions-proto-go/ping/v1/pingv1connect" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" + "gitea.dev/actions-proto-go/runner/v1/runnerv1connect" auth_model "gitea.dev/models/auth" "gitea.dev/modules/setting" - pingv1 "code.gitea.io/actions-proto-go/ping/v1" - "code.gitea.io/actions-proto-go/ping/v1/pingv1connect" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "code.gitea.io/actions-proto-go/runner/v1/runnerv1connect" "connectrpc.com/connect" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/tests/integration/api_actions_artifact_test.go b/tests/integration/api_actions_artifact_test.go index 31b60cffc0..9e8444525f 100644 --- a/tests/integration/api_actions_artifact_test.go +++ b/tests/integration/api_actions_artifact_test.go @@ -16,13 +16,13 @@ import ( "strings" "testing" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" auth_model "gitea.dev/models/auth" repo_model "gitea.dev/models/repo" "gitea.dev/models/unittest" user_model "gitea.dev/models/user" "gitea.dev/tests" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/tests/integration/api_actions_artifact_v4_test.go b/tests/integration/api_actions_artifact_v4_test.go index c988f41756..acefc9eeb8 100644 --- a/tests/integration/api_actions_artifact_v4_test.go +++ b/tests/integration/api_actions_artifact_v4_test.go @@ -18,6 +18,7 @@ import ( "testing" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" repo_model "gitea.dev/models/repo" @@ -32,7 +33,6 @@ import ( "gitea.dev/routers/api/actions" actions_service "gitea.dev/services/actions" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/encoding/protojson" diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index 6f95408033..af309674cd 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -15,6 +15,7 @@ import ( "testing" "time" + runnerv1 "gitea.dev/actions-proto-go/runner/v1" actions_model "gitea.dev/models/actions" auth_model "gitea.dev/models/auth" db_model "gitea.dev/models/db" @@ -34,7 +35,6 @@ import ( "gitea.dev/services/actions" "gitea.dev/tests" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" "github.com/PuerkitoBio/goquery" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"