mirror of
https://codeberg.org/forgejo/forgejo
synced 2024-11-28 12:46:09 +01:00
Compare commits
41 commits
8bcb0f08e0
...
43a54a64e3
Author | SHA1 | Date | |
---|---|---|---|
43a54a64e3 | |||
77506c6f6c | |||
8e9b6817bc | |||
23efd9d278 | |||
692929b628 | |||
caad931385 | |||
b693611b35 | |||
5d09023f13 | |||
0e6fd0d1c1 | |||
49d7663929 | |||
1df06e3f39 | |||
14f6fcf448 | |||
80d48621cd | |||
6c771a311b | |||
7711db0a71 | |||
5574968ecb | |||
b9d91694af | |||
62f995203a | |||
d68a613ba8 | |||
07ba4d9f87 | |||
461d8b53c2 | |||
075c4c89ee | |||
1167d523c4 | |||
b60a7c3358 | |||
4674aea25b | |||
eba9c0ce48 | |||
c8ba17c73f | |||
2bdab948cb | |||
ad98ea63ee | |||
49eb168677 | |||
9c869b10b5 | |||
b8270240bf | |||
edfb57e699 | |||
c08d263a19 | |||
930e38d010 | |||
5374d29aa9 | |||
d971dfbae1 | |||
885cc32b14 | |||
2c3da59e27 | |||
2d343f8987 | |||
3793ec4d14 |
|
@ -1,42 +0,0 @@
|
||||||
<!-- NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue -->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
1. Please speak English, this is the language all maintainers can speak and write.
|
|
||||||
2. Please ask questions or configuration/deploy problems on our Discord
|
|
||||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
|
||||||
3. Please take a moment to check that your issue doesn't already exist.
|
|
||||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
|
|
||||||
5. Please give all relevant information below for bug reports, because
|
|
||||||
incomplete details will be handled as an invalid report.
|
|
||||||
-->
|
|
||||||
|
|
||||||
- Gitea version (or commit ref):
|
|
||||||
- Git version:
|
|
||||||
- Operating system:
|
|
||||||
<!-- Please include information on whether you built gitea yourself, used one of our downloads or are using some other package -->
|
|
||||||
<!-- Please also tell us how you are running gitea, e.g. if it is being run from docker, a command-line, systemd etc. --->
|
|
||||||
<!-- If you are using a package or systemd tell us what distribution you are using -->
|
|
||||||
- Database (use `[x]`):
|
|
||||||
- [ ] PostgreSQL
|
|
||||||
- [ ] MySQL
|
|
||||||
- [ ] MSSQL
|
|
||||||
- [ ] SQLite
|
|
||||||
- Can you reproduce the bug at https://try.gitea.io:
|
|
||||||
- [ ] Yes (provide example URL)
|
|
||||||
- [ ] No
|
|
||||||
- Log gist:
|
|
||||||
<!-- It really is important to provide pertinent logs -->
|
|
||||||
<!-- Please read https://docs.gitea.com/administration/logging-config#collecting-logs-for-help -->
|
|
||||||
<!-- In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini -->
|
|
||||||
|
|
||||||
## Description
|
|
||||||
<!-- If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please
|
|
||||||
disable the proxy/CDN fully and connect to gitea directly to confirm
|
|
||||||
the issue still persists without those services. -->
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
|
|
||||||
<!-- **If this issue involves the Web Interface, please include a screenshot** -->
|
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
|
@ -1,2 +0,0 @@
|
||||||
open_collective: gitea
|
|
||||||
custom: https://www.bountysource.com/teams/gitea
|
|
91
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
91
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
|
@ -1,91 +0,0 @@
|
||||||
name: Bug Report
|
|
||||||
description: Found something you weren't expecting? Report it here!
|
|
||||||
labels: ["type/bug"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
1. Please speak English, this is the language all maintainers can speak and write.
|
|
||||||
2. Please ask questions or configuration/deploy problems on our Discord
|
|
||||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
|
||||||
3. Make sure you are using the latest release and
|
|
||||||
take a moment to check that your issue hasn't been reported before.
|
|
||||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
|
|
||||||
5. It's really important to provide pertinent details and logs (https://docs.gitea.com/help/support),
|
|
||||||
incomplete details will be handled as an invalid report.
|
|
||||||
- type: textarea
|
|
||||||
id: description
|
|
||||||
attributes:
|
|
||||||
label: Description
|
|
||||||
description: |
|
|
||||||
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below)
|
|
||||||
If you are using a proxy or a CDN (e.g. Cloudflare) in front of Gitea, please disable the proxy/CDN fully and access Gitea directly to confirm the issue still persists without those services.
|
|
||||||
- type: input
|
|
||||||
id: gitea-ver
|
|
||||||
attributes:
|
|
||||||
label: Gitea Version
|
|
||||||
description: Gitea version (or commit reference) of your instance
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
id: can-reproduce
|
|
||||||
attributes:
|
|
||||||
label: Can you reproduce the bug on the Gitea demo site?
|
|
||||||
description: |
|
|
||||||
If so, please provide a URL in the Description field
|
|
||||||
URL of Gitea demo: https://try.gitea.io
|
|
||||||
options:
|
|
||||||
- "Yes"
|
|
||||||
- "No"
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
It's really important to provide pertinent logs
|
|
||||||
Please read https://docs.gitea.com/administration/logging-config#collecting-logs-for-help
|
|
||||||
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini
|
|
||||||
- type: input
|
|
||||||
id: logs
|
|
||||||
attributes:
|
|
||||||
label: Log Gist
|
|
||||||
description: Please provide a gist URL of your logs, with any sensitive information (e.g. API keys) removed/hidden
|
|
||||||
- type: textarea
|
|
||||||
id: screenshots
|
|
||||||
attributes:
|
|
||||||
label: Screenshots
|
|
||||||
description: If this issue involves the Web Interface, please provide one or more screenshots
|
|
||||||
- type: input
|
|
||||||
id: git-ver
|
|
||||||
attributes:
|
|
||||||
label: Git Version
|
|
||||||
description: The version of git running on the server
|
|
||||||
- type: input
|
|
||||||
id: os-ver
|
|
||||||
attributes:
|
|
||||||
label: Operating System
|
|
||||||
description: The operating system you are using to run Gitea
|
|
||||||
- type: textarea
|
|
||||||
id: run-info
|
|
||||||
attributes:
|
|
||||||
label: How are you running Gitea?
|
|
||||||
description: |
|
|
||||||
Please include information on whether you built Gitea yourself, used one of our downloads, are using https://try.gitea.io or are using some other package
|
|
||||||
Please also tell us how you are running Gitea, e.g. if it is being run from docker, a command-line, systemd etc.
|
|
||||||
If you are using a package or systemd tell us what distribution you are using
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
id: database
|
|
||||||
attributes:
|
|
||||||
label: Database
|
|
||||||
description: What database system are you running?
|
|
||||||
options:
|
|
||||||
- PostgreSQL
|
|
||||||
- MySQL/MariaDB
|
|
||||||
- MSSQL
|
|
||||||
- SQLite
|
|
17
.github/ISSUE_TEMPLATE/config.yml
vendored
17
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,17 +0,0 @@
|
||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: Security Concern
|
|
||||||
url: https://tinyurl.com/security-gitea
|
|
||||||
about: For security concerns, please send a mail to security@gitea.io instead of opening a public issue.
|
|
||||||
- name: Discord Server
|
|
||||||
url: https://discord.gg/Gitea
|
|
||||||
about: Please ask questions and discuss configuration or deployment problems here.
|
|
||||||
- name: Discourse Forum
|
|
||||||
url: https://discourse.gitea.io
|
|
||||||
about: Questions and configuration or deployment problems can also be discussed on our forum.
|
|
||||||
- name: Frequently Asked Questions
|
|
||||||
url: https://docs.gitea.com/help/faq
|
|
||||||
about: Please check if your question isn't mentioned here.
|
|
||||||
- name: Crowdin Translations
|
|
||||||
url: https://crowdin.com/project/gitea
|
|
||||||
about: Translations are managed here.
|
|
24
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
24
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
|
@ -1,24 +0,0 @@
|
||||||
name: Feature Request
|
|
||||||
description: Got an idea for a feature that Gitea doesn't have currently? Submit your idea here!
|
|
||||||
labels: ["type/proposal"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
1. Please speak English, this is the language all maintainers can speak and write.
|
|
||||||
2. Please ask questions or configuration/deploy problems on our Discord
|
|
||||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
|
||||||
3. Please take a moment to check that your feature hasn't already been suggested.
|
|
||||||
- type: textarea
|
|
||||||
id: description
|
|
||||||
attributes:
|
|
||||||
label: Feature Description
|
|
||||||
placeholder: |
|
|
||||||
I think it would be great if Gitea had...
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
id: screenshots
|
|
||||||
attributes:
|
|
||||||
label: Screenshots
|
|
||||||
description: If you can, provide screenshots of an implementation on another site e.g. GitHub
|
|
66
.github/ISSUE_TEMPLATE/ui.bug-report.yaml
vendored
66
.github/ISSUE_TEMPLATE/ui.bug-report.yaml
vendored
|
@ -1,66 +0,0 @@
|
||||||
name: Web Interface Bug Report
|
|
||||||
description: Something doesn't look quite as it should? Report it here!
|
|
||||||
labels: ["type/bug", "topic/ui"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
1. Please speak English, this is the language all maintainers can speak and write.
|
|
||||||
2. Please ask questions or configuration/deploy problems on our Discord
|
|
||||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
|
||||||
3. Please take a moment to check that your issue doesn't already exist.
|
|
||||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.com/help/faq)
|
|
||||||
5. Please give all relevant information below for bug reports, because
|
|
||||||
incomplete details will be handled as an invalid report.
|
|
||||||
6. In particular it's really important to provide pertinent logs. If you are certain that this is a javascript
|
|
||||||
error, show us the javascript console. If the error appears to relate to Gitea the server you must also give us
|
|
||||||
DEBUG level logs. (See https://docs.gitea.com/administration/logging-config#collecting-logs-for-help)
|
|
||||||
- type: textarea
|
|
||||||
id: description
|
|
||||||
attributes:
|
|
||||||
label: Description
|
|
||||||
description: |
|
|
||||||
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below)
|
|
||||||
If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please disable the proxy/CDN fully and connect to gitea directly to confirm the issue still persists without those services.
|
|
||||||
- type: textarea
|
|
||||||
id: screenshots
|
|
||||||
attributes:
|
|
||||||
label: Screenshots
|
|
||||||
description: Please provide at least 1 screenshot showing the issue.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: gitea-ver
|
|
||||||
attributes:
|
|
||||||
label: Gitea Version
|
|
||||||
description: Gitea version (or commit reference) your instance is running
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
id: can-reproduce
|
|
||||||
attributes:
|
|
||||||
label: Can you reproduce the bug on the Gitea demo site?
|
|
||||||
description: |
|
|
||||||
If so, please provide a URL in the Description field
|
|
||||||
URL of Gitea demo: https://try.gitea.io
|
|
||||||
options:
|
|
||||||
- "Yes"
|
|
||||||
- "No"
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: os-ver
|
|
||||||
attributes:
|
|
||||||
label: Operating System
|
|
||||||
description: The operating system you are using to access Gitea
|
|
||||||
- type: input
|
|
||||||
id: browser-ver
|
|
||||||
attributes:
|
|
||||||
label: Browser Version
|
|
||||||
description: The browser and version that you are using to access Gitea
|
|
||||||
validations:
|
|
||||||
required: true
|
|
5
.github/actionlint.yaml
vendored
5
.github/actionlint.yaml
vendored
|
@ -1,5 +0,0 @@
|
||||||
self-hosted-runner:
|
|
||||||
labels:
|
|
||||||
- actuated-4cpu-8gb
|
|
||||||
- actuated-4cpu-16gb
|
|
||||||
- nscloud
|
|
36
.github/labeler.yml
vendored
36
.github/labeler.yml
vendored
|
@ -1,36 +0,0 @@
|
||||||
modifies/docs:
|
|
||||||
- "**/*.md"
|
|
||||||
- "docs/**"
|
|
||||||
|
|
||||||
modifies/frontend:
|
|
||||||
- "web_src/**/*"
|
|
||||||
|
|
||||||
modifies/templates:
|
|
||||||
- all: ["templates/**", "!templates/swagger/v1_json.tmpl"]
|
|
||||||
|
|
||||||
modifies/api:
|
|
||||||
- "routers/api/**"
|
|
||||||
- "templates/swagger/v1_json.tmpl"
|
|
||||||
|
|
||||||
modifies/cli:
|
|
||||||
- "cmd/**"
|
|
||||||
|
|
||||||
modifies/translation:
|
|
||||||
- "options/locale/*.ini"
|
|
||||||
|
|
||||||
modifies/migrations:
|
|
||||||
- "models/migrations/**/*"
|
|
||||||
|
|
||||||
modifies/internal:
|
|
||||||
- "Makefile"
|
|
||||||
- "Dockerfile"
|
|
||||||
- "Dockerfile.rootless"
|
|
||||||
- "docker/**"
|
|
||||||
- "webpack.config.js"
|
|
||||||
- ".eslintrc.yaml"
|
|
||||||
- ".golangci.yml"
|
|
||||||
- ".markdownlint.yaml"
|
|
||||||
- ".spectral.yaml"
|
|
||||||
- ".stylelintrc.yaml"
|
|
||||||
- ".yamllint.yaml"
|
|
||||||
- ".github/**"
|
|
9
.github/pull_request_template.md
vendored
9
.github/pull_request_template.md
vendored
|
@ -1,9 +0,0 @@
|
||||||
<!-- start tips -->
|
|
||||||
Please check the following:
|
|
||||||
1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for backports.
|
|
||||||
2. Make sure you have read contributing guidelines: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md .
|
|
||||||
3. Describe what your pull request does and which issue you're targeting (if any).
|
|
||||||
4. It is recommended to enable "Allow edits by maintainers", so maintainers can help more easily.
|
|
||||||
5. Your input here will be included in the commit message when this PR has been merged. If you don't want some content to be included, please separate them with a line like `---`.
|
|
||||||
6. Delete all these tips before posting.
|
|
||||||
<!-- end tips -->
|
|
29
.github/workflows/cron-licenses.yml
vendored
29
.github/workflows/cron-licenses.yml
vendored
|
@ -1,29 +0,0 @@
|
||||||
name: cron-licenses
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "7 0 * * 1" # every Monday at 00:07 UTC
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cron-licenses:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository == 'go-gitea/gitea'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- run: make generate-license generate-gitignore
|
|
||||||
timeout-minutes: 40
|
|
||||||
- name: push translations to repo
|
|
||||||
uses: appleboy/git-push-action@v0.0.3
|
|
||||||
with:
|
|
||||||
author_email: "teabot@gitea.io"
|
|
||||||
author_name: GiteaBot
|
|
||||||
branch: main
|
|
||||||
commit: true
|
|
||||||
commit_message: "[skip ci] Updated licenses and gitignores"
|
|
||||||
remote: "git@github.com:go-gitea/gitea.git"
|
|
||||||
ssh_key: ${{ secrets.DEPLOY_KEY }}
|
|
22
.github/workflows/cron-lock.yml
vendored
22
.github/workflows/cron-lock.yml
vendored
|
@ -1,22 +0,0 @@
|
||||||
name: cron-lock
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * *" # every day at 00:00 UTC
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: lock
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
action:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository == 'go-gitea/gitea'
|
|
||||||
steps:
|
|
||||||
- uses: dessant/lock-threads@v5
|
|
||||||
with:
|
|
||||||
issue-inactive-days: 45
|
|
49
.github/workflows/cron-translations.yml
vendored
49
.github/workflows/cron-translations.yml
vendored
|
@ -1,49 +0,0 @@
|
||||||
name: cron-translations
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "7 0 * * *" # every day at 00:07 UTC
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
crowdin-pull:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository == 'go-gitea/gitea'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: download from crowdin
|
|
||||||
uses: docker://jonasfranz/crowdin
|
|
||||||
env:
|
|
||||||
CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }}
|
|
||||||
PLUGIN_DOWNLOAD: true
|
|
||||||
PLUGIN_EXPORT_DIR: options/locale/
|
|
||||||
PLUGIN_IGNORE_BRANCH: true
|
|
||||||
PLUGIN_PROJECT_IDENTIFIER: gitea
|
|
||||||
- name: update locales
|
|
||||||
run: ./build/update-locales.sh
|
|
||||||
- name: push translations to repo
|
|
||||||
uses: appleboy/git-push-action@v0.0.3
|
|
||||||
with:
|
|
||||||
author_email: "teabot@gitea.io"
|
|
||||||
author_name: GiteaBot
|
|
||||||
branch: main
|
|
||||||
commit: true
|
|
||||||
commit_message: "[skip ci] Updated translations via Crowdin"
|
|
||||||
remote: "git@github.com:go-gitea/gitea.git"
|
|
||||||
ssh_key: ${{ secrets.DEPLOY_KEY }}
|
|
||||||
crowdin-push:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.repository == 'go-gitea/gitea'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: push translations to crowdin
|
|
||||||
uses: docker://jonasfranz/crowdin
|
|
||||||
env:
|
|
||||||
CROWDIN_KEY: ${{ secrets.CROWDIN_KEY }}
|
|
||||||
PLUGIN_UPLOAD: true
|
|
||||||
PLUGIN_EXPORT_DIR: options/locale/
|
|
||||||
PLUGIN_IGNORE_BRANCH: true
|
|
||||||
PLUGIN_PROJECT_IDENTIFIER: gitea
|
|
||||||
PLUGIN_FILES: |
|
|
||||||
locale_en-US.ini: options/locale/locale_en-US.ini
|
|
||||||
PLUGIN_BRANCH: main
|
|
25
.github/workflows/disk-clean.yml
vendored
25
.github/workflows/disk-clean.yml
vendored
|
@ -1,25 +0,0 @@
|
||||||
name: disk-clean
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
triage:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Free Disk Space (Ubuntu)
|
|
||||||
uses: jlumbroso/free-disk-space@main
|
|
||||||
with:
|
|
||||||
# this might remove tools that are actually needed,
|
|
||||||
# if set to "true" but frees about 6 GB
|
|
||||||
tool-cache: false
|
|
||||||
|
|
||||||
# all of these default to true, but feel free to set to
|
|
||||||
# "false" if necessary for your workflow
|
|
||||||
android: true
|
|
||||||
dotnet: true
|
|
||||||
haskell: true
|
|
||||||
large-packages: false
|
|
||||||
docker-images: false
|
|
||||||
swap-storage: true
|
|
97
.github/workflows/files-changed.yml
vendored
97
.github/workflows/files-changed.yml
vendored
|
@ -1,97 +0,0 @@
|
||||||
name: files-changed
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
outputs:
|
|
||||||
backend:
|
|
||||||
value: ${{ jobs.detect.outputs.backend }}
|
|
||||||
frontend:
|
|
||||||
value: ${{ jobs.detect.outputs.frontend }}
|
|
||||||
docs:
|
|
||||||
value: ${{ jobs.detect.outputs.docs }}
|
|
||||||
actions:
|
|
||||||
value: ${{ jobs.detect.outputs.actions }}
|
|
||||||
templates:
|
|
||||||
value: ${{ jobs.detect.outputs.templates }}
|
|
||||||
docker:
|
|
||||||
value: ${{ jobs.detect.outputs.docker }}
|
|
||||||
swagger:
|
|
||||||
value: ${{ jobs.detect.outputs.swagger }}
|
|
||||||
yaml:
|
|
||||||
value: ${{ jobs.detect.outputs.yaml }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
detect:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 3
|
|
||||||
outputs:
|
|
||||||
backend: ${{ steps.changes.outputs.backend }}
|
|
||||||
frontend: ${{ steps.changes.outputs.frontend }}
|
|
||||||
docs: ${{ steps.changes.outputs.docs }}
|
|
||||||
actions: ${{ steps.changes.outputs.actions }}
|
|
||||||
templates: ${{ steps.changes.outputs.templates }}
|
|
||||||
docker: ${{ steps.changes.outputs.docker }}
|
|
||||||
swagger: ${{ steps.changes.outputs.swagger }}
|
|
||||||
yaml: ${{ steps.changes.outputs.yaml }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: dorny/paths-filter@v2
|
|
||||||
id: changes
|
|
||||||
with:
|
|
||||||
filters: |
|
|
||||||
backend:
|
|
||||||
- "**/*.go"
|
|
||||||
- "templates/**/*.tmpl"
|
|
||||||
- "assets/emoji.json"
|
|
||||||
- "go.mod"
|
|
||||||
- "go.sum"
|
|
||||||
- "Makefile"
|
|
||||||
- ".golangci.yml"
|
|
||||||
- ".editorconfig"
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
- "**/*.js"
|
|
||||||
- "web_src/**"
|
|
||||||
- "assets/emoji.json"
|
|
||||||
- "package.json"
|
|
||||||
- "package-lock.json"
|
|
||||||
- "Makefile"
|
|
||||||
- ".eslintrc.yaml"
|
|
||||||
- ".stylelintrc.yaml"
|
|
||||||
- ".npmrc"
|
|
||||||
|
|
||||||
docs:
|
|
||||||
- "**/*.md"
|
|
||||||
- "docs/**"
|
|
||||||
- ".markdownlint.yaml"
|
|
||||||
- "package.json"
|
|
||||||
- "package-lock.json"
|
|
||||||
|
|
||||||
actions:
|
|
||||||
- ".github/workflows/*"
|
|
||||||
- "Makefile"
|
|
||||||
|
|
||||||
templates:
|
|
||||||
- "templates/**/*.tmpl"
|
|
||||||
- "pyproject.toml"
|
|
||||||
- "poetry.lock"
|
|
||||||
|
|
||||||
docker:
|
|
||||||
- "Dockerfile"
|
|
||||||
- "Dockerfile.rootless"
|
|
||||||
- "docker/**"
|
|
||||||
- "Makefile"
|
|
||||||
|
|
||||||
swagger:
|
|
||||||
- "templates/swagger/v1_json.tmpl"
|
|
||||||
- "Makefile"
|
|
||||||
- "package.json"
|
|
||||||
- "package-lock.json"
|
|
||||||
- ".spectral.yaml"
|
|
||||||
|
|
||||||
yaml:
|
|
||||||
- "**/*.yml"
|
|
||||||
- "**/*.yaml"
|
|
||||||
- ".yamllint.yaml"
|
|
||||||
- "pyproject.toml"
|
|
||||||
- "poetry.lock"
|
|
182
.github/workflows/pull-compliance.yml
vendored
182
.github/workflows/pull-compliance.yml
vendored
|
@ -1,182 +0,0 @@
|
||||||
name: compliance
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
files-changed:
|
|
||||||
uses: ./.github/workflows/files-changed.yml
|
|
||||||
|
|
||||||
lint-backend:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- run: make deps-backend deps-tools
|
|
||||||
- run: make lint-backend
|
|
||||||
env:
|
|
||||||
TAGS: bindata sqlite sqlite_unlock_notify
|
|
||||||
|
|
||||||
lint-templates:
|
|
||||||
if: needs.files-changed.outputs.templates == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- run: pip install poetry
|
|
||||||
- run: make deps-py
|
|
||||||
- run: make lint-templates
|
|
||||||
|
|
||||||
lint-yaml:
|
|
||||||
if: needs.files-changed.outputs.yaml == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: "3.11"
|
|
||||||
- run: pip install poetry
|
|
||||||
- run: make deps-py
|
|
||||||
- run: make lint-yaml
|
|
||||||
|
|
||||||
lint-swagger:
|
|
||||||
if: needs.files-changed.outputs.swagger == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- run: make deps-frontend
|
|
||||||
- run: make lint-swagger
|
|
||||||
|
|
||||||
lint-go-windows:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- run: make deps-backend deps-tools
|
|
||||||
- run: make lint-go-windows lint-go-vet
|
|
||||||
env:
|
|
||||||
TAGS: bindata sqlite sqlite_unlock_notify
|
|
||||||
GOOS: windows
|
|
||||||
GOARCH: amd64
|
|
||||||
|
|
||||||
lint-go-gogit:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- run: make deps-backend deps-tools
|
|
||||||
- run: make lint-go
|
|
||||||
env:
|
|
||||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
|
||||||
|
|
||||||
checks-backend:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- run: make deps-backend deps-tools
|
|
||||||
- run: make --always-make checks-backend # ensure the "go-licenses" make target runs
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
if: needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- run: make deps-frontend
|
|
||||||
- run: make lint-frontend
|
|
||||||
- run: make checks-frontend
|
|
||||||
- run: make test-frontend
|
|
||||||
- run: make frontend
|
|
||||||
|
|
||||||
backend:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
# no frontend build here as backend should be able to build
|
|
||||||
# even without any frontend files
|
|
||||||
- run: make deps-backend
|
|
||||||
- run: go build -o gitea_no_gcc # test if build succeeds without the sqlite tag
|
|
||||||
- name: build-backend-arm64
|
|
||||||
run: make backend # test cross compile
|
|
||||||
env:
|
|
||||||
GOOS: linux
|
|
||||||
GOARCH: arm64
|
|
||||||
TAGS: bindata gogit
|
|
||||||
- name: build-backend-windows
|
|
||||||
run: go build -o gitea_windows
|
|
||||||
env:
|
|
||||||
GOOS: windows
|
|
||||||
GOARCH: amd64
|
|
||||||
TAGS: bindata gogit
|
|
||||||
- name: build-backend-386
|
|
||||||
run: go build -o gitea_linux_386 # test if compatible with 32 bit
|
|
||||||
env:
|
|
||||||
GOOS: linux
|
|
||||||
GOARCH: 386
|
|
||||||
|
|
||||||
docs:
|
|
||||||
if: needs.files-changed.outputs.docs == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- run: make deps-frontend
|
|
||||||
- run: make lint-md
|
|
||||||
- run: make docs
|
|
||||||
|
|
||||||
actions:
|
|
||||||
if: needs.files-changed.outputs.actions == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- run: make lint-actions
|
|
215
.github/workflows/pull-db-tests.yml
vendored
215
.github/workflows/pull-db-tests.yml
vendored
|
@ -1,215 +0,0 @@
|
||||||
name: db-tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
files-changed:
|
|
||||||
uses: ./.github/workflows/files-changed.yml
|
|
||||||
|
|
||||||
test-pgsql:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
services:
|
|
||||||
pgsql:
|
|
||||||
image: postgres:12
|
|
||||||
env:
|
|
||||||
POSTGRES_DB: test
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
ldap:
|
|
||||||
image: gitea/test-openldap:latest
|
|
||||||
ports:
|
|
||||||
- "389:389"
|
|
||||||
- "636:636"
|
|
||||||
minio:
|
|
||||||
# as github actions doesn't support "entrypoint", we need to use a non-official image
|
|
||||||
# that has a custom entrypoint set to "minio server /data"
|
|
||||||
image: bitnami/minio:2023.8.31
|
|
||||||
env:
|
|
||||||
MINIO_ROOT_USER: 123456
|
|
||||||
MINIO_ROOT_PASSWORD: 12345678
|
|
||||||
ports:
|
|
||||||
- "9000:9000"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- name: Add hosts to /etc/hosts
|
|
||||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 pgsql ldap minio" | sudo tee -a /etc/hosts'
|
|
||||||
- run: make deps-backend
|
|
||||||
- run: make backend
|
|
||||||
env:
|
|
||||||
TAGS: bindata
|
|
||||||
- run: make test-pgsql-migration test-pgsql
|
|
||||||
timeout-minutes: 50
|
|
||||||
env:
|
|
||||||
TAGS: bindata gogit
|
|
||||||
RACE_ENABLED: true
|
|
||||||
TEST_TAGS: gogit
|
|
||||||
TEST_LDAP: 1
|
|
||||||
USE_REPO_TEST_DIR: 1
|
|
||||||
|
|
||||||
test-sqlite:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- run: make deps-backend
|
|
||||||
- run: make backend
|
|
||||||
env:
|
|
||||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
|
||||||
- run: make test-sqlite-migration test-sqlite
|
|
||||||
timeout-minutes: 50
|
|
||||||
env:
|
|
||||||
TAGS: bindata gogit sqlite sqlite_unlock_notify
|
|
||||||
RACE_ENABLED: true
|
|
||||||
TEST_TAGS: gogit sqlite sqlite_unlock_notify
|
|
||||||
USE_REPO_TEST_DIR: 1
|
|
||||||
|
|
||||||
test-unit:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
services:
|
|
||||||
elasticsearch:
|
|
||||||
image: elasticsearch:7.5.0
|
|
||||||
env:
|
|
||||||
discovery.type: single-node
|
|
||||||
ports:
|
|
||||||
- "9200:9200"
|
|
||||||
meilisearch:
|
|
||||||
image: getmeili/meilisearch:v1.2.0
|
|
||||||
env:
|
|
||||||
MEILI_ENV: development # disable auth
|
|
||||||
ports:
|
|
||||||
- "7700:7700"
|
|
||||||
redis:
|
|
||||||
image: redis
|
|
||||||
options: >- # wait until redis has started
|
|
||||||
--health-cmd "redis-cli ping"
|
|
||||||
--health-interval 5s
|
|
||||||
--health-timeout 3s
|
|
||||||
--health-retries 10
|
|
||||||
ports:
|
|
||||||
- 6379:6379
|
|
||||||
minio:
|
|
||||||
image: bitnami/minio:2021.3.17
|
|
||||||
env:
|
|
||||||
MINIO_ACCESS_KEY: 123456
|
|
||||||
MINIO_SECRET_KEY: 12345678
|
|
||||||
ports:
|
|
||||||
- "9000:9000"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- name: Add hosts to /etc/hosts
|
|
||||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch meilisearch smtpimap" | sudo tee -a /etc/hosts'
|
|
||||||
- run: make deps-backend
|
|
||||||
- run: make backend
|
|
||||||
env:
|
|
||||||
TAGS: bindata
|
|
||||||
- name: unit-tests
|
|
||||||
run: make unit-test-coverage test-check
|
|
||||||
env:
|
|
||||||
TAGS: bindata
|
|
||||||
RACE_ENABLED: true
|
|
||||||
GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }}
|
|
||||||
- name: unit-tests-gogit
|
|
||||||
run: make unit-test-coverage test-check
|
|
||||||
env:
|
|
||||||
TAGS: bindata gogit
|
|
||||||
RACE_ENABLED: true
|
|
||||||
GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }}
|
|
||||||
|
|
||||||
test-mysql:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
services:
|
|
||||||
mysql:
|
|
||||||
image: mysql:8.0
|
|
||||||
env:
|
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
|
||||||
MYSQL_DATABASE: testgitea
|
|
||||||
ports:
|
|
||||||
- "3306:3306"
|
|
||||||
elasticsearch:
|
|
||||||
image: elasticsearch:7.5.0
|
|
||||||
env:
|
|
||||||
discovery.type: single-node
|
|
||||||
ports:
|
|
||||||
- "9200:9200"
|
|
||||||
smtpimap:
|
|
||||||
image: tabascoterrier/docker-imap-devel:latest
|
|
||||||
ports:
|
|
||||||
- "25:25"
|
|
||||||
- "143:143"
|
|
||||||
- "587:587"
|
|
||||||
- "993:993"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- name: Add hosts to /etc/hosts
|
|
||||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch smtpimap" | sudo tee -a /etc/hosts'
|
|
||||||
- run: make deps-backend
|
|
||||||
- run: make backend
|
|
||||||
env:
|
|
||||||
TAGS: bindata
|
|
||||||
- name: run tests
|
|
||||||
run: make test-mysql-migration integration-test-coverage
|
|
||||||
env:
|
|
||||||
TAGS: bindata
|
|
||||||
RACE_ENABLED: true
|
|
||||||
USE_REPO_TEST_DIR: 1
|
|
||||||
TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200"
|
|
||||||
|
|
||||||
test-mssql:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
services:
|
|
||||||
mssql:
|
|
||||||
image: mcr.microsoft.com/mssql/server:2017-latest
|
|
||||||
env:
|
|
||||||
ACCEPT_EULA: Y
|
|
||||||
MSSQL_PID: Standard
|
|
||||||
SA_PASSWORD: MwantsaSecurePassword1
|
|
||||||
ports:
|
|
||||||
- "1433:1433"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- name: Add hosts to /etc/hosts
|
|
||||||
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mssql" | sudo tee -a /etc/hosts'
|
|
||||||
- run: make deps-backend
|
|
||||||
- run: make backend
|
|
||||||
env:
|
|
||||||
TAGS: bindata
|
|
||||||
- run: make test-mssql-migration test-mssql
|
|
||||||
timeout-minutes: 50
|
|
||||||
env:
|
|
||||||
TAGS: bindata
|
|
||||||
USE_REPO_TEST_DIR: 1
|
|
35
.github/workflows/pull-docker-dryrun.yml
vendored
35
.github/workflows/pull-docker-dryrun.yml
vendored
|
@ -1,35 +0,0 @@
|
||||||
name: docker-dryrun
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
files-changed:
|
|
||||||
uses: ./.github/workflows/files-changed.yml
|
|
||||||
|
|
||||||
regular:
|
|
||||||
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
push: false
|
|
||||||
tags: gitea/gitea:linux-amd64
|
|
||||||
|
|
||||||
rootless:
|
|
||||||
if: needs.files-changed.outputs.docker == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
push: false
|
|
||||||
file: Dockerfile.rootless
|
|
||||||
tags: gitea/gitea:linux-amd64
|
|
32
.github/workflows/pull-e2e-tests.yml
vendored
32
.github/workflows/pull-e2e-tests.yml
vendored
|
@ -1,32 +0,0 @@
|
||||||
name: e2e-tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
files-changed:
|
|
||||||
uses: ./.github/workflows/files-changed.yml
|
|
||||||
|
|
||||||
test-e2e:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' || needs.files-changed.outputs.actions == 'true'
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- run: make deps-frontend frontend deps-backend
|
|
||||||
- run: npx playwright install --with-deps
|
|
||||||
- run: make test-e2e-sqlite
|
|
||||||
timeout-minutes: 40
|
|
||||||
env:
|
|
||||||
USE_REPO_TEST_DIR: 1
|
|
20
.github/workflows/pull-labeler.yml
vendored
20
.github/workflows/pull-labeler.yml
vendored
|
@ -1,20 +0,0 @@
|
||||||
name: labeler
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
label:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/labeler@v4
|
|
||||||
with:
|
|
||||||
dot: true
|
|
134
.github/workflows/release-nightly.yml
vendored
134
.github/workflows/release-nightly.yml
vendored
|
@ -1,134 +0,0 @@
|
||||||
name: release-nightly
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main, release/v*]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
disk-clean:
|
|
||||||
uses: ./.github/workflows/disk-clean.yml
|
|
||||||
nightly-binary:
|
|
||||||
runs-on: nscloud
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- run: make deps-frontend deps-backend
|
|
||||||
# xgo build
|
|
||||||
- run: make release
|
|
||||||
env:
|
|
||||||
TAGS: bindata sqlite sqlite_unlock_notify
|
|
||||||
- name: import gpg key
|
|
||||||
id: import_gpg
|
|
||||||
uses: crazy-max/ghaction-import-gpg@v6
|
|
||||||
with:
|
|
||||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
|
||||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
|
||||||
- name: sign binaries
|
|
||||||
run: |
|
|
||||||
for f in dist/release/*; do
|
|
||||||
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
|
|
||||||
done
|
|
||||||
# clean branch name to get the folder name in S3
|
|
||||||
- name: Get cleaned branch name
|
|
||||||
id: clean_name
|
|
||||||
run: |
|
|
||||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
|
||||||
echo "Cleaned name is ${REF_NAME}"
|
|
||||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: configure aws
|
|
||||||
uses: aws-actions/configure-aws-credentials@v4
|
|
||||||
with:
|
|
||||||
aws-region: ${{ secrets.AWS_REGION }}
|
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
||||||
- name: upload binaries to s3
|
|
||||||
run: |
|
|
||||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
|
||||||
nightly-docker-rootful:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- uses: docker/setup-qemu-action@v3
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- name: Get cleaned branch name
|
|
||||||
id: clean_name
|
|
||||||
run: |
|
|
||||||
# if main then say nightly otherwise cleanup name
|
|
||||||
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
|
|
||||||
echo "branch=nightly" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
|
||||||
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: fetch go modules
|
|
||||||
run: make vendor
|
|
||||||
- name: build rootful docker image
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}
|
|
||||||
nightly-docker-rootless:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- uses: docker/setup-qemu-action@v3
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- name: Get cleaned branch name
|
|
||||||
id: clean_name
|
|
||||||
run: |
|
|
||||||
# if main then say nightly otherwise cleanup name
|
|
||||||
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
|
|
||||||
echo "branch=nightly" >> "$GITHUB_OUTPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
|
|
||||||
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: fetch go modules
|
|
||||||
run: make vendor
|
|
||||||
- name: build rootless docker image
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
file: Dockerfile.rootless
|
|
||||||
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}-rootless
|
|
132
.github/workflows/release-tag-rc.yml
vendored
132
.github/workflows/release-tag-rc.yml
vendored
|
@ -1,132 +0,0 @@
|
||||||
name: release-tag-rc
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- "v1*-rc*"
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
binary:
|
|
||||||
runs-on: nscloud
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- run: make deps-frontend deps-backend
|
|
||||||
# xgo build
|
|
||||||
- run: make release
|
|
||||||
env:
|
|
||||||
TAGS: bindata sqlite sqlite_unlock_notify
|
|
||||||
- name: import gpg key
|
|
||||||
id: import_gpg
|
|
||||||
uses: crazy-max/ghaction-import-gpg@v6
|
|
||||||
with:
|
|
||||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
|
||||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
|
||||||
- name: sign binaries
|
|
||||||
run: |
|
|
||||||
for f in dist/release/*; do
|
|
||||||
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
|
|
||||||
done
|
|
||||||
# clean branch name to get the folder name in S3
|
|
||||||
- name: Get cleaned branch name
|
|
||||||
id: clean_name
|
|
||||||
run: |
|
|
||||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
|
|
||||||
echo "Cleaned name is ${REF_NAME}"
|
|
||||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: configure aws
|
|
||||||
uses: aws-actions/configure-aws-credentials@v4
|
|
||||||
with:
|
|
||||||
aws-region: ${{ secrets.AWS_REGION }}
|
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
||||||
- name: upload binaries to s3
|
|
||||||
run: |
|
|
||||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
|
||||||
- name: Install GH CLI
|
|
||||||
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
|
|
||||||
with:
|
|
||||||
gh-cli-version: 2.39.1
|
|
||||||
- name: create github release
|
|
||||||
run: |
|
|
||||||
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --draft --notes-from-tag dist/release/*
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
||||||
docker-rootful:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: docker/setup-qemu-action@v3
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- uses: docker/metadata-action@v5
|
|
||||||
id: meta
|
|
||||||
with:
|
|
||||||
images: gitea/gitea
|
|
||||||
flavor: |
|
|
||||||
latest=false
|
|
||||||
# 1.2.3-rc0
|
|
||||||
tags: |
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: build rootful docker image
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
|
||||||
docker-rootless:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: docker/setup-qemu-action@v3
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- uses: docker/metadata-action@v5
|
|
||||||
id: meta
|
|
||||||
with:
|
|
||||||
images: gitea/gitea
|
|
||||||
# each tag below will have the suffix of -rootless
|
|
||||||
flavor: |
|
|
||||||
latest=false
|
|
||||||
suffix=-rootless
|
|
||||||
# 1.2.3-rc0
|
|
||||||
tags: |
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: build rootless docker image
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
file: Dockerfile.rootless
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
|
143
.github/workflows/release-tag-version.yml
vendored
143
.github/workflows/release-tag-version.yml
vendored
|
@ -1,143 +0,0 @@
|
||||||
name: release-tag-version
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- "v1.*"
|
|
||||||
- "!v1*-rc*"
|
|
||||||
- "!v1*-dev"
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
binary:
|
|
||||||
runs-on: nscloud
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: go.mod
|
|
||||||
check-latest: true
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- run: make deps-frontend deps-backend
|
|
||||||
# xgo build
|
|
||||||
- run: make release
|
|
||||||
env:
|
|
||||||
TAGS: bindata sqlite sqlite_unlock_notify
|
|
||||||
- name: import gpg key
|
|
||||||
id: import_gpg
|
|
||||||
uses: crazy-max/ghaction-import-gpg@v6
|
|
||||||
with:
|
|
||||||
gpg_private_key: ${{ secrets.GPGSIGN_KEY }}
|
|
||||||
passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }}
|
|
||||||
- name: sign binaries
|
|
||||||
run: |
|
|
||||||
for f in dist/release/*; do
|
|
||||||
echo '${{ secrets.GPGSIGN_PASSPHRASE }}' | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --yes --detach-sign -u ${{ steps.import_gpg.outputs.fingerprint }} --output "$f.asc" "$f"
|
|
||||||
done
|
|
||||||
# clean branch name to get the folder name in S3
|
|
||||||
- name: Get cleaned branch name
|
|
||||||
id: clean_name
|
|
||||||
run: |
|
|
||||||
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\/v//' -e 's/release\/v//')
|
|
||||||
echo "Cleaned name is ${REF_NAME}"
|
|
||||||
echo "branch=${REF_NAME}" >> "$GITHUB_OUTPUT"
|
|
||||||
- name: configure aws
|
|
||||||
uses: aws-actions/configure-aws-credentials@v4
|
|
||||||
with:
|
|
||||||
aws-region: ${{ secrets.AWS_REGION }}
|
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
||||||
- name: upload binaries to s3
|
|
||||||
run: |
|
|
||||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
|
||||||
- name: Install GH CLI
|
|
||||||
uses: dev-hanz-ops/install-gh-cli-action@v0.1.0
|
|
||||||
with:
|
|
||||||
gh-cli-version: 2.39.1
|
|
||||||
- name: create github release
|
|
||||||
run: |
|
|
||||||
gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --notes-from-tag dist/release/*
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
||||||
docker-rootful:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: docker/setup-qemu-action@v3
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- uses: docker/metadata-action@v5
|
|
||||||
id: meta
|
|
||||||
with:
|
|
||||||
images: gitea/gitea
|
|
||||||
# this will generate tags in the following format:
|
|
||||||
# latest
|
|
||||||
# 1
|
|
||||||
# 1.2
|
|
||||||
# 1.2.3
|
|
||||||
tags: |
|
|
||||||
type=semver,pattern={{major}}
|
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: build rootful docker image
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
|
||||||
docker-rootless:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
|
||||||
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
|
|
||||||
- run: git fetch --unshallow --quiet --tags --force
|
|
||||||
- uses: docker/setup-qemu-action@v3
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
- uses: docker/metadata-action@v5
|
|
||||||
id: meta
|
|
||||||
with:
|
|
||||||
images: gitea/gitea
|
|
||||||
# each tag below will have the suffix of -rootless
|
|
||||||
flavor: |
|
|
||||||
suffix=-rootless,onlatest=true
|
|
||||||
# this will generate tags in the following format (with -rootless suffix added):
|
|
||||||
# latest
|
|
||||||
# 1
|
|
||||||
# 1.2
|
|
||||||
# 1.2.3
|
|
||||||
tags: |
|
|
||||||
type=semver,pattern={{major}}
|
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: build rootless docker image
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
file: Dockerfile.rootless
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
|
|
@ -50,6 +50,6 @@ func runGenerateActionsRunnerToken(c *cli.Context) error {
|
||||||
if extra.HasError() {
|
if extra.HasError() {
|
||||||
return handleCliResponseExtra(extra)
|
return handleCliResponseExtra(extra)
|
||||||
}
|
}
|
||||||
_, _ = fmt.Printf("%s\n", respText)
|
_, _ = fmt.Printf("%s\n", respText.Text)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,9 @@ import (
|
||||||
"code.gitea.io/gitea/models/migrations"
|
"code.gitea.io/gitea/models/migrations"
|
||||||
migrate_base "code.gitea.io/gitea/models/migrations/base"
|
migrate_base "code.gitea.io/gitea/models/migrations/base"
|
||||||
"code.gitea.io/gitea/modules/container"
|
"code.gitea.io/gitea/modules/container"
|
||||||
"code.gitea.io/gitea/modules/doctor"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/services/doctor"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/doctor"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/services/doctor"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
|
|
@ -78,6 +78,6 @@ func runKeys(c *cli.Context) error {
|
||||||
if extra.Error != nil {
|
if extra.Error != nil {
|
||||||
return extra.Error
|
return extra.Error
|
||||||
}
|
}
|
||||||
_, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString))
|
_, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString.Text))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,6 @@ func runSendMail(c *cli.Context) error {
|
||||||
if extra.HasError() {
|
if extra.HasError() {
|
||||||
return handleCliResponseExtra(extra)
|
return handleCliResponseExtra(extra)
|
||||||
}
|
}
|
||||||
_, _ = fmt.Printf("Sent %s email(s) to all users\n", respText)
|
_, _ = fmt.Printf("Sent %s email(s) to all users\n", respText.Text)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,9 @@ func migrateLFS(ctx context.Context, dstStorage storage.ObjectStorage) error {
|
||||||
|
|
||||||
func migrateAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error {
|
func migrateAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error {
|
||||||
return db.Iterate(ctx, nil, func(ctx context.Context, user *user_model.User) error {
|
return db.Iterate(ctx, nil, func(ctx context.Context, user *user_model.User) error {
|
||||||
|
if user.CustomAvatarRelativePath() == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
_, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath())
|
_, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath())
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
@ -117,6 +120,9 @@ func migrateAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error
|
||||||
|
|
||||||
func migrateRepoAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error {
|
func migrateRepoAvatars(ctx context.Context, dstStorage storage.ObjectStorage) error {
|
||||||
return db.Iterate(ctx, nil, func(ctx context.Context, repo *repo_model.Repository) error {
|
return db.Iterate(ctx, nil, func(ctx context.Context, repo *repo_model.Repository) error {
|
||||||
|
if repo.CustomAvatarRelativePath() == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
_, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath())
|
_, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath())
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|
|
@ -1067,6 +1067,9 @@ LEVEL = Info
|
||||||
;;
|
;;
|
||||||
;; In addition to testing patches using the three-way merge method, re-test conflicting patches with git apply
|
;; In addition to testing patches using the three-way merge method, re-test conflicting patches with git apply
|
||||||
;TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY = false
|
;TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY = false
|
||||||
|
;;
|
||||||
|
;; Retarget child pull requests to the parent pull request branch target on merge of parent pull request. It only works on merged PRs where the head and base branch target the same repo.
|
||||||
|
;RETARGET_CHILDREN_ON_MERGE = true
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -135,6 +135,7 @@ In addition, there is _`StaticRootPath`_ which can be set as a built-in at build
|
||||||
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request.
|
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request.
|
||||||
- `ADD_CO_COMMITTER_TRAILERS`: **true**: Add co-authored-by and co-committed-by trailers to merge commit messages if committer does not match author.
|
- `ADD_CO_COMMITTER_TRAILERS`: **true**: Add co-authored-by and co-committed-by trailers to merge commit messages if committer does not match author.
|
||||||
- `TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY`: **false**: PR patches are tested using a three-way merge method to discover if there are conflicts. If this setting is set to **true**, conflicting patches will be retested using `git apply` - This was the previous behaviour in 1.18 (and earlier) but is somewhat inefficient. Please report if you find that this setting is required.
|
- `TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY`: **false**: PR patches are tested using a three-way merge method to discover if there are conflicts. If this setting is set to **true**, conflicting patches will be retested using `git apply` - This was the previous behaviour in 1.18 (and earlier) but is somewhat inefficient. Please report if you find that this setting is required.
|
||||||
|
- `RETARGET_CHILDREN_ON_MERGE`: **true**: Retarget child pull requests to the parent pull request branch target on merge of parent pull request. It only works on merged PRs where the head and base branch target the same repo.
|
||||||
|
|
||||||
### Repository - Issue (`repository.issue`)
|
### Repository - Issue (`repository.issue`)
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,15 @@ GITEA_CUSTOM=/home/gitea/custom ./gitea web
|
||||||
|
|
||||||
## From Go language
|
## From Go language
|
||||||
|
|
||||||
As Gitea is written in Go, it uses some Go variables, such as:
|
As Gitea is written in Go, it uses some variables that influence the behaviour of Go's runtime, such as:
|
||||||
|
|
||||||
- `GOOS`
|
- `GOMEMLIMIT`
|
||||||
- `GOARCH`
|
- `GOGC`
|
||||||
- [`GOPATH`](https://golang.org/cmd/go/#hdr-GOPATH_environment_variable)
|
- `GOMAXPROCS`
|
||||||
|
- `GODEBUG`
|
||||||
|
|
||||||
For documentation about each of the variables available, refer to the
|
For documentation about each of the variables available, refer to the
|
||||||
[official Go documentation](https://golang.org/cmd/go/#hdr-Environment_variables).
|
[official Go documentation on runtime environment variables](https://pkg.go.dev/runtime#hdr-Environment_Variables).
|
||||||
|
|
||||||
## Gitea files
|
## Gitea files
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ _Symbols used in table:_
|
||||||
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Markdown support | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ✘ | ✘ |
|
| CSV support | ✓ | ✘ | ✓ | ✘ | ✘ | ✓ | ✘ | ✘ |
|
||||||
| 'GitHub / GitLab pages' | [⚙️][gitea-pages-server], [⚙️][gitea-caddy-plugin] | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | ✘ |
|
| 'GitHub / GitLab pages' | [⚙️][gitea-pages-server], [⚙️][gitea-caddy-plugin] | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | ✘ |
|
||||||
|
| Gists / Snippets | [⚙️][opengist] | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Repo-specific wiki (as a repo itself) | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ | ✘ |
|
| Repo-specific wiki (as a repo itself) | ✓ | ✓ | ✓ | ✓ | ✓ | / | ✘ | ✘ |
|
||||||
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Deploy Tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
| Repository Tokens with write rights | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
@ -147,3 +148,4 @@ _Symbols used in table:_
|
||||||
|
|
||||||
[gitea-caddy-plugin]: https://github.com/42wim/caddy-gitea
|
[gitea-caddy-plugin]: https://github.com/42wim/caddy-gitea
|
||||||
[gitea-pages-server]: https://codeberg.org/Codeberg/pages-server
|
[gitea-pages-server]: https://codeberg.org/Codeberg/pages-server
|
||||||
|
[opengist]: https://github.com/thomiceli/opengist
|
||||||
|
|
|
@ -24,16 +24,26 @@ The following examples use `dnf`.
|
||||||
|
|
||||||
## Configuring the package registry
|
## Configuring the package registry
|
||||||
|
|
||||||
To register the RPM registry add the url to the list of known apt sources:
|
To register the RPM registry add the url to the list of known sources:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
dnf config-manager --add-repo https://gitea.example.com/api/packages/{owner}/rpm/{group}.repo
|
dnf config-manager --add-repo https://gitea.example.com/api/packages/{owner}/rpm/{group}.repo
|
||||||
```
|
```
|
||||||
|
|
||||||
| Placeholder | Description |
|
| Placeholder | Description |
|
||||||
| ----------- |----------------------------------------------------|
|
| ----------- | ----------- |
|
||||||
| `owner` | The owner of the package. |
|
| `owner` | The owner of the package. |
|
||||||
| `group` | Everything, e.g. `el7`, `rocky/el9` , `test/fc38`.|
|
| `group` | Optional: Everything, e.g. empty, `el7`, `rocky/el9`, `test/fc38`. |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# without a group
|
||||||
|
dnf config-manager --add-repo https://gitea.example.com/api/packages/testuser/rpm.repo
|
||||||
|
|
||||||
|
# with the group 'centos/el7'
|
||||||
|
dnf config-manager --add-repo https://gitea.example.com/api/packages/testuser/rpm/centos/el7.repo
|
||||||
|
```
|
||||||
|
|
||||||
If the registry is private, provide credentials in the url. You can use a password or a [personal access token](development/api-usage.md#authentication):
|
If the registry is private, provide credentials in the url. You can use a password or a [personal access token](development/api-usage.md#authentication):
|
||||||
|
|
||||||
|
@ -41,7 +51,7 @@ If the registry is private, provide credentials in the url. You can use a passwo
|
||||||
dnf config-manager --add-repo https://{username}:{your_password_or_token}@gitea.example.com/api/packages/{owner}/rpm/{group}.repo
|
dnf config-manager --add-repo https://{username}:{your_password_or_token}@gitea.example.com/api/packages/{owner}/rpm/{group}.repo
|
||||||
```
|
```
|
||||||
|
|
||||||
You have to add the credentials to the urls in the `rpm.repo` file in `/etc/yum.repos.d` too.
|
You have to add the credentials to the urls in the created `.repo` file in `/etc/yum.repos.d` too.
|
||||||
|
|
||||||
## Publish a package
|
## Publish a package
|
||||||
|
|
||||||
|
@ -54,11 +64,17 @@ PUT https://gitea.example.com/api/packages/{owner}/rpm/{group}/upload
|
||||||
| Parameter | Description |
|
| Parameter | Description |
|
||||||
| --------- | ----------- |
|
| --------- | ----------- |
|
||||||
| `owner` | The owner of the package. |
|
| `owner` | The owner of the package. |
|
||||||
| `group` | Everything, e.g. `el7`, `rocky/el9` , `test/fc38`.|
|
| `group` | Optional: Everything, e.g. empty, `el7`, `rocky/el9`, `test/fc38`. |
|
||||||
|
|
||||||
Example request using HTTP Basic authentication:
|
Example request using HTTP Basic authentication:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
# without a group
|
||||||
|
curl --user your_username:your_password_or_token \
|
||||||
|
--upload-file path/to/file.rpm \
|
||||||
|
https://gitea.example.com/api/packages/testuser/rpm/upload
|
||||||
|
|
||||||
|
# with the group 'centos/el7'
|
||||||
curl --user your_username:your_password_or_token \
|
curl --user your_username:your_password_or_token \
|
||||||
--upload-file path/to/file.rpm \
|
--upload-file path/to/file.rpm \
|
||||||
https://gitea.example.com/api/packages/testuser/rpm/centos/el7/upload
|
https://gitea.example.com/api/packages/testuser/rpm/centos/el7/upload
|
||||||
|
@ -83,17 +99,22 @@ To delete an RPM package perform a HTTP DELETE operation. This will delete the p
|
||||||
DELETE https://gitea.example.com/api/packages/{owner}/rpm/{group}/package/{package_name}/{package_version}/{architecture}
|
DELETE https://gitea.example.com/api/packages/{owner}/rpm/{group}/package/{package_name}/{package_version}/{architecture}
|
||||||
```
|
```
|
||||||
|
|
||||||
| Parameter | Description |
|
| Parameter | Description |
|
||||||
|-------------------|----------------------------|
|
| ----------------- | ----------- |
|
||||||
| `owner` | The owner of the package. |
|
| `owner` | The owner of the package. |
|
||||||
| `group` | The package group . |
|
| `group` | Optional: The package group. |
|
||||||
| `package_name` | The package name. |
|
| `package_name` | The package name. |
|
||||||
| `package_version` | The package version. |
|
| `package_version` | The package version. |
|
||||||
| `architecture` | The package architecture. |
|
| `architecture` | The package architecture. |
|
||||||
|
|
||||||
Example request using HTTP Basic authentication:
|
Example request using HTTP Basic authentication:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
# without a group
|
||||||
|
curl --user your_username:your_token_or_password -X DELETE \
|
||||||
|
https://gitea.example.com/api/packages/testuser/rpm/package/test-package/1.0.0/x86_64
|
||||||
|
|
||||||
|
# with the group 'centos/el7'
|
||||||
curl --user your_username:your_token_or_password -X DELETE \
|
curl --user your_username:your_token_or_password -X DELETE \
|
||||||
https://gitea.example.com/api/packages/testuser/rpm/centos/el7/package/test-package/1.0.0/x86_64
|
https://gitea.example.com/api/packages/testuser/rpm/centos/el7/package/test-package/1.0.0/x86_64
|
||||||
```
|
```
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -306,6 +306,8 @@ replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142
|
||||||
|
|
||||||
replace github.com/nektos/act => gitea.com/gitea/act v0.2.51
|
replace github.com/nektos/act => gitea.com/gitea/act v0.2.51
|
||||||
|
|
||||||
|
replace github.com/gorilla/feeds => github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5
|
||||||
|
|
||||||
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||||
|
|
||||||
exclude github.com/gofrs/uuid v4.0.0+incompatible
|
exclude github.com/gofrs/uuid v4.0.0+incompatible
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -501,8 +501,6 @@ github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8
|
||||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||||
github.com/gorilla/feeds v1.1.2 h1:pxzZ5PD3RJdhFH2FsJJ4x6PqMqbgFk1+Vez4XWBW8Iw=
|
|
||||||
github.com/gorilla/feeds v1.1.2/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
|
|
||||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
@ -904,6 +902,8 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMx
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
|
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
|
||||||
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||||
|
github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5 h1:3seWKGVhGoc66Ht5QlhQsr4xT2caDnFegsnh2NqvENU=
|
||||||
|
github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
|
||||||
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
|
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
|
||||||
github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
|
github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||||
|
|
|
@ -46,10 +46,13 @@ type ActionRun struct {
|
||||||
TriggerEvent string // the trigger event defined in the `on` configuration of the triggered workflow
|
TriggerEvent string // the trigger event defined in the `on` configuration of the triggered workflow
|
||||||
Status Status `xorm:"index"`
|
Status Status `xorm:"index"`
|
||||||
Version int `xorm:"version default 0"` // Status could be updated concomitantly, so an optimistic lock is needed
|
Version int `xorm:"version default 0"` // Status could be updated concomitantly, so an optimistic lock is needed
|
||||||
Started timeutil.TimeStamp
|
// Started and Stopped is used for recording last run time, if rerun happened, they will be reset to 0
|
||||||
Stopped timeutil.TimeStamp
|
Started timeutil.TimeStamp
|
||||||
Created timeutil.TimeStamp `xorm:"created"`
|
Stopped timeutil.TimeStamp
|
||||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
// PreviousDuration is used for recording previous duration
|
||||||
|
PreviousDuration time.Duration
|
||||||
|
Created timeutil.TimeStamp `xorm:"created"`
|
||||||
|
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -118,7 +121,7 @@ func (run *ActionRun) LoadAttributes(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (run *ActionRun) Duration() time.Duration {
|
func (run *ActionRun) Duration() time.Duration {
|
||||||
return calculateDuration(run.Started, run.Stopped, run.Status)
|
return calculateDuration(run.Started, run.Stopped, run.Status) + run.PreviousDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (run *ActionRun) GetPushEventPayload() (*api.PushPayload, error) {
|
func (run *ActionRun) GetPushEventPayload() (*api.PushPayload, error) {
|
||||||
|
|
|
@ -669,3 +669,10 @@
|
||||||
type: 10
|
type: 10
|
||||||
config: "{}"
|
config: "{}"
|
||||||
created_unix: 946684810
|
created_unix: 946684810
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 101
|
||||||
|
repo_id: 59
|
||||||
|
type: 1
|
||||||
|
config: "{}"
|
||||||
|
created_unix: 946684810
|
||||||
|
|
|
@ -1693,3 +1693,16 @@
|
||||||
size: 0
|
size: 0
|
||||||
is_fsck_enabled: true
|
is_fsck_enabled: true
|
||||||
close_issues_via_commit_in_any_branch: false
|
close_issues_via_commit_in_any_branch: false
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 59
|
||||||
|
owner_id: 2
|
||||||
|
owner_name: user2
|
||||||
|
lower_name: test_commit_revert
|
||||||
|
name: test_commit_revert
|
||||||
|
default_branch: main
|
||||||
|
is_empty: false
|
||||||
|
is_archived: false
|
||||||
|
is_private: true
|
||||||
|
status: 0
|
||||||
|
num_issues: 0
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
num_followers: 2
|
num_followers: 2
|
||||||
num_following: 1
|
num_following: 1
|
||||||
num_stars: 2
|
num_stars: 2
|
||||||
num_repos: 14
|
num_repos: 15
|
||||||
num_teams: 0
|
num_teams: 0
|
||||||
num_members: 0
|
num_members: 0
|
||||||
visibility: 0
|
visibility: 0
|
||||||
|
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"code.gitea.io/gitea/modules/translation"
|
"code.gitea.io/gitea/modules/translation"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CommitStatus holds a single Status of a single Commit
|
// CommitStatus holds a single Status of a single Commit
|
||||||
|
@ -38,7 +37,7 @@ type CommitStatus struct {
|
||||||
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
|
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
|
||||||
TargetURL string `xorm:"TEXT"`
|
TargetURL string `xorm:"TEXT"`
|
||||||
Description string `xorm:"TEXT"`
|
Description string `xorm:"TEXT"`
|
||||||
ContextHash string `xorm:"char(40) index"`
|
ContextHash string `xorm:"VARCHAR(64) index"`
|
||||||
Context string `xorm:"TEXT"`
|
Context string `xorm:"TEXT"`
|
||||||
Creator *user_model.User `xorm:"-"`
|
Creator *user_model.User `xorm:"-"`
|
||||||
CreatorID int64
|
CreatorID int64
|
||||||
|
@ -221,57 +220,42 @@ func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus {
|
||||||
// CommitStatusOptions holds the options for query commit statuses
|
// CommitStatusOptions holds the options for query commit statuses
|
||||||
type CommitStatusOptions struct {
|
type CommitStatusOptions struct {
|
||||||
db.ListOptions
|
db.ListOptions
|
||||||
|
RepoID int64
|
||||||
|
SHA string
|
||||||
State string
|
State string
|
||||||
SortType string
|
SortType string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommitStatuses returns all statuses for a given commit.
|
func (opts *CommitStatusOptions) ToConds() builder.Cond {
|
||||||
func GetCommitStatuses(ctx context.Context, repo *repo_model.Repository, sha string, opts *CommitStatusOptions) ([]*CommitStatus, int64, error) {
|
var cond builder.Cond = builder.Eq{
|
||||||
if opts.Page <= 0 {
|
"repo_id": opts.RepoID,
|
||||||
opts.Page = 1
|
"sha": opts.SHA,
|
||||||
}
|
|
||||||
if opts.PageSize <= 0 {
|
|
||||||
opts.Page = setting.ItemsPerPage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
countSession := listCommitStatusesStatement(ctx, repo, sha, opts)
|
|
||||||
countSession = db.SetSessionPagination(countSession, opts)
|
|
||||||
maxResults, err := countSession.Count(new(CommitStatus))
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Count PRs: %v", err)
|
|
||||||
return nil, maxResults, err
|
|
||||||
}
|
|
||||||
|
|
||||||
statuses := make([]*CommitStatus, 0, opts.PageSize)
|
|
||||||
findSession := listCommitStatusesStatement(ctx, repo, sha, opts)
|
|
||||||
findSession = db.SetSessionPagination(findSession, opts)
|
|
||||||
sortCommitStatusesSession(findSession, opts.SortType)
|
|
||||||
return statuses, maxResults, findSession.Find(&statuses)
|
|
||||||
}
|
|
||||||
|
|
||||||
func listCommitStatusesStatement(ctx context.Context, repo *repo_model.Repository, sha string, opts *CommitStatusOptions) *xorm.Session {
|
|
||||||
sess := db.GetEngine(ctx).Where("repo_id = ?", repo.ID).And("sha = ?", sha)
|
|
||||||
switch opts.State {
|
switch opts.State {
|
||||||
case "pending", "success", "error", "failure", "warning":
|
case "pending", "success", "error", "failure", "warning":
|
||||||
sess.And("state = ?", opts.State)
|
cond = cond.And(builder.Eq{
|
||||||
|
"state": opts.State,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return sess
|
|
||||||
|
return cond
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortCommitStatusesSession(sess *xorm.Session, sortType string) {
|
func (opts *CommitStatusOptions) ToOrders() string {
|
||||||
switch sortType {
|
switch opts.SortType {
|
||||||
case "oldest":
|
case "oldest":
|
||||||
sess.Asc("created_unix")
|
return "created_unix ASC"
|
||||||
case "recentupdate":
|
case "recentupdate":
|
||||||
sess.Desc("updated_unix")
|
return "updated_unix DESC"
|
||||||
case "leastupdate":
|
case "leastupdate":
|
||||||
sess.Asc("updated_unix")
|
return "updated_unix ASC"
|
||||||
case "leastindex":
|
case "leastindex":
|
||||||
sess.Desc("index")
|
return "`index` DESC"
|
||||||
case "highestindex":
|
case "highestindex":
|
||||||
sess.Asc("index")
|
return "`index` ASC"
|
||||||
default:
|
default:
|
||||||
sess.Desc("created_unix")
|
return "created_unix DESC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,11 @@ func TestGetCommitStatuses(t *testing.T) {
|
||||||
|
|
||||||
sha1 := "1234123412341234123412341234123412341234"
|
sha1 := "1234123412341234123412341234123412341234"
|
||||||
|
|
||||||
statuses, maxResults, err := git_model.GetCommitStatuses(db.DefaultContext, repo1, sha1, &git_model.CommitStatusOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 50}})
|
statuses, maxResults, err := db.FindAndCount[git_model.CommitStatus](db.DefaultContext, &git_model.CommitStatusOptions{
|
||||||
|
ListOptions: db.ListOptions{Page: 1, PageSize: 50},
|
||||||
|
RepoID: repo1.ID,
|
||||||
|
SHA: sha1,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, int(maxResults), 5)
|
assert.Equal(t, int(maxResults), 5)
|
||||||
assert.Len(t, statuses, 5)
|
assert.Len(t, statuses, 5)
|
||||||
|
@ -46,4 +50,128 @@ func TestGetCommitStatuses(t *testing.T) {
|
||||||
assert.Equal(t, "deploy/awesomeness", statuses[4].Context)
|
assert.Equal(t, "deploy/awesomeness", statuses[4].Context)
|
||||||
assert.Equal(t, structs.CommitStatusError, statuses[4].State)
|
assert.Equal(t, structs.CommitStatusError, statuses[4].State)
|
||||||
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL(db.DefaultContext))
|
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL(db.DefaultContext))
|
||||||
|
|
||||||
|
statuses, maxResults, err = db.FindAndCount[git_model.CommitStatus](db.DefaultContext, &git_model.CommitStatusOptions{
|
||||||
|
ListOptions: db.ListOptions{Page: 2, PageSize: 50},
|
||||||
|
RepoID: repo1.ID,
|
||||||
|
SHA: sha1,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int(maxResults), 5)
|
||||||
|
assert.Empty(t, statuses)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_CalcCommitStatus(t *testing.T) {
|
||||||
|
kases := []struct {
|
||||||
|
statuses []*git_model.CommitStatus
|
||||||
|
expected *git_model.CommitStatus
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
statuses: []*git_model.CommitStatus{
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statuses: []*git_model.CommitStatus{
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statuses: []*git_model.CommitStatus{
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statuses: []*git_model.CommitStatus{
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusError,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statuses: []*git_model.CommitStatus{
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusWarning,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusPending,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusWarning,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statuses: []*git_model.CommitStatus{
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
statuses: []*git_model.CommitStatus{
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusFailure,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: structs.CommitStatusWarning,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusError,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kase := range kases {
|
||||||
|
assert.Equal(t, kase.expected, git_model.CalcCommitStatus(kase.statuses))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,7 +270,7 @@ type Comment struct {
|
||||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||||
|
|
||||||
// Reference issue in commit message
|
// Reference issue in commit message
|
||||||
CommitSHA string `xorm:"VARCHAR(40)"`
|
CommitSHA string `xorm:"VARCHAR(64)"`
|
||||||
|
|
||||||
Attachments []*repo_model.Attachment `xorm:"-"`
|
Attachments []*repo_model.Attachment `xorm:"-"`
|
||||||
Reactions ReactionList `xorm:"-"`
|
Reactions ReactionList `xorm:"-"`
|
||||||
|
|
|
@ -171,11 +171,11 @@ type PullRequest struct {
|
||||||
HeadBranch string
|
HeadBranch string
|
||||||
HeadCommitID string `xorm:"-"`
|
HeadCommitID string `xorm:"-"`
|
||||||
BaseBranch string
|
BaseBranch string
|
||||||
MergeBase string `xorm:"VARCHAR(40)"`
|
MergeBase string `xorm:"VARCHAR(64)"`
|
||||||
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
|
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
|
|
||||||
HasMerged bool `xorm:"INDEX"`
|
HasMerged bool `xorm:"INDEX"`
|
||||||
MergedCommitID string `xorm:"VARCHAR(40)"`
|
MergedCommitID string `xorm:"VARCHAR(64)"`
|
||||||
MergerID int64 `xorm:"INDEX"`
|
MergerID int64 `xorm:"INDEX"`
|
||||||
Merger *user_model.User `xorm:"-"`
|
Merger *user_model.User `xorm:"-"`
|
||||||
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
|
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
|
||||||
|
|
|
@ -116,7 +116,7 @@ type Review struct {
|
||||||
Content string `xorm:"TEXT"`
|
Content string `xorm:"TEXT"`
|
||||||
// Official is a review made by an assigned approver (counts towards approval)
|
// Official is a review made by an assigned approver (counts towards approval)
|
||||||
Official bool `xorm:"NOT NULL DEFAULT false"`
|
Official bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
CommitID string `xorm:"VARCHAR(40)"`
|
CommitID string `xorm:"VARCHAR(64)"`
|
||||||
Stale bool `xorm:"NOT NULL DEFAULT false"`
|
Stale bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
Dismissed bool `xorm:"NOT NULL DEFAULT false"`
|
Dismissed bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
|
|
||||||
|
|
|
@ -340,7 +340,7 @@ func GetTrackedTimeByID(ctx context.Context, id int64) (*TrackedTime, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIssueTotalTrackedTime returns the total tracked time for issues by given conditions.
|
// GetIssueTotalTrackedTime returns the total tracked time for issues by given conditions.
|
||||||
func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed bool) (int64, error) {
|
func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed util.OptionalBool) (int64, error) {
|
||||||
if len(opts.IssueIDs) <= MaxQueryParameters {
|
if len(opts.IssueIDs) <= MaxQueryParameters {
|
||||||
return getIssueTotalTrackedTimeChunk(ctx, opts, isClosed, opts.IssueIDs)
|
return getIssueTotalTrackedTimeChunk(ctx, opts, isClosed, opts.IssueIDs)
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,7 @@ func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed
|
||||||
return accum, nil
|
return accum, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isClosed bool, issueIDs []int64) (int64, error) {
|
func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isClosed util.OptionalBool, issueIDs []int64) (int64, error) {
|
||||||
sumSession := func(opts *IssuesOptions, issueIDs []int64) *xorm.Session {
|
sumSession := func(opts *IssuesOptions, issueIDs []int64) *xorm.Session {
|
||||||
sess := db.GetEngine(ctx).
|
sess := db.GetEngine(ctx).
|
||||||
Table("tracked_time").
|
Table("tracked_time").
|
||||||
|
@ -377,7 +377,9 @@ func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isC
|
||||||
Time int64
|
Time int64
|
||||||
}
|
}
|
||||||
|
|
||||||
return sumSession(opts, issueIDs).
|
session := sumSession(opts, issueIDs)
|
||||||
And("issue.is_closed = ?", isClosed).
|
if !isClosed.IsNone() {
|
||||||
SumInt(new(trackedTime), "tracked_time.time")
|
session = session.And("issue.is_closed = ?", isClosed.IsTrue())
|
||||||
|
}
|
||||||
|
return session.SumInt(new(trackedTime), "tracked_time.time")
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -119,11 +120,15 @@ func TestTotalTimesForEachUser(t *testing.T) {
|
||||||
func TestGetIssueTotalTrackedTime(t *testing.T) {
|
func TestGetIssueTotalTrackedTime(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
|
||||||
ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, false)
|
ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolFalse)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 3682, ttt)
|
assert.EqualValues(t, 3682, ttt)
|
||||||
|
|
||||||
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, true)
|
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolTrue)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 0, ttt)
|
assert.EqualValues(t, 0, ttt)
|
||||||
|
|
||||||
|
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolNone)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 3682, ttt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# type Repository struct {
|
||||||
|
# ID int64 `xorm:"pk autoincr"`
|
||||||
|
# }
|
||||||
|
-
|
||||||
|
id: 1
|
||||||
|
-
|
||||||
|
id: 2
|
||||||
|
-
|
||||||
|
id: 3
|
||||||
|
-
|
||||||
|
id: 10
|
|
@ -552,6 +552,12 @@ var migrations = []Migration{
|
||||||
NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID),
|
NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID),
|
||||||
// v283 -> v284
|
// v283 -> v284
|
||||||
NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
|
NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
|
||||||
|
// v284 -> v285
|
||||||
|
NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
|
||||||
|
// v285 -> v286
|
||||||
|
NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun),
|
||||||
|
// v286 -> v287
|
||||||
|
NewMigration("Add support for SHA256 git repositories", v1_22.AdjustDBForSha256),
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentDBVersion returns the current db version
|
// GetCurrentDBVersion returns the current db version
|
||||||
|
|
18
models/migrations/v1_22/v285.go
Normal file
18
models/migrations/v1_22/v285.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1_22 //nolint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddPreviousDurationToActionRun(x *xorm.Engine) error {
|
||||||
|
type ActionRun struct {
|
||||||
|
PreviousDuration time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.Sync(&ActionRun{})
|
||||||
|
}
|
104
models/migrations/v1_22/v286.go
Normal file
104
models/migrations/v1_22/v286.go
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
package v1_22 //nolint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func expandHashReferencesToSha256(x *xorm.Engine) error {
|
||||||
|
alteredTables := [][2]string{
|
||||||
|
{"commit_status", "context_hash"},
|
||||||
|
{"comment", "commit_sha"},
|
||||||
|
{"pull_request", "merge_base"},
|
||||||
|
{"pull_request", "merged_commit_id"},
|
||||||
|
{"review", "commit_id"},
|
||||||
|
{"review_state", "commit_sha"},
|
||||||
|
{"repo_archiver", "commit_id"},
|
||||||
|
{"release", "sha1"},
|
||||||
|
{"repo_indexer_status", "commit_sha"},
|
||||||
|
}
|
||||||
|
|
||||||
|
db := x.NewSession()
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
if err := db.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !setting.Database.Type.IsSQLite3() {
|
||||||
|
if setting.Database.Type.IsMSSQL() {
|
||||||
|
// drop indexes that need to be re-created afterwards
|
||||||
|
droppedIndexes := []string{
|
||||||
|
"DROP INDEX commit_status.IDX_commit_status_context_hash",
|
||||||
|
"DROP INDEX review_state.UQE_review_state_pull_commit_user",
|
||||||
|
"DROP INDEX repo_archiver.UQE_repo_archiver_s",
|
||||||
|
}
|
||||||
|
for _, s := range droppedIndexes {
|
||||||
|
_, err := db.Exec(s)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(s + " " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, alts := range alteredTables {
|
||||||
|
var err error
|
||||||
|
if setting.Database.Type.IsMySQL() {
|
||||||
|
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` MODIFY COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
|
||||||
|
} else if setting.Database.Type.IsMSSQL() {
|
||||||
|
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
|
||||||
|
} else {
|
||||||
|
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` TYPE VARCHAR(64)", alts[0], alts[1]))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("alter column '%s' of table '%s' failed: %w", alts[1], alts[0], err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if setting.Database.Type.IsMSSQL() {
|
||||||
|
recreateIndexes := []string{
|
||||||
|
"CREATE INDEX IDX_commit_status_context_hash ON commit_status(context_hash)",
|
||||||
|
"CREATE UNIQUE INDEX UQE_review_state_pull_commit_user ON review_state(user_id, pull_id, commit_sha)",
|
||||||
|
"CREATE UNIQUE INDEX UQE_repo_archiver_s ON repo_archiver(repo_id, type, commit_id)",
|
||||||
|
}
|
||||||
|
for _, s := range recreateIndexes {
|
||||||
|
_, err := db.Exec(s)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(s + " " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Debug("Updated database tables to hold SHA256 git hash references")
|
||||||
|
|
||||||
|
return db.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func addObjectFormatNameToRepository(x *xorm.Engine) error {
|
||||||
|
type Repository struct {
|
||||||
|
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.Sync(new(Repository)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here to catch weird edge-cases where column constraints above are
|
||||||
|
// not applied by the DB backend
|
||||||
|
_, err := x.Exec("UPDATE repository set object_format_name = 'sha1' WHERE object_format_name = '' or object_format_name IS NULL")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AdjustDBForSha256(x *xorm.Engine) error {
|
||||||
|
if err := expandHashReferencesToSha256(x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return addObjectFormatNameToRepository(x)
|
||||||
|
}
|
62
models/migrations/v1_22/v286_test.go
Normal file
62
models/migrations/v1_22/v286_test.go
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package v1_22 //nolint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/migrations/base"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PrepareOldRepository(t *testing.T) (*xorm.Engine, func()) {
|
||||||
|
type Repository struct { // old struct
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare and load the testing database
|
||||||
|
return base.PrepareTestEnv(t, 0, new(Repository))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_RepositoryFormat(t *testing.T) {
|
||||||
|
x, deferable := PrepareOldRepository(t)
|
||||||
|
defer deferable()
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
ObjectFormatName string `xorg:"not null default('sha1')"`
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := new(Repository)
|
||||||
|
|
||||||
|
// check we have some records to migrate
|
||||||
|
count, err := x.Count(new(Repository))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 4, count)
|
||||||
|
|
||||||
|
assert.NoError(t, AdjustDBForSha256(x))
|
||||||
|
|
||||||
|
repo.ID = 20
|
||||||
|
repo.ObjectFormatName = "sha256"
|
||||||
|
_, err = x.Insert(repo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
count, err = x.Count(new(Repository))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 5, count)
|
||||||
|
|
||||||
|
repo = new(Repository)
|
||||||
|
ok, err := x.ID(2).Get(repo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, true, ok)
|
||||||
|
assert.EqualValues(t, "sha1", repo.ObjectFormatName)
|
||||||
|
|
||||||
|
repo = new(Repository)
|
||||||
|
ok, err = x.ID(20).Get(repo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, true, ok)
|
||||||
|
assert.EqualValues(t, "sha256", repo.ObjectFormatName)
|
||||||
|
}
|
|
@ -191,18 +191,18 @@ type Package struct {
|
||||||
func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) {
|
func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) {
|
||||||
e := db.GetEngine(ctx)
|
e := db.GetEngine(ctx)
|
||||||
|
|
||||||
key := &Package{
|
existing := &Package{}
|
||||||
OwnerID: p.OwnerID,
|
|
||||||
Type: p.Type,
|
|
||||||
LowerName: p.LowerName,
|
|
||||||
}
|
|
||||||
|
|
||||||
has, err := e.Get(key)
|
has, err := e.Where(builder.Eq{
|
||||||
|
"owner_id": p.OwnerID,
|
||||||
|
"type": p.Type,
|
||||||
|
"lower_name": p.LowerName,
|
||||||
|
}).Get(existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if has {
|
if has {
|
||||||
return key, ErrDuplicatePackage
|
return existing, ErrDuplicatePackage
|
||||||
}
|
}
|
||||||
if _, err = e.Insert(p); err != nil {
|
if _, err = e.Insert(p); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -41,12 +41,20 @@ type PackageBlob struct {
|
||||||
func GetOrInsertBlob(ctx context.Context, pb *PackageBlob) (*PackageBlob, bool, error) {
|
func GetOrInsertBlob(ctx context.Context, pb *PackageBlob) (*PackageBlob, bool, error) {
|
||||||
e := db.GetEngine(ctx)
|
e := db.GetEngine(ctx)
|
||||||
|
|
||||||
has, err := e.Get(pb)
|
existing := &PackageBlob{}
|
||||||
|
|
||||||
|
has, err := e.Where(builder.Eq{
|
||||||
|
"size": pb.Size,
|
||||||
|
"hash_md5": pb.HashMD5,
|
||||||
|
"hash_sha1": pb.HashSHA1,
|
||||||
|
"hash_sha256": pb.HashSHA256,
|
||||||
|
"hash_sha512": pb.HashSHA512,
|
||||||
|
}).Get(existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
if has {
|
if has {
|
||||||
return pb, true, nil
|
return existing, true, nil
|
||||||
}
|
}
|
||||||
if _, err = e.Insert(pb); err != nil {
|
if _, err = e.Insert(pb); err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
|
|
|
@ -46,18 +46,18 @@ type PackageFile struct {
|
||||||
func TryInsertFile(ctx context.Context, pf *PackageFile) (*PackageFile, error) {
|
func TryInsertFile(ctx context.Context, pf *PackageFile) (*PackageFile, error) {
|
||||||
e := db.GetEngine(ctx)
|
e := db.GetEngine(ctx)
|
||||||
|
|
||||||
key := &PackageFile{
|
existing := &PackageFile{}
|
||||||
VersionID: pf.VersionID,
|
|
||||||
LowerName: pf.LowerName,
|
|
||||||
CompositeKey: pf.CompositeKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
has, err := e.Get(key)
|
has, err := e.Where(builder.Eq{
|
||||||
|
"version_id": pf.VersionID,
|
||||||
|
"lower_name": pf.LowerName,
|
||||||
|
"composite_key": pf.CompositeKey,
|
||||||
|
}).Get(existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if has {
|
if has {
|
||||||
return pf, ErrDuplicatePackageFile
|
return existing, ErrDuplicatePackageFile
|
||||||
}
|
}
|
||||||
if _, err = e.Insert(pf); err != nil {
|
if _, err = e.Insert(pf); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -93,13 +93,13 @@ func GetFileForVersionByName(ctx context.Context, versionID int64, name, key str
|
||||||
return nil, ErrPackageFileNotExist
|
return nil, ErrPackageFileNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
pf := &PackageFile{
|
pf := &PackageFile{}
|
||||||
VersionID: versionID,
|
|
||||||
LowerName: strings.ToLower(name),
|
|
||||||
CompositeKey: key,
|
|
||||||
}
|
|
||||||
|
|
||||||
has, err := db.GetEngine(ctx).Get(pf)
|
has, err := db.GetEngine(ctx).Where(builder.Eq{
|
||||||
|
"version_id": versionID,
|
||||||
|
"lower_name": strings.ToLower(name),
|
||||||
|
"composite_key": key,
|
||||||
|
}).Get(pf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,17 +39,17 @@ type PackageVersion struct {
|
||||||
func GetOrInsertVersion(ctx context.Context, pv *PackageVersion) (*PackageVersion, error) {
|
func GetOrInsertVersion(ctx context.Context, pv *PackageVersion) (*PackageVersion, error) {
|
||||||
e := db.GetEngine(ctx)
|
e := db.GetEngine(ctx)
|
||||||
|
|
||||||
key := &PackageVersion{
|
existing := &PackageVersion{}
|
||||||
PackageID: pv.PackageID,
|
|
||||||
LowerVersion: pv.LowerVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
has, err := e.Get(key)
|
has, err := e.Where(builder.Eq{
|
||||||
|
"package_id": pv.PackageID,
|
||||||
|
"lower_version": pv.LowerVersion,
|
||||||
|
}).Get(existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if has {
|
if has {
|
||||||
return key, ErrDuplicatePackageVersion
|
return existing, ErrDuplicatePackageVersion
|
||||||
}
|
}
|
||||||
if _, err = e.Insert(pv); err != nil {
|
if _, err = e.Insert(pv); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
23
models/packages/rpm/search.go
Normal file
23
models/packages/rpm/search.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package rpm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
packages_model "code.gitea.io/gitea/models/packages"
|
||||||
|
rpm_module "code.gitea.io/gitea/modules/packages/rpm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetGroups gets all available groups
|
||||||
|
func GetGroups(ctx context.Context, ownerID int64) ([]string, error) {
|
||||||
|
return packages_model.GetDistinctPropertyValues(
|
||||||
|
ctx,
|
||||||
|
packages_model.TypeRpm,
|
||||||
|
ownerID,
|
||||||
|
packages_model.PropertyTypeFile,
|
||||||
|
rpm_module.PropertyGroup,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ type ReviewState struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
|
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
|
||||||
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
|
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
|
||||||
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
|
CommitSHA string `xorm:"NOT NULL VARCHAR(64) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
|
||||||
UpdatedFiles map[string]ViewedState `xorm:"NOT NULL LONGTEXT JSON"` // Stores for each of the changed files of a PR whether they have been viewed, changed since last viewed, or not viewed
|
UpdatedFiles map[string]ViewedState `xorm:"NOT NULL LONGTEXT JSON"` // Stores for each of the changed files of a PR whether they have been viewed, changed since last viewed, or not viewed
|
||||||
UpdatedUnix timeutil.TimeStamp `xorm:"updated"` // Is an accurate indicator of the order of commits as we do not expect it to be possible to make reviews on previous commits
|
UpdatedUnix timeutil.TimeStamp `xorm:"updated"` // Is an accurate indicator of the order of commits as we do not expect it to be possible to make reviews on previous commits
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ type RepoArchiver struct { //revive:disable-line:exported
|
||||||
RepoID int64 `xorm:"index unique(s)"`
|
RepoID int64 `xorm:"index unique(s)"`
|
||||||
Type git.ArchiveType `xorm:"unique(s)"`
|
Type git.ArchiveType `xorm:"unique(s)"`
|
||||||
Status ArchiverStatus
|
Status ArchiverStatus
|
||||||
CommitID string `xorm:"VARCHAR(40) unique(s)"`
|
CommitID string `xorm:"VARCHAR(64) unique(s)"`
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ type Release struct {
|
||||||
Target string
|
Target string
|
||||||
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
|
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
|
||||||
Title string
|
Title string
|
||||||
Sha1 string `xorm:"VARCHAR(40)"`
|
Sha1 string `xorm:"VARCHAR(64)"`
|
||||||
NumCommits int64
|
NumCommits int64
|
||||||
NumCommitsBehind int64 `xorm:"-"`
|
NumCommitsBehind int64 `xorm:"-"`
|
||||||
Note string `xorm:"TEXT"`
|
Note string `xorm:"TEXT"`
|
||||||
|
|
|
@ -180,7 +180,7 @@ type Repository struct {
|
||||||
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
|
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
|
||||||
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
|
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
Topics []string `xorm:"TEXT JSON"`
|
Topics []string `xorm:"TEXT JSON"`
|
||||||
ObjectFormatName string `xorm:"-"`
|
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
|
||||||
|
|
||||||
TrustModel TrustModelType
|
TrustModel TrustModelType
|
||||||
|
|
||||||
|
@ -276,10 +276,6 @@ func (repo *Repository) AfterLoad() {
|
||||||
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
|
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
|
||||||
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
|
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
|
||||||
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
|
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
|
||||||
|
|
||||||
// this is a temporary behaviour to support old repos, next step is to store the object format in the database
|
|
||||||
// and read from database so this line could be removed. To not depend on git module, we use a constant variable here
|
|
||||||
repo.ObjectFormatName = "sha1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadAttributes loads attributes of the repository.
|
// LoadAttributes loads attributes of the repository.
|
||||||
|
|
|
@ -27,7 +27,7 @@ const (
|
||||||
type RepoIndexerStatus struct { //revive:disable-line:exported
|
type RepoIndexerStatus struct { //revive:disable-line:exported
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
RepoID int64 `xorm:"INDEX(s)"`
|
RepoID int64 `xorm:"INDEX(s)"`
|
||||||
CommitSha string `xorm:"VARCHAR(40)"`
|
CommitSha string `xorm:"VARCHAR(64)"`
|
||||||
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
|
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string, any))
|
||||||
}
|
}
|
||||||
|
|
||||||
func determineAccessMode(ctx *Base, pkg *Package, doer *user_model.User) (perm.AccessMode, error) {
|
func determineAccessMode(ctx *Base, pkg *Package, doer *user_model.User) (perm.AccessMode, error) {
|
||||||
if setting.Service.RequireSignInView && doer == nil {
|
if setting.Service.RequireSignInView && (doer == nil || doer.IsGhost()) {
|
||||||
return perm.AccessModeNone, nil
|
return perm.AccessModeNone, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
144
modules/git/blame_sha256_test.go
Normal file
144
modules/git/blame_sha256_test.go
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReadingBlameOutputSha256(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
|
||||||
|
repo, err := OpenRepository(ctx, "./tests/repos/repo5_pulls_sha256")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
|
commit, err := repo.GetCommit("0b69b7bb649b5d46e14cabb6468685e5dd721290acc7ffe604d37cde57927345")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
parts := []*BlamePart{
|
||||||
|
{
|
||||||
|
Sha: "1e35a51dc00fd7de730344c07061acfe80e8117e075ac979b6a29a3a045190ca",
|
||||||
|
Lines: []string{
|
||||||
|
"# test_repo",
|
||||||
|
"Test repository for testing migration from github to gitea",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sha: "0b69b7bb649b5d46e14cabb6468685e5dd721290acc7ffe604d37cde57927345",
|
||||||
|
Lines: []string{"", "Do not make any changes to this repo it is used for unit testing"},
|
||||||
|
PreviousSha: "1e35a51dc00fd7de730344c07061acfe80e8117e075ac979b6a29a3a045190ca",
|
||||||
|
PreviousPath: "README.md",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, bypass := range []bool{false, true} {
|
||||||
|
blameReader, err := CreateBlameReader(ctx, Sha256ObjectFormat, "./tests/repos/repo5_pulls_sha256", commit, "README.md", bypass)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, blameReader)
|
||||||
|
defer blameReader.Close()
|
||||||
|
|
||||||
|
assert.False(t, blameReader.UsesIgnoreRevs())
|
||||||
|
|
||||||
|
for _, part := range parts {
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, part, actualPart)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure all parts have been read
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.Nil(t, actualPart)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("With .git-blame-ignore-revs", func(t *testing.T) {
|
||||||
|
repo, err := OpenRepository(ctx, "./tests/repos/repo6_blame_sha256")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
|
full := []*BlamePart{
|
||||||
|
{
|
||||||
|
Sha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
Lines: []string{"line", "line"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sha: "9347b0198cd1f25017579b79d0938fa89dba34ad2514f0dd92f6bc975ed1a2fe",
|
||||||
|
Lines: []string{"changed line"},
|
||||||
|
PreviousSha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
PreviousPath: "blame.txt",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
Lines: []string{"line", "line", ""},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
CommitID string
|
||||||
|
UsesIgnoreRevs bool
|
||||||
|
Bypass bool
|
||||||
|
Parts []*BlamePart
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
CommitID: "e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3",
|
||||||
|
UsesIgnoreRevs: true,
|
||||||
|
Bypass: false,
|
||||||
|
Parts: []*BlamePart{
|
||||||
|
{
|
||||||
|
Sha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
Lines: []string{"line", "line", "changed line", "line", "line", ""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CommitID: "e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3",
|
||||||
|
UsesIgnoreRevs: false,
|
||||||
|
Bypass: true,
|
||||||
|
Parts: full,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CommitID: "9347b0198cd1f25017579b79d0938fa89dba34ad2514f0dd92f6bc975ed1a2fe",
|
||||||
|
UsesIgnoreRevs: false,
|
||||||
|
Bypass: false,
|
||||||
|
Parts: full,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CommitID: "9347b0198cd1f25017579b79d0938fa89dba34ad2514f0dd92f6bc975ed1a2fe",
|
||||||
|
UsesIgnoreRevs: false,
|
||||||
|
Bypass: false,
|
||||||
|
Parts: full,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
commit, err := repo.GetCommit(c.CommitID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
blameReader, err := CreateBlameReader(ctx, repo.objectFormat, "./tests/repos/repo6_blame_sha256", commit, "blame.txt", c.Bypass)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, blameReader)
|
||||||
|
defer blameReader.Close()
|
||||||
|
|
||||||
|
assert.Equal(t, c.UsesIgnoreRevs, blameReader.UsesIgnoreRevs())
|
||||||
|
|
||||||
|
for _, part := range c.Parts {
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, part, actualPart)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure all parts have been read
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.Nil(t, actualPart)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -85,6 +85,8 @@ readLoop:
|
||||||
commit.Committer.Decode(data)
|
commit.Committer.Decode(data)
|
||||||
_, _ = payloadSB.Write(line)
|
_, _ = payloadSB.Write(line)
|
||||||
case "gpgsig":
|
case "gpgsig":
|
||||||
|
fallthrough
|
||||||
|
case "gpgsig-sha256": // FIXME: no intertop, so only 1 exists at present.
|
||||||
_, _ = signatureSB.Write(data)
|
_, _ = signatureSB.Write(data)
|
||||||
_ = signatureSB.WriteByte('\n')
|
_ = signatureSB.WriteByte('\n')
|
||||||
pgpsig = true
|
pgpsig = true
|
||||||
|
|
195
modules/git/commit_sha256_test.go
Normal file
195
modules/git/commit_sha256_test.go
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCommitsCountSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
commitsCount, err := CommitsCount(DefaultContext,
|
||||||
|
CommitsCountOptions{
|
||||||
|
RepoPath: bareRepo1Path,
|
||||||
|
Revision: []string{"f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc"},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int64(3), commitsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommitsCountWithoutBaseSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
commitsCount, err := CommitsCount(DefaultContext,
|
||||||
|
CommitsCountOptions{
|
||||||
|
RepoPath: bareRepo1Path,
|
||||||
|
Not: "main",
|
||||||
|
Revision: []string{"branch1"},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int64(2), commitsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFullCommitIDSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "f004f4")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFullCommitIDErrorSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "unknown")
|
||||||
|
assert.Empty(t, id)
|
||||||
|
if assert.Error(t, err) {
|
||||||
|
assert.EqualError(t, err, "object does not exist [id: unknown, rel_path: ]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommitFromReaderSha256(t *testing.T) {
|
||||||
|
commitString := `9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 commit 1114
|
||||||
|
tree e7f9e96dd79c09b078cac8b303a7d3b9d65ff9b734e86060a4d20409fd379f9e
|
||||||
|
parent 26e9ccc29fad747e9c5d9f4c9ddeb7eff61cc45ef6a8dc258cbeb181afc055e8
|
||||||
|
author Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
committer Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
gpgsig-sha256 -----BEGIN PGP SIGNATURE-----
|
||||||
|
` + " " + `
|
||||||
|
iQIrBAABCgAtFiEES+fB08xlgTrzSdQvhkUIsBsmec8FAmU/wKoPHGFtYWplckBz
|
||||||
|
dXNlLmRlAAoJEIZFCLAbJnnP4s4PQIJATa++WPzR6/H4etT7bsOGoMyguEJYyWOd
|
||||||
|
aTybplzT7QAL7h2to0QszGabtzMJPIA39xSFZNYNN30voK5YyyYibXluPKgjemfK
|
||||||
|
WNXwF+gkwgZI38gSvKf+vlqI+EYyIFe19wOhiju0m8SIlB5NEPiWHa17q2mqmqqx
|
||||||
|
1FWa2JdqLPYjAtSLFXeSZegrY5V1FxdemyMUONkg8YO9OSIMZiE0GsnnOXQ3xcT4
|
||||||
|
JTCnmlUxIKw689UiEY80JopUIq+Wl7+qq9507IYYSUCyB6JazL42AKMzVCbD+qBP
|
||||||
|
oOzh/hafYgk9H9qCQXaLbmvs17zXRpicig1bAzqgAy1FDelvpERyRTydEajSLIG6
|
||||||
|
U1cRCkgXCZ0NfsYNPPmBa8b3+rnstypXYTbyMwTln7FfUAaGo6o9JYiPMkzxlmsy
|
||||||
|
zfp/tcaY8+LlBL9aOJjtv+a0p+HrpCGd6CCa4ARfphTLq8QRSSh8uzlB9N+6HnRI
|
||||||
|
VAEUo6ecdDxSpyt2naeg9pKus/BRi7P6g4B1hkk/zZstUX/QP4IQuAJbXjkvsC+X
|
||||||
|
HKRr3NlRM/DygzTyj0gN74uoa0goCIbyAQhiT42nm0cuhM7uN/W0ayrlZjGF1cbR
|
||||||
|
8NCJUL2Nwj0ywKIavC99Ipkb8AsFwpVT6U6effs6
|
||||||
|
=xybZ
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
|
|
||||||
|
signed commit`
|
||||||
|
|
||||||
|
sha := &Sha256Hash{
|
||||||
|
0x94, 0x33, 0xb2, 0xa6, 0x2b, 0x96, 0x4c, 0x17, 0xa4, 0x48, 0x5a, 0xe1, 0x80, 0xf4, 0x5f, 0x59,
|
||||||
|
0x5d, 0x3e, 0x69, 0xd3, 0x1b, 0x78, 0x60, 0x87, 0x77, 0x5e, 0x28, 0xc6, 0xb6, 0x39, 0x9d, 0xf0,
|
||||||
|
}
|
||||||
|
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare_sha256"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, gitRepo)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if !assert.NotNil(t, commitFromReader) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.EqualValues(t, sha, commitFromReader.ID)
|
||||||
|
assert.EqualValues(t, `-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIrBAABCgAtFiEES+fB08xlgTrzSdQvhkUIsBsmec8FAmU/wKoPHGFtYWplckBz
|
||||||
|
dXNlLmRlAAoJEIZFCLAbJnnP4s4PQIJATa++WPzR6/H4etT7bsOGoMyguEJYyWOd
|
||||||
|
aTybplzT7QAL7h2to0QszGabtzMJPIA39xSFZNYNN30voK5YyyYibXluPKgjemfK
|
||||||
|
WNXwF+gkwgZI38gSvKf+vlqI+EYyIFe19wOhiju0m8SIlB5NEPiWHa17q2mqmqqx
|
||||||
|
1FWa2JdqLPYjAtSLFXeSZegrY5V1FxdemyMUONkg8YO9OSIMZiE0GsnnOXQ3xcT4
|
||||||
|
JTCnmlUxIKw689UiEY80JopUIq+Wl7+qq9507IYYSUCyB6JazL42AKMzVCbD+qBP
|
||||||
|
oOzh/hafYgk9H9qCQXaLbmvs17zXRpicig1bAzqgAy1FDelvpERyRTydEajSLIG6
|
||||||
|
U1cRCkgXCZ0NfsYNPPmBa8b3+rnstypXYTbyMwTln7FfUAaGo6o9JYiPMkzxlmsy
|
||||||
|
zfp/tcaY8+LlBL9aOJjtv+a0p+HrpCGd6CCa4ARfphTLq8QRSSh8uzlB9N+6HnRI
|
||||||
|
VAEUo6ecdDxSpyt2naeg9pKus/BRi7P6g4B1hkk/zZstUX/QP4IQuAJbXjkvsC+X
|
||||||
|
HKRr3NlRM/DygzTyj0gN74uoa0goCIbyAQhiT42nm0cuhM7uN/W0ayrlZjGF1cbR
|
||||||
|
8NCJUL2Nwj0ywKIavC99Ipkb8AsFwpVT6U6effs6
|
||||||
|
=xybZ
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
|
`, commitFromReader.Signature.Signature)
|
||||||
|
assert.EqualValues(t, `tree e7f9e96dd79c09b078cac8b303a7d3b9d65ff9b734e86060a4d20409fd379f9e
|
||||||
|
parent 26e9ccc29fad747e9c5d9f4c9ddeb7eff61cc45ef6a8dc258cbeb181afc055e8
|
||||||
|
author Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
committer Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
|
||||||
|
signed commit`, commitFromReader.Signature.Payload)
|
||||||
|
assert.EqualValues(t, "Adam Majer <amajer@suse.de>", commitFromReader.Author.String())
|
||||||
|
|
||||||
|
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
commitFromReader.CommitMessage += "\n\n"
|
||||||
|
commitFromReader.Signature.Payload += "\n\n"
|
||||||
|
assert.EqualValues(t, commitFromReader, commitFromReader2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasPreviousCommitSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
|
commit, err := repo.GetCommit("f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
parentSHA := MustIDFromString("b0ec7af4547047f12d5093e37ef8f1b3b5415ed8ee17894d43a34d7d34212e9c")
|
||||||
|
notParentSHA := MustIDFromString("42e334efd04cd36eea6da0599913333c26116e1a537ca76e5b6e4af4dda00236")
|
||||||
|
assert.Equal(t, repo.objectFormat, parentSHA.Type())
|
||||||
|
assert.Equal(t, repo.objectFormat.Name(), "sha256")
|
||||||
|
|
||||||
|
haz, err := commit.HasPreviousCommit(parentSHA)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, haz)
|
||||||
|
|
||||||
|
hazNot, err := commit.HasPreviousCommit(notParentSHA)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.False(t, hazNot)
|
||||||
|
|
||||||
|
selfNot, err := commit.HasPreviousCommit(commit.ID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.False(t, selfNot)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCommitFileStatusMergesSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo6_merge_sha256")
|
||||||
|
|
||||||
|
commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expected := CommitFileStatus{
|
||||||
|
[]string{
|
||||||
|
"add_file.txt",
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
[]string{
|
||||||
|
"to_modify.txt",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expected.Added, commitFileStatus.Added)
|
||||||
|
assert.Equal(t, expected.Removed, commitFileStatus.Removed)
|
||||||
|
assert.Equal(t, expected.Modified, commitFileStatus.Modified)
|
||||||
|
|
||||||
|
expected = CommitFileStatus{
|
||||||
|
[]string{},
|
||||||
|
[]string{
|
||||||
|
"to_remove.txt",
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
commitFileStatus, err = GetCommitFileStatus(DefaultContext, bareRepo1Path, "da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, expected.Added, commitFileStatus.Added)
|
||||||
|
assert.Equal(t, expected.Removed, commitFileStatus.Removed)
|
||||||
|
assert.Equal(t, expected.Modified, commitFileStatus.Modified)
|
||||||
|
}
|
|
@ -49,9 +49,9 @@ func TestFormat_Flag(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "multiple fields",
|
name: "multiple fields",
|
||||||
|
|
||||||
givenFormat: foreachref.NewFormat("refname:short", "objecttype", "objectname"),
|
givenFormat: foreachref.NewFormat("refname:lstrip=2", "objecttype", "objectname"),
|
||||||
|
|
||||||
wantFlag: "refname:short %(refname:short)%00objecttype %(objecttype)%00objectname %(objectname)%00%00",
|
wantFlag: "refname:lstrip=2 %(refname:lstrip=2)%00objecttype %(objecttype)%00objectname %(objectname)%00%00",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,10 +166,6 @@ func InitSimple(ctx context.Context) error {
|
||||||
// InitFull initializes git module with version check and change global variables, sync gitconfig.
|
// InitFull initializes git module with version check and change global variables, sync gitconfig.
|
||||||
// It should only be called once at the beginning of the program initialization (TestMain/GlobalInitInstalled) as this code makes unsynchronized changes to variables.
|
// It should only be called once at the beginning of the program initialization (TestMain/GlobalInitInstalled) as this code makes unsynchronized changes to variables.
|
||||||
func InitFull(ctx context.Context) (err error) {
|
func InitFull(ctx context.Context) (err error) {
|
||||||
if err = checkInit(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = InitSimple(ctx); err != nil {
|
if err = InitSimple(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -189,7 +185,13 @@ func InitFull(ctx context.Context) (err error) {
|
||||||
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
|
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
|
||||||
}
|
}
|
||||||
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
|
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
|
||||||
SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil
|
SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil && !isGogit
|
||||||
|
if SupportHashSha256 {
|
||||||
|
SupportedObjectFormats = append(SupportedObjectFormats, Sha256ObjectFormat)
|
||||||
|
} else {
|
||||||
|
log.Warn("sha256 hash support is disabled - requires Git >= 2.42. Gogit is currently unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
if setting.LFS.StartServer {
|
if setting.LFS.StartServer {
|
||||||
if CheckGitVersionAtLeast("2.1.2") != nil {
|
if CheckGitVersionAtLeast("2.1.2") != nil {
|
||||||
return errors.New("LFS server support requires Git >= 2.1.2")
|
return errors.New("LFS server support requires Git >= 2.1.2")
|
||||||
|
|
|
@ -5,6 +5,7 @@ package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
@ -12,6 +13,9 @@ import (
|
||||||
// sha1Pattern can be used to determine if a string is an valid sha
|
// sha1Pattern can be used to determine if a string is an valid sha
|
||||||
var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`)
|
var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`)
|
||||||
|
|
||||||
|
// sha256Pattern can be used to determine if a string is an valid sha
|
||||||
|
var sha256Pattern = regexp.MustCompile(`^[0-9a-f]{4,64}$`)
|
||||||
|
|
||||||
type ObjectFormat interface {
|
type ObjectFormat interface {
|
||||||
// Name returns the name of the object format
|
// Name returns the name of the object format
|
||||||
Name() string
|
Name() string
|
||||||
|
@ -29,11 +33,12 @@ type ObjectFormat interface {
|
||||||
ComputeHash(t ObjectType, content []byte) ObjectID
|
ComputeHash(t ObjectType, content []byte) ObjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SHA1 Type */
|
||||||
type Sha1ObjectFormatImpl struct{}
|
type Sha1ObjectFormatImpl struct{}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
emptyObjectID = &Sha1Hash{}
|
emptySha1ObjectID = &Sha1Hash{}
|
||||||
emptyTree = &Sha1Hash{
|
emptySha1Tree = &Sha1Hash{
|
||||||
0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
|
0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
|
||||||
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04,
|
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04,
|
||||||
}
|
}
|
||||||
|
@ -41,11 +46,11 @@ var (
|
||||||
|
|
||||||
func (Sha1ObjectFormatImpl) Name() string { return "sha1" }
|
func (Sha1ObjectFormatImpl) Name() string { return "sha1" }
|
||||||
func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID {
|
func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID {
|
||||||
return emptyObjectID
|
return emptySha1ObjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Sha1ObjectFormatImpl) EmptyTree() ObjectID {
|
func (Sha1ObjectFormatImpl) EmptyTree() ObjectID {
|
||||||
return emptyTree
|
return emptySha1Tree
|
||||||
}
|
}
|
||||||
func (Sha1ObjectFormatImpl) FullLength() int { return 40 }
|
func (Sha1ObjectFormatImpl) FullLength() int { return 40 }
|
||||||
func (Sha1ObjectFormatImpl) IsValid(input string) bool {
|
func (Sha1ObjectFormatImpl) IsValid(input string) bool {
|
||||||
|
@ -72,11 +77,59 @@ func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID
|
||||||
return &sha1
|
return &sha1
|
||||||
}
|
}
|
||||||
|
|
||||||
var Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{}
|
/* SHA256 Type */
|
||||||
|
type Sha256ObjectFormatImpl struct{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
emptySha256ObjectID = &Sha256Hash{}
|
||||||
|
emptySha256Tree = &Sha256Hash{
|
||||||
|
0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1,
|
||||||
|
0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5,
|
||||||
|
0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc,
|
||||||
|
0x53, 0x21,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (Sha256ObjectFormatImpl) Name() string { return "sha256" }
|
||||||
|
func (Sha256ObjectFormatImpl) EmptyObjectID() ObjectID {
|
||||||
|
return emptySha256ObjectID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Sha256ObjectFormatImpl) EmptyTree() ObjectID {
|
||||||
|
return emptySha256Tree
|
||||||
|
}
|
||||||
|
func (Sha256ObjectFormatImpl) FullLength() int { return 64 }
|
||||||
|
func (Sha256ObjectFormatImpl) IsValid(input string) bool {
|
||||||
|
return sha256Pattern.MatchString(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Sha256ObjectFormatImpl) MustID(b []byte) ObjectID {
|
||||||
|
var id Sha256Hash
|
||||||
|
copy(id[0:32], b)
|
||||||
|
return &id
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeHash compute the hash for a given ObjectType and content
|
||||||
|
func (h Sha256ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
|
||||||
|
hasher := sha256.New()
|
||||||
|
_, _ = hasher.Write(t.Bytes())
|
||||||
|
_, _ = hasher.Write([]byte(" "))
|
||||||
|
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
|
||||||
|
_, _ = hasher.Write([]byte{0})
|
||||||
|
|
||||||
|
// HashSum generates a SHA256 for the provided hash
|
||||||
|
var sha256 Sha1Hash
|
||||||
|
copy(sha256[:], hasher.Sum(nil))
|
||||||
|
return &sha256
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{}
|
||||||
|
Sha256ObjectFormat ObjectFormat = Sha256ObjectFormatImpl{}
|
||||||
|
)
|
||||||
|
|
||||||
var SupportedObjectFormats = []ObjectFormat{
|
var SupportedObjectFormats = []ObjectFormat{
|
||||||
Sha1ObjectFormat,
|
Sha1ObjectFormat,
|
||||||
// TODO: add sha256
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ObjectFormatFromName(name string) ObjectFormat {
|
func ObjectFormatFromName(name string) ObjectFormat {
|
||||||
|
|
|
@ -16,6 +16,7 @@ type ObjectID interface {
|
||||||
Type() ObjectFormat
|
Type() ObjectFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SHA1 */
|
||||||
type Sha1Hash [20]byte
|
type Sha1Hash [20]byte
|
||||||
|
|
||||||
func (h *Sha1Hash) String() string {
|
func (h *Sha1Hash) String() string {
|
||||||
|
@ -39,6 +40,21 @@ func MustIDFromString(hexHash string) ObjectID {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SHA256 */
|
||||||
|
type Sha256Hash [32]byte
|
||||||
|
|
||||||
|
func (h *Sha256Hash) String() string {
|
||||||
|
return hex.EncodeToString(h[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Sha256Hash) IsZero() bool {
|
||||||
|
empty := Sha256Hash{}
|
||||||
|
return bytes.Equal(empty[:], h[:])
|
||||||
|
}
|
||||||
|
func (h *Sha256Hash) RawValue() []byte { return h[:] }
|
||||||
|
func (*Sha256Hash) Type() ObjectFormat { return Sha256ObjectFormat }
|
||||||
|
|
||||||
|
/* utility */
|
||||||
func NewIDFromString(hexHash string) (ObjectID, error) {
|
func NewIDFromString(hexHash string) (ObjectID, error) {
|
||||||
var theObjectFormat ObjectFormat
|
var theObjectFormat ObjectFormat
|
||||||
for _, objectFormat := range SupportedObjectFormats {
|
for _, objectFormat := range SupportedObjectFormats {
|
||||||
|
|
|
@ -13,6 +13,8 @@ func ParseGogitHash(h plumbing.Hash) ObjectID {
|
||||||
switch hash.Size {
|
switch hash.Size {
|
||||||
case 20:
|
case 20:
|
||||||
return Sha1ObjectFormat.MustID(h[:])
|
return Sha1ObjectFormat.MustID(h[:])
|
||||||
|
case 32:
|
||||||
|
return Sha256ObjectFormat.MustID(h[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -97,15 +97,12 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := NewCommand(ctx, "init")
|
cmd := NewCommand(ctx, "init")
|
||||||
if SupportHashSha256 {
|
|
||||||
if objectFormatName == "" {
|
if !IsValidObjectFormat(objectFormatName) {
|
||||||
objectFormatName = Sha1ObjectFormat.Name()
|
return fmt.Errorf("invalid object format: %s", objectFormatName)
|
||||||
}
|
|
||||||
if !IsValidObjectFormat(objectFormatName) {
|
|
||||||
return fmt.Errorf("invalid object format: %s", objectFormatName)
|
|
||||||
}
|
|
||||||
cmd.AddOptionValues("--object-format", objectFormatName)
|
|
||||||
}
|
}
|
||||||
|
cmd.AddOptionValues("--object-format", objectFormatName)
|
||||||
|
|
||||||
if bare {
|
if bare {
|
||||||
cmd.AddArguments("--bare")
|
cmd.AddArguments("--bare")
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -62,11 +63,15 @@ func (repo *Repository) CreateArchive(ctx context.Context, format ArchiveType, t
|
||||||
cmd.AddOptionFormat("--format=%s", format.String())
|
cmd.AddOptionFormat("--format=%s", format.String())
|
||||||
cmd.AddDynamicArguments(commitID)
|
cmd.AddDynamicArguments(commitID)
|
||||||
|
|
||||||
|
// Avoid LFS hooks getting installed because of /etc/gitconfig, which can break pull requests.
|
||||||
|
env := append(os.Environ(), "GIT_CONFIG_NOSYSTEM=1")
|
||||||
|
|
||||||
var stderr strings.Builder
|
var stderr strings.Builder
|
||||||
err := cmd.Run(&RunOpts{
|
err := cmd.Run(&RunOpts{
|
||||||
Dir: repo.Path,
|
Dir: repo.Path,
|
||||||
Stdout: target,
|
Stdout: target,
|
||||||
Stderr: &stderr,
|
Stderr: &stderr,
|
||||||
|
Env: env,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ConcatenateError(err, stderr.String())
|
return ConcatenateError(err, stderr.String())
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var isGogit bool
|
||||||
|
|
||||||
// contextKey is a value for use with context.WithValue.
|
// contextKey is a value for use with context.WithValue.
|
||||||
type contextKey struct {
|
type contextKey struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -21,6 +21,10 @@ import (
|
||||||
"github.com/go-git/go-git/v5/storage/filesystem"
|
"github.com/go-git/go-git/v5/storage/filesystem"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
isGogit = true
|
||||||
|
}
|
||||||
|
|
||||||
// Repository represents a Git repository.
|
// Repository represents a Git repository.
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
Path string
|
Path string
|
||||||
|
|
|
@ -15,6 +15,10 @@ import (
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
isGogit = false
|
||||||
|
}
|
||||||
|
|
||||||
// Repository represents a Git repository.
|
// Repository represents a Git repository.
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
Path string
|
Path string
|
||||||
|
|
|
@ -112,7 +112,9 @@ func (repo *Repository) GetTagWithID(idStr, name string) (*Tag, error) {
|
||||||
|
|
||||||
// GetTagInfos returns all tag infos of the repository.
|
// GetTagInfos returns all tag infos of the repository.
|
||||||
func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) {
|
func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) {
|
||||||
forEachRefFmt := foreachref.NewFormat("objecttype", "refname:short", "object", "objectname", "creator", "contents", "contents:signature")
|
// Generally, refname:short should be equal to refname:lstrip=2 except core.warnAmbiguousRefs is used to select the strict abbreviation mode.
|
||||||
|
// https://git-scm.com/docs/git-for-each-ref#Documentation/git-for-each-ref.txt-refname
|
||||||
|
forEachRefFmt := foreachref.NewFormat("objecttype", "refname:lstrip=2", "object", "objectname", "creator", "contents", "contents:signature")
|
||||||
|
|
||||||
stdoutReader, stdoutWriter := io.Pipe()
|
stdoutReader, stdoutWriter := io.Pipe()
|
||||||
defer stdoutReader.Close()
|
defer stdoutReader.Close()
|
||||||
|
@ -162,7 +164,7 @@ func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) {
|
||||||
func parseTagRef(objectFormat ObjectFormat, ref map[string]string) (tag *Tag, err error) {
|
func parseTagRef(objectFormat ObjectFormat, ref map[string]string) (tag *Tag, err error) {
|
||||||
tag = &Tag{
|
tag = &Tag{
|
||||||
Type: ref["objecttype"],
|
Type: ref["objecttype"],
|
||||||
Name: ref["refname:short"],
|
Name: ref["refname:lstrip=2"],
|
||||||
}
|
}
|
||||||
|
|
||||||
tag.ID, err = NewIDFromString(ref["objectname"])
|
tag.ID, err = NewIDFromString(ref["objectname"])
|
||||||
|
|
|
@ -208,8 +208,8 @@ func TestRepository_parseTagRef(t *testing.T) {
|
||||||
name: "lightweight tag",
|
name: "lightweight tag",
|
||||||
|
|
||||||
givenRef: map[string]string{
|
givenRef: map[string]string{
|
||||||
"objecttype": "commit",
|
"objecttype": "commit",
|
||||||
"refname:short": "v1.9.1",
|
"refname:lstrip=2": "v1.9.1",
|
||||||
// object will be empty for lightweight tags
|
// object will be empty for lightweight tags
|
||||||
"object": "",
|
"object": "",
|
||||||
"objectname": "ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889",
|
"objectname": "ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889",
|
||||||
|
@ -237,8 +237,8 @@ func TestRepository_parseTagRef(t *testing.T) {
|
||||||
name: "annotated tag",
|
name: "annotated tag",
|
||||||
|
|
||||||
givenRef: map[string]string{
|
givenRef: map[string]string{
|
||||||
"objecttype": "tag",
|
"objecttype": "tag",
|
||||||
"refname:short": "v0.0.1",
|
"refname:lstrip=2": "v0.0.1",
|
||||||
// object will refer to commit hash for annotated tag
|
// object will refer to commit hash for annotated tag
|
||||||
"object": "3325fd8a973321fd59455492976c042dde3fd1ca",
|
"object": "3325fd8a973321fd59455492976c042dde3fd1ca",
|
||||||
"objectname": "8c68a1f06fc59c655b7e3905b159d761e91c53c9",
|
"objectname": "8c68a1f06fc59c655b7e3905b159d761e91c53c9",
|
||||||
|
@ -266,11 +266,11 @@ func TestRepository_parseTagRef(t *testing.T) {
|
||||||
name: "annotated tag with signature",
|
name: "annotated tag with signature",
|
||||||
|
|
||||||
givenRef: map[string]string{
|
givenRef: map[string]string{
|
||||||
"objecttype": "tag",
|
"objecttype": "tag",
|
||||||
"refname:short": "v0.0.1",
|
"refname:lstrip=2": "v0.0.1",
|
||||||
"object": "3325fd8a973321fd59455492976c042dde3fd1ca",
|
"object": "3325fd8a973321fd59455492976c042dde3fd1ca",
|
||||||
"objectname": "8c68a1f06fc59c655b7e3905b159d761e91c53c9",
|
"objectname": "8c68a1f06fc59c655b7e3905b159d761e91c53c9",
|
||||||
"creator": "Foo Bar <foo@bar.com> 1565789218 +0300",
|
"creator": "Foo Bar <foo@bar.com> 1565789218 +0300",
|
||||||
"contents": `Add changelog of v1.9.1 (#7859)
|
"contents": `Add changelog of v1.9.1 (#7859)
|
||||||
|
|
||||||
* add changelog of v1.9.1
|
* add changelog of v1.9.1
|
||||||
|
|
1
modules/git/tests/repos/repo1_bare_sha256/HEAD
Normal file
1
modules/git/tests/repos/repo1_bare_sha256/HEAD
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ref: refs/heads/main
|
6
modules/git/tests/repos/repo1_bare_sha256/config
Normal file
6
modules/git/tests/repos/repo1_bare_sha256/config
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[core]
|
||||||
|
repositoryformatversion = 1
|
||||||
|
filemode = true
|
||||||
|
bare = true
|
||||||
|
[extensions]
|
||||||
|
objectformat = sha256
|
1
modules/git/tests/repos/repo1_bare_sha256/description
Normal file
1
modules/git/tests/repos/repo1_bare_sha256/description
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
6
modules/git/tests/repos/repo1_bare_sha256/info/exclude
Normal file
6
modules/git/tests/repos/repo1_bare_sha256/info/exclude
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
7
modules/git/tests/repos/repo1_bare_sha256/info/refs
Normal file
7
modules/git/tests/repos/repo1_bare_sha256/info/refs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
42e334efd04cd36eea6da0599913333c26116e1a537ca76e5b6e4af4dda00236 refs/heads/branch1
|
||||||
|
5bc2249e32e0ba40a08879fba2bd4e97a13cb345831549f4bc5649525da8f6cc refs/heads/branch2
|
||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 refs/heads/main
|
||||||
|
29a82d4fc02e19190fb489cc90d5730ed91970b49f4e39acda2798b3dd4f814e refs/tags/signed-tag
|
||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 refs/tags/signed-tag^{}
|
||||||
|
171822a62559f3aa28a00aa3785dbe915d6a8eb02712682740db44fc8bd2187a refs/tags/test
|
||||||
|
6aae864a3d1d0d6a5be0cc64028c1e7021e2632b031fd8eb82afc5a283d1c3d1 refs/tags/test^{}
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
P pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.pack
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8
modules/git/tests/repos/repo1_bare_sha256/packed-refs
Normal file
8
modules/git/tests/repos/repo1_bare_sha256/packed-refs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# pack-refs with: peeled fully-peeled sorted
|
||||||
|
42e334efd04cd36eea6da0599913333c26116e1a537ca76e5b6e4af4dda00236 refs/heads/branch1
|
||||||
|
5bc2249e32e0ba40a08879fba2bd4e97a13cb345831549f4bc5649525da8f6cc refs/heads/branch2
|
||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 refs/heads/main
|
||||||
|
29a82d4fc02e19190fb489cc90d5730ed91970b49f4e39acda2798b3dd4f814e refs/tags/signed-tag
|
||||||
|
^9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0
|
||||||
|
171822a62559f3aa28a00aa3785dbe915d6a8eb02712682740db44fc8bd2187a refs/tags/test
|
||||||
|
^6aae864a3d1d0d6a5be0cc64028c1e7021e2632b031fd8eb82afc5a283d1c3d1
|
|
@ -0,0 +1 @@
|
||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0
|
1
modules/git/tests/repos/repo5_pulls_sha256/HEAD
Normal file
1
modules/git/tests/repos/repo5_pulls_sha256/HEAD
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ref: refs/heads/main
|
6
modules/git/tests/repos/repo5_pulls_sha256/config
Normal file
6
modules/git/tests/repos/repo5_pulls_sha256/config
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[core]
|
||||||
|
repositoryformatversion = 1
|
||||||
|
filemode = true
|
||||||
|
bare = true
|
||||||
|
[extensions]
|
||||||
|
objectformat = sha256
|
1
modules/git/tests/repos/repo5_pulls_sha256/description
Normal file
1
modules/git/tests/repos/repo5_pulls_sha256/description
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
4
modules/git/tests/repos/repo5_pulls_sha256/info/refs
Normal file
4
modules/git/tests/repos/repo5_pulls_sha256/info/refs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
35ecd0f946c8baeb76fa5a3876f46bf35218655e2304d8505026fa4bfb496a4b refs/heads/main
|
||||||
|
35ecd0f946c8baeb76fa5a3876f46bf35218655e2304d8505026fa4bfb496a4b refs/heads/main-clone
|
||||||
|
7f50a4906503378b0bbb7d61bd2ca8d8d8ff4f7a2474980f99402d742ccc9665 refs/heads/test-patch-1
|
||||||
|
1e35a51dc00fd7de730344c07061acfe80e8117e075ac979b6a29a3a045190ca refs/tags/v0.9.99
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
P pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.pack
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue