Compare commits

..

9 Commits

Author SHA1 Message Date
wxiaoguang
86aafea3fb Fix session gob (#35128)
Some checks failed
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-docker-rootful (push) Has been cancelled
release-nightly / nightly-docker-rootless (push) Has been cancelled
Fix #35126
2025-07-20 01:49:36 +00:00
silverwind
3531e9dbfd Replace setup-python with setup-uv (#35116)
Some checks failed
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-docker-rootful (push) Has been cancelled
release-nightly / nightly-docker-rootless (push) Has been cancelled
cron-translations / crowdin-pull (push) Has been cancelled
2025-07-18 14:02:57 +00:00
wxiaoguang
c4f5b2b531 Don't use full-file highlight when there is a git diff textconv (#35114)
Fix #35106
2025-07-18 19:16:27 +08:00
wxiaoguang
8f91bfe9d8 Fix submodule parsing when the gitmodules is missing (#35109)
Follow up #35096, fix #35095, fix #35115 and add more tests

The old code used some fragile behaviors which depend on the "nil"
receiver. This PR should be a complete fix for more edge cases.
2025-07-18 09:42:44 +00:00
silverwind
13b9659952 Align issue-title-buttons with list-header (#35018)
This change concerns the "Edit" and "New Issue" button on top right.
With this change, switching from the issue list into an issue, the "New
Issue" button will no longer "shift" from the postion on the previous
page.

<img width="1299" alt="Screenshot 2025-07-09 at 17 37 31"
src="https://github.com/user-attachments/assets/1ea55d8a-2abd-49b0-951a-ccc6466a74ee"
/>

<img width="1300" alt="Screenshot 2025-07-09 at 17 37 19"
src="https://github.com/user-attachments/assets/05997d9d-25eb-4786-803d-00c575f78bef"
/>

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2025-07-18 09:13:32 +00:00
GiteaBot
3e8aa52446 [skip ci] Updated translations via Crowdin 2025-07-18 00:38:45 +00:00
silverwind
2f138f7a03 Increase gap on latest commit (#35104)
Some checks failed
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-docker-rootful (push) Has been cancelled
release-nightly / nightly-docker-rootless (push) Has been cancelled
cron-translations / crowdin-pull (push) Has been cancelled
2025-07-17 20:53:03 +00:00
NorthRealm
39f145ae72 Fix job status aggregation logic (#35000)
For a run (assume 2 jobs) that has a failed job and a waiting job, the
run status should be waiting, **as the run is not done yet.**

Related #34823
2025-07-17 21:12:02 +03:00
Lunny Xiao
8ee96039aa Fix some missed GitHeadRefName when renaming (#35102) 2025-07-17 14:01:11 +00:00
29 changed files with 242 additions and 108 deletions

View File

@@ -32,15 +32,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: astral-sh/setup-uv@v6
- run: uv python install 3.12
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
cache-dependency-path: package-lock.json
- run: pip install uv
- run: make deps-py
- run: make deps-frontend
- run: make lint-templates
@@ -51,10 +49,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install uv
- uses: astral-sh/setup-uv@v6
- run: uv python install 3.12
- run: make deps-py
- run: make lint-yaml

View File

@@ -187,10 +187,10 @@ func AggregateJobStatus(jobs []*ActionRunJob) Status {
return StatusCancelled
case hasRunning:
return StatusRunning
case hasFailure:
return StatusFailure
case hasWaiting:
return StatusWaiting
case hasFailure:
return StatusFailure
case hasBlocked:
return StatusBlocked
default:

View File

@@ -64,7 +64,7 @@ func TestAggregateJobStatus(t *testing.T) {
{[]Status{StatusFailure, StatusSuccess}, StatusFailure},
{[]Status{StatusFailure, StatusSkipped}, StatusFailure},
{[]Status{StatusFailure, StatusCancelled}, StatusCancelled},
{[]Status{StatusFailure, StatusWaiting}, StatusFailure},
{[]Status{StatusFailure, StatusWaiting}, StatusWaiting},
{[]Status{StatusFailure, StatusRunning}, StatusRunning},
{[]Status{StatusFailure, StatusBlocked}, StatusFailure},

View File

@@ -413,7 +413,7 @@ func (pr *PullRequest) getReviewedByLines(ctx context.Context, writer io.Writer)
return committer.Commit()
}
// GetGitRefName returns git ref for hidden pull request branch
// GetGitHeadRefName returns git ref for hidden pull request branch
func (pr *PullRequest) GetGitHeadRefName() string {
return fmt.Sprintf("%s%d/head", git.PullPrefix, pr.Index)
}

View File

@@ -20,6 +20,7 @@ const (
GitlabLanguage = "gitlab-language"
Lockable = "lockable"
Filter = "filter"
Diff = "diff"
)
var LinguistAttributes = []string{

View File

@@ -15,8 +15,12 @@ type CommitInfo struct {
func getCommitInfoSubmoduleFile(repoLink string, entry *TreeEntry, commit *Commit, treePathDir string) (*CommitSubmoduleFile, error) {
fullPath := path.Join(treePathDir, entry.Name())
submodule, err := commit.GetSubModule(fullPath)
if submodule == nil || err != nil {
if err != nil {
return nil, err
}
if submodule == nil {
// unable to find submodule from ".gitmodules" file
return NewCommitSubmoduleFile(repoLink, fullPath, "", entry.ID.String()), nil
}
return NewCommitSubmoduleFile(repoLink, fullPath, submodule.URL, entry.ID.String()), nil
}

View File

@@ -129,7 +129,14 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
require.NoError(t, err)
cisf, err := getCommitInfoSubmoduleFile("/any/repo-link", tree, commit, "")
require.NoError(t, err)
assert.Nil(t, cisf)
assert.Equal(t, &CommitSubmoduleFile{
repoLink: "/any/repo-link",
fullPath: "file1.txt",
refURL: "",
refID: "e2129701f1a4d54dc44f03c93bca0a2aec7c5449",
}, cisf)
// since there is no refURL, it means that the submodule info doesn't exist, so it won't have a web link
assert.Nil(t, cisf.SubmoduleWebLinkTree(t.Context()))
})
}

View File

@@ -29,12 +29,16 @@ func NewCommitSubmoduleFile(repoLink, fullPath, refURL, refID string) *CommitSub
return &CommitSubmoduleFile{repoLink: repoLink, fullPath: fullPath, refURL: refURL, refID: refID}
}
// RefID returns the commit ID of the submodule, it returns empty string for nil receiver
func (sf *CommitSubmoduleFile) RefID() string {
if sf == nil {
return ""
}
return sf.refID
}
func (sf *CommitSubmoduleFile) getWebLinkInTargetRepo(ctx context.Context, moreLinkPath string) *SubmoduleWebLink {
if sf == nil {
if sf == nil || sf.refURL == "" {
return nil
}
if strings.HasPrefix(sf.refURL, "../") {
@@ -53,14 +57,13 @@ func (sf *CommitSubmoduleFile) getWebLinkInTargetRepo(ctx context.Context, moreL
}
// SubmoduleWebLinkTree tries to make the submodule's tree link in its own repo, it also works on "nil" receiver
// It returns nil if the submodule does not have a valid URL or is nil
func (sf *CommitSubmoduleFile) SubmoduleWebLinkTree(ctx context.Context, optCommitID ...string) *SubmoduleWebLink {
if sf == nil {
return nil
}
return sf.getWebLinkInTargetRepo(ctx, "/tree/"+util.OptionalArg(optCommitID, sf.refID))
return sf.getWebLinkInTargetRepo(ctx, "/tree/"+util.OptionalArg(optCommitID, sf.RefID()))
}
// SubmoduleWebLinkCompare tries to make the submodule's compare link in its own repo, it also works on "nil" receiver
// It returns nil if the submodule does not have a valid URL or is nil
func (sf *CommitSubmoduleFile) SubmoduleWebLinkCompare(ctx context.Context, commitID1, commitID2 string) *SubmoduleWebLink {
return sf.getWebLinkInTargetRepo(ctx, "/compare/"+commitID1+"..."+commitID2)
}

View File

@@ -12,6 +12,8 @@ import (
func TestCommitSubmoduleLink(t *testing.T) {
assert.Nil(t, (*CommitSubmoduleFile)(nil).SubmoduleWebLinkTree(t.Context()))
assert.Nil(t, (*CommitSubmoduleFile)(nil).SubmoduleWebLinkCompare(t.Context(), "", ""))
assert.Nil(t, (&CommitSubmoduleFile{}).SubmoduleWebLinkTree(t.Context()))
assert.Nil(t, (&CommitSubmoduleFile{}).SubmoduleWebLinkCompare(t.Context(), "", ""))
t.Run("GitHubRepo", func(t *testing.T) {
sf := NewCommitSubmoduleFile("/any/repo-link", "full-path", "git@github.com:user/repo.git", "aaaa")

View File

@@ -49,7 +49,7 @@ func (p *PullRequest) IsForkPullRequest() bool {
return p.Head.RepoFullName() != p.Base.RepoFullName()
}
// GetGitRefName returns pull request relative path to head
// GetGitHeadRefName returns pull request relative path to head
func (p PullRequest) GetGitHeadRefName() string {
return fmt.Sprintf("%s%d/head", git.PullPrefix, p.Number)
}

68
modules/session/mem.go Normal file
View File

@@ -0,0 +1,68 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package session
import (
"bytes"
"encoding/gob"
"net/http"
"gitea.com/go-chi/session"
)
type mockMemRawStore struct {
s *session.MemStore
}
var _ session.RawStore = (*mockMemRawStore)(nil)
func (m *mockMemRawStore) Set(k, v any) error {
// We need to use gob to encode the value, to make it have the same behavior as other stores and catch abuses.
// Because gob needs to "Register" the type before it can encode it, and it's unable to decode a struct to "any" so use a map to help to decode the value.
var buf bytes.Buffer
if err := gob.NewEncoder(&buf).Encode(map[string]any{"v": v}); err != nil {
return err
}
return m.s.Set(k, buf.Bytes())
}
func (m *mockMemRawStore) Get(k any) (ret any) {
v, ok := m.s.Get(k).([]byte)
if !ok {
return nil
}
var w map[string]any
_ = gob.NewDecoder(bytes.NewBuffer(v)).Decode(&w)
return w["v"]
}
func (m *mockMemRawStore) Delete(k any) error {
return m.s.Delete(k)
}
func (m *mockMemRawStore) ID() string {
return m.s.ID()
}
func (m *mockMemRawStore) Release() error {
return m.s.Release()
}
func (m *mockMemRawStore) Flush() error {
return m.s.Flush()
}
type mockMemStore struct {
*mockMemRawStore
}
var _ Store = (*mockMemStore)(nil)
func (m mockMemStore) Destroy(writer http.ResponseWriter, request *http.Request) error {
return nil
}
func NewMockMemStore(sid string) Store {
return &mockMemStore{&mockMemRawStore{session.NewMemStore(sid)}}
}

View File

@@ -1,26 +0,0 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package session
import (
"net/http"
"gitea.com/go-chi/session"
)
type MockStore struct {
*session.MemStore
}
func (m *MockStore) Destroy(writer http.ResponseWriter, request *http.Request) error {
return nil
}
type mockStoreContextKeyStruct struct{}
var MockStoreContextKey = mockStoreContextKeyStruct{}
func NewMockStore(sid string) *MockStore {
return &MockStore{session.NewMemStore(sid)}
}

View File

@@ -11,25 +11,25 @@ import (
"gitea.com/go-chi/session"
)
// Store represents a session store
type RawStore = session.RawStore
type Store interface {
Get(any) any
Set(any, any) error
Delete(any) error
ID() string
Release() error
Flush() error
RawStore
Destroy(http.ResponseWriter, *http.Request) error
}
type mockStoreContextKeyStruct struct{}
var MockStoreContextKey = mockStoreContextKeyStruct{}
// RegenerateSession regenerates the underlying session and returns the new store
func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, error) {
for _, f := range BeforeRegenerateSession {
f(resp, req)
}
if setting.IsInTesting {
if store, ok := req.Context().Value(MockStoreContextKey).(*MockStore); ok {
return store, nil
if store := req.Context().Value(MockStoreContextKey); store != nil {
return store.(Store), nil
}
}
return session.RegenerateSession(resp, req)
@@ -37,8 +37,8 @@ func RegenerateSession(resp http.ResponseWriter, req *http.Request) (Store, erro
func GetContextSession(req *http.Request) Store {
if setting.IsInTesting {
if store, ok := req.Context().Value(MockStoreContextKey).(*MockStore); ok {
return store
if store := req.Context().Value(MockStoreContextKey); store != nil {
return store.(Store)
}
}
return session.GetSession(req)

View File

@@ -22,8 +22,8 @@ type VirtualSessionProvider struct {
provider session.Provider
}
// Init initializes the cookie session provider with given root path.
func (o *VirtualSessionProvider) Init(gclifetime int64, config string) error {
// Init initializes the cookie session provider with the given config.
func (o *VirtualSessionProvider) Init(gcLifetime int64, config string) error {
var opts session.Options
if err := json.Unmarshal([]byte(config), &opts); err != nil {
return err
@@ -52,7 +52,7 @@ func (o *VirtualSessionProvider) Init(gclifetime int64, config string) error {
default:
return fmt.Errorf("VirtualSessionProvider: Unknown Provider: %s", opts.Provider)
}
return o.provider.Init(gclifetime, opts.ProviderConfig)
return o.provider.Init(gcLifetime, opts.ProviderConfig)
}
// Read returns raw session store by session ID.

View File

@@ -358,6 +358,7 @@ no_reply_address=Fearann Ríomhphoist Folaite
no_reply_address_helper=Ainm fearainn d'úsáideoirí a bhfuil seoladh ríomhphoist i bhfolach acu. Mar shampla, logálfar an t-ainm úsáideora 'joe' i Git mar 'joe@noreply.example.org' má tá an fearainn ríomhphoist i bhfolach socraithe go 'noreply.example.org'.
password_algorithm=Algartam Hais Pasfhocal
invalid_password_algorithm=Algartam hais pasfhocail neamhbhailí
password_algorithm_helper=Socraigh an algartam haiseála pasfhocail. Bíonn riachtanais agus láidreachtaí difriúla ag halgartaim. Tá an algartam argon2 sách slán ach úsáideann sé go leor cuimhne agus d'fhéadfadh sé a bheith mí-oiriúnach do chórais bheaga.
enable_update_checker=Cumasaigh Seiceoir Nuashonraithe
enable_update_checker_helper=Seiceálacha ar eisiúintí leagan nua go tréimhsiúil trí nascadh le gitea.io.
env_config_keys=Cumraíocht Comhshaoil
@@ -451,6 +452,7 @@ use_scratch_code=Úsáid cód scratch
twofa_scratch_used=D'úsáid tú do chód scratch. Tá tú atreoraithe chuig an leathanach socruithe dhá fhachtóir ionas gur féidir leat clárú do ghléas a bhaint nó cód scratch nua a ghiniúint.
twofa_passcode_incorrect=Tá do phaschód mícheart. Má chuir tú do ghléas míchuir tú, bain úsáid as do chód scratch chun síniú isteach.
twofa_scratch_token_incorrect=Tá do chód scratch mícheart.
twofa_required=Ní mór duit Fíordheimhniú Dhá Fhachtóir a shocrú chun rochtain a fháil ar stórtha, nó iarracht a dhéanamh logáil isteach arís.
login_userpass=Sínigh isteach
login_openid=OpenID
oauth_signup_tab=Cláraigh Cuntas Nua
@@ -462,6 +464,7 @@ oauth_signin_submit=Cuntas Nasc
oauth.signin.error.general=Tharla earráid agus an t-iarratas údaraithe á phróiseáil: %s. Má leanann an earráid seo, téigh i dteagmháil le riarthóir an tsuímh.
oauth.signin.error.access_denied=Diúltaíodh an t-iarratas ar údarú.
oauth.signin.error.temporarily_unavailable=Theip ar údarú toisc nach bhfuil an fhreastalaí fíordheimhnithe ar fáil Bain triail as arís níos déanaí.
oauth_callback_unable_auto_reg=Tá Clárú Uathoibríoch cumasaithe, ach thug Soláthraí OAuth2 %[1]s réimsí ar iarraidh ar ais: %[2]s, ní féidir cuntas a chruthú go huathoibríoch. Cruthaigh cuntas nó déan nasc leis, nó déan teagmháil le riarthóir an tsuímh.
openid_connect_submit=Ceangail
openid_connect_title=Ceangail le cuntas atá ann cheana
openid_connect_desc=Níl an URI OpenID roghnaithe ar eolas. Comhcheangail é le cuntas nua anseo.
@@ -474,6 +477,7 @@ email_domain_blacklisted=Ní féidir leat clárú le do sheoladh ríomhphoist.
authorize_application=Údaraigh an Feidhmchlár
authorize_redirect_notice=Déanfar tú a atreorú chuig %s má údaraíonn tú an feidhmchlár seo.
authorize_application_created_by=Chruthaigh %s an feidhmchlár seo.
authorize_application_description=Má dheonaíonn tú rochtain, beidh sé in ann rochtain a fháil ar fhaisnéis do chuntais go léir agus scríobh chuici, lena n-áirítear stórtha príobháideacha agus eagraíochtaí.
authorize_application_with_scopes=Le scóip: %s
authorize_title=Údaraigh "%s" chun rochtain a fháil ar do chuntas?
authorization_failed=Theip ar údarú
@@ -503,6 +507,7 @@ activate_email.text=Cliceáil ar an nasc seo a leanas le do sheoladh ríomhphois
register_notify=Fáilte go dtí %s
register_notify.title=%[1]s, fáilte go %[2]s
register_notify.text_1=Seo do ríomhphost deimhnithe clárúcháin le haghaidh %s!
register_notify.text_2=Is féidir leat logáil isteach anois tríd an ainm úsáideora: %s.
register_notify.text_3=Má cruthaíodh an cuntas seo duit, <a href="%s">socraigh do phasfhocal</a> ar dtús.
reset_password=Aisghabháil do chuntas
@@ -684,6 +689,7 @@ form.name_chars_not_allowed=Tá carachtair neamhbhailí in ainm úsáideora "%s"
block.block=Bloc
block.block.user=Bloc úsáideoir
block.block.org=Bac úsáideoir ón eagraíocht
block.block.failure=Theip ar an úsáideoir a bhac: %s
block.unblock=Díbhlocáil
block.unblock.failure=Theip ar an úsáideoir a díbhlocáil: %s
@@ -727,6 +733,7 @@ webauthn=Fíordheimhniú Dhá-Fachtóir (Eochracha Slándála)
public_profile=Próifíl Phoiblí
biography_placeholder=Inis dúinn beagán fút féin! (Is féidir leat Markdown a úsáid)
location_placeholder=Comhroinn do shuíomh thart le daoine eile
profile_desc=Rialú conas a thaispeántar do phróifíl d'úsáideoirí eile. Úsáidfear do phríomhsheoladh ríomhphoist le haghaidh fógraí, aisghabháil pasfhocal agus oibríochtaí Git gréasánbhunaithe.
password_username_disabled=Níl cead agat d'ainm úsáideora a athrú. Déan teagmháil le do riarthóir suímh le haghaidh tuilleadh sonraí.
password_full_name_disabled=Níl cead agat dainm iomlán a athrú. Déan teagmháil le do riarthóir suímh le haghaidh tuilleadh sonraí.
full_name=Ainm Iomlán
@@ -805,6 +812,7 @@ activations_pending=Gníomhartha ar Feitheamh
can_not_add_email_activations_pending=Tá gníomhachtú ar feitheamh, déan iarracht arís i gceann cúpla nóiméad más mian leat ríomhphost nua a chur leis.
delete_email=Bain
email_deletion=Bain Seoladh R-phoist
email_deletion_desc=Bainfear an seoladh ríomhphoist seo agus faisnéis ghaolmhar as do chuntas. Fanfaidh na gealltanais Git ón seoladh ríomhphoist seo gan athrú. Ar mhaith leat leanúint ar aghaidh?
email_deletion_success=Tá an seoladh ríomhphoist bainte.
theme_update_success=Nuashonraíodh do théama.
theme_update_error=Níl an téama roghnaithe ann.
@@ -1013,6 +1021,8 @@ email_notifications.onmention=Ríomhphost amháin ar luaigh
email_notifications.disable=Díchumasaigh Fógraí Ríomhphoist
email_notifications.submit=Socraigh rogha ríomhphoist
email_notifications.andyourown=Agus Do Fógraí Féin
email_notifications.actions.desc=Fógraí le haghaidh rith sreabha oibre ar stórtha atá socraithe le <a target="_blank" href="%s">Gníomhartha Gitea</a>.
email_notifications.actions.failure_only=Fógra a thabhairt ach amháin i gcás ritheanna sreabha oibre nár éirigh leo
visibility=Infheictheacht úsáideora
visibility.public=Poiblí
@@ -1094,6 +1104,7 @@ mirror_sync=sioncronaithe
mirror_sync_on_commit=Sioncrónaigh nuair a bhrúitear geallúintí
mirror_address=Clón Ó URL
mirror_address_desc=Cuir aon dhintiúir riachtanacha sa chuid Údaraithe.
mirror_address_url_invalid=Tá an URL a cuireadh ar fáil neamhbhailí. Cinntigh go bhfuil gach comhpháirt den URL escaped i gceart.
mirror_address_protocol_invalid=Tá an URL curtha ar fáil neamhbhailí. Ní féidir ach suíomhanna http (s)://nó git://a úsáid le haghaidh scátháin.
mirror_lfs=Stóráil Comhad Móra (LFS)
mirror_lfs_desc=Gníomhachtaigh scáthú sonraí LFS.
@@ -1153,6 +1164,8 @@ template.issue_labels=Lipéid Eisiúna
template.one_item=Ní mór mír teimpléad amháin ar a laghad a roghnú
template.invalid=Ní mór stór teimpléad a roghnú
archive.title=Tá an stór seo cartlannaithe. Is féidir leat comhaid a fheiceáil agus é a chlónáil. Ní féidir leat saincheisteanna a oscailt, iarratais a tharraingt ná tiomnú a bhrú.
archive.title_date=Tá an stórlann seo cartlannaithe ar %s. Is féidir leat comhaid a fheiceáil agus é a chlónáil. Ní féidir leat saincheisteanna a oscailt, iarratais a tharraingt ná tiomnú a bhrú.
archive.issue.nocomment=Tá an stóras seo i gcartlann. Ní féidir leat trácht a dhéanamh ar shaincheisteanna.
archive.pull.nocomment=Tá an stóras seo i gcartlann. Ní féidir leat trácht a dhéanamh ar iarratais tarraingthe.
@@ -1181,6 +1194,7 @@ migrate_items_releases=Eisiúintí
migrate_repo=Stóras Imirc
migrate.clone_address=Aimirce/ Clón Ó URL
migrate.clone_address_desc=An URL 'clón' HTTP(S) nó Git de stóras atá ann cheana
migrate.github_token_desc=Is féidir leat comhartha amháin nó níos mó a chur anseo scartha le camóga chun an t-aistriú a dhéanamh níos tapúla trí theorainn ráta API GitHub a sheachaint. RABHADH: Dfhéadfadh mí-úsáid a bhaint as an ngné seo sárú a dhéanamh ar pholasaí an tsoláthraí seirbhíse agus dfhéadfadh sé go gcuirfí bac ar do chuntas(í).
migrate.clone_local_path=nó cosán freastalaí áitiúil
migrate.permission_denied=Ní cheadaítear duit stórais áitiúla a iompórtáil.
migrate.permission_denied_blocked=Ní féidir leat allmhairiú ó óstaigh neamh-cheadaithe, iarr ar an riarachán socruithe ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS a sheiceáil le do thoil.
@@ -1242,6 +1256,7 @@ create_new_repo_command=Stóras nua a chruthú ar an líne ordaithe
push_exist_repo=Stóras atá ann cheana a bhrú ón líne ordaithe
empty_message=Níl aon ábhar sa stóras seo.
broken_message=Ní féidir na sonraí Git atá mar bhunús leis an stóras seo a léamh. Déan teagmháil le riarthóir an chás seo nó scrios an stóras seo.
no_branch=Níl aon bhrainse ag an stóras seo.
code=Cód
code.desc=Rochtain ar chód foinse, comhaid, gealltanais agus brainsí.
@@ -1387,6 +1402,8 @@ editor.failed_to_commit=Theip ar athruithe a chur i bhfeidhm.
editor.failed_to_commit_summary=Teachtaireacht Earráide:
editor.fork_create=Stóras Forc chun Athruithe a Mholadh
editor.fork_create_description=Ní féidir leat an stórlann seo a chur in eagar go díreach. Ina áit sin, is féidir leat forc a chruthú, eagarthóireachtaí a dhéanamh agus iarratas tarraingthe a chruthú.
editor.fork_edit_description=Ní féidir leat an stórlann seo a chur in eagar go díreach. Scríobhfar na hathruithe chuig do fhorc <b>%s</b>, ionas gur féidir leat iarratas tarraingthe a chruthú.
editor.fork_not_editable=Tá forc déanta agat ar an stóras seo ach ní féidir do fhorc a chur in eagar.
editor.fork_failed_to_push_branch=Theip ar bhrainse %s a bhrú chuig do stóras.
editor.fork_branch_exists=Tá brainse "%s" ann cheana féin i do fhorc, roghnaigh ainm brainse nua le do thoil.
@@ -1685,6 +1702,7 @@ issues.lock_no_reason=comhrá faoi ghlas agus teoranta do chomhoibrithe %s
issues.unlock_comment=an comhrá seo a dhíghlasáil %s
issues.lock_confirm=Glas
issues.unlock_confirm=Díghlasáil
issues.lock.notice_1=- Ní féidir le húsáideoirí eile tuairimí nua a chur leis an gceist seo.
issues.lock.notice_2=- Is féidir leatsa agus le comhoibrithe eile a bhfuil rochtain acu ar an stór seo fós tuairimí a fhágáil a fheiceann daoine eile.
issues.lock.notice_3=- Is féidir leat an tsaincheist seo a dhíghlasáil arís sa todhchaí.
issues.unlock.notice_1=- Bheadh gach duine in ann trácht a dhéanamh ar an gceist seo arís.
@@ -1853,6 +1871,7 @@ pulls.select_commit_hold_shift_for_range=Roghnaigh tiomantas. Coinnigh shift + c
pulls.review_only_possible_for_full_diff=Ní féidir athbhreithniú a dhéanamh ach amháin nuair a bhreathnaítear ar an difríocht iomlán
pulls.filter_changes_by_commit=Scagaigh de réir tiomantas
pulls.nothing_to_compare=Tá na brainsí seo cothrom. Ní gá iarratas tarraingthe a chruthú.
pulls.nothing_to_compare_have_tag=Tá na brainsí/clibeanna roghnaithe comhionann.
pulls.nothing_to_compare_and_allow_empty_pr=Tá na brainsí seo cothrom. Beidh an PR seo folamh.
pulls.has_pull_request=`Tá iarratas tarraingthe idir na brainsí seo ann cheana: <a href="%[1]s">%[2]s#%[3]d</a>`
pulls.create=Cruthaigh Iarratas Tarraing
@@ -2015,6 +2034,7 @@ milestones.filter_sort.most_issues=Saincheisteanna is mó
milestones.filter_sort.least_issues=Saincheisteanna is lú
signing.will_sign=Síneofar an gealltanas seo le heochair "%s".
signing.wont_sign.error=Tharla earráid agus seiceáil á dhéanamh an bhféadfaí an tiomnú a shíniú.
signing.wont_sign.nokey=Níl aon eochair ar fáil chun an tiomantas seo a shíniú.
signing.wont_sign.never=Ní shínítear tiomáintí riamh.
signing.wont_sign.always=Sínítear tiomáintí i gcónaí.
@@ -2523,6 +2543,7 @@ settings.block_on_official_review_requests_desc=Ní bheidh sé indéanta cumasc
settings.block_outdated_branch=Cuir bac ar chumasc má tá an t-iarratas tarraingthe as dáta
settings.block_outdated_branch_desc=Ní bheidh cumasc indéanta nuair a bhíonn ceannbhrainse taobh thiar de bhronnbhrainse.
settings.block_admin_merge_override=Ní mór do riarthóirí rialacha cosanta brainse a leanúint
settings.block_admin_merge_override_desc=Ní mór do riarthóirí rialacha cosanta brainse a leanúint agus ní féidir leo iad a sheachaint.
settings.default_branch_desc=Roghnaigh brainse stóras réamhshocraithe le haghaidh iarratas tarraingte agus geallann an cód:
settings.merge_style_desc=Stíleanna Cumaisc
settings.default_merge_style_desc=Stíl Cumaisc Réamhshocraithe
@@ -2549,7 +2570,10 @@ settings.matrix.homeserver_url=URL sheirbhíse baile
settings.matrix.room_id=ID seomra
settings.matrix.message_type=Cineál teachtaireachta
settings.visibility.private.button=Déan Príobháideach
settings.visibility.private.text=Má athraítear an infheictheacht go príobháideach, ní bheidh an stór le feiceáil ach ag baill cheadaithe agus dfhéadfadh sé go mbainfí an gaol idir é agus forcanna, faireoirí agus réaltaí atá ann cheana féin.
settings.visibility.private.bullet_title=<strong>An infheictheacht a athrú go toil phríobháide</strong>
settings.visibility.private.bullet_one=Déan an stóras le feiceáil ag baill cheadaithe amháin.
settings.visibility.private.bullet_two=Dfhéadfadh sé an gaol idir é agus <strong>forcanna</strong>, <strong>faireoirí</strong>, agus <strong>réaltaí</strong> a bhaint.
settings.visibility.public.button=Déan Poiblí
settings.visibility.public.text=Má athraíonn an infheictheacht don phobal, beidh an stóras le feiceáil do dhuine ar bith.
settings.visibility.public.bullet_title=<strong>Athróidh an infheictheacht go poiblí:</strong>
@@ -2804,6 +2828,7 @@ team_permission_desc=Cead
team_unit_desc=Ceadaigh Rochtain ar Rannóga Stóras
team_unit_disabled=(Díchumasaithe)
form.name_been_taken=Tá ainm na heagraíochta "%s" tógtha cheana féin.
form.name_reserved=Tá an t-ainm eagraíochta "%s" curtha in áirithe.
form.name_pattern_not_allowed=Ní cheadaítear an patrún "%s" in ainm eagraíochta.
form.create_org_not_allowed=Níl cead agat eagraíocht a chruthú.
@@ -2845,6 +2870,7 @@ settings.delete_notices_2=Scriosfaidh an oibríocht seo go buan gach <strong>st
settings.delete_notices_3=Scriosfaidh an oibríocht seo gach <strong>pacáiste</strong> de chuid <strong>%s</strong> go buan.
settings.delete_notices_4=Scriosfaidh an oibríocht seo gach <strong>tionscadal</strong> de chuid <strong>%s</strong> go buan.
settings.confirm_delete_account=Deimhnigh scriosadh
settings.delete_failed=Theip ar Scriosadh Eagraíochta mar gheall ar earráid inmheánach
settings.delete_successful=Scriosadh an eagraíocht <b>%s</b> go rathúil.
settings.hooks_desc=Cuir crúcaí gréasán in leis a spreagfar do <strong>gach stóras</strong> faoin eagraíocht seo.
@@ -2994,6 +3020,9 @@ dashboard.resync_all_sshprincipals=Nuashonraigh an comhad '.ssh/authorized_princ
dashboard.resync_all_hooks=Athshioncrónaigh crúcaí réamhfhála, nuashonraithe agus iar-fhála na stórtha go léir.
dashboard.reinit_missing_repos=Aththosaigh gach stórais Git atá in easnamh a bhfuil taifid ann dóibh
dashboard.sync_external_users=Sioncrónaigh sonraí úsáideoirí seachtracha
dashboard.cleanup_hook_task_table=Glan suas an tábla hook_task
dashboard.cleanup_packages=Glan suas pacáistí atá imithe in éag
dashboard.cleanup_actions=Glan suas acmhainní gníomhartha atá imithe in éag
dashboard.server_uptime=Aga fónaimh Freastalaí
dashboard.current_goroutine=Goroutines Reatha
dashboard.current_memory_usage=Úsáid Cuimhne Reatha
@@ -3430,6 +3459,7 @@ monitor.start=Am Tosaigh
monitor.execute_time=Am Forghníomhaithe
monitor.last_execution_result=Toradh
monitor.process.cancel=Cealaigh próiseas
monitor.process.cancel_desc=Dfhéadfadh caillteanas sonraí a bheith mar thoradh ar phróiseas a chealú
monitor.process.children=Leanaí
monitor.queues=Scuaineanna
@@ -3701,6 +3731,7 @@ owner.settings.cargo.initialize.success=Cruthaíodh an t-innéacs Cargo go rath
owner.settings.cargo.rebuild=Innéacs Atógáil
owner.settings.cargo.rebuild.description=Is féidir atógáil a bheith úsáideach mura bhfuil an t-innéacs sioncronaithe leis na pacáistí Cargo stóráilte.
owner.settings.cargo.rebuild.error=Níorbh fhéidir an t-innéacs Cargo a atógáil: %v
owner.settings.cargo.rebuild.success=Rinneadh innéacs an Charga a atógáil go rathúil.
owner.settings.cleanuprules.title=Bainistigh Rialacha Glanta
owner.settings.cleanuprules.add=Cuir Riail Glantacháin leis
owner.settings.cleanuprules.edit=Cuir Riail Glantacháin in eagar
@@ -3788,6 +3819,7 @@ runners.delete_runner=Scrios an reathaí seo
runners.delete_runner_success=Scriosadh an reathaí go rathúil
runners.delete_runner_failed=Theip ar an reathaí a scriosadh
runners.delete_runner_header=Deimhnigh an reathaí seo a scriosadh
runners.delete_runner_notice=Má tá tasc á rith ar an rithóir seo, cuirfear deireadh leis agus marcálfar é mar theip air. Dfhéadfadh sé seo cur isteach ar shreabhadh oibre na tógála.
runners.none=Níl aon reathaí ar fáil
runners.status.unspecified=Anaithnid
runners.status.idle=Díomhaoin

View File

@@ -358,6 +358,7 @@ no_reply_address=Domínio dos emails ocultos
no_reply_address_helper=Nome de domínio para utilizadores com um endereço de email oculto. Por exemplo, o nome de utilizador 'silva' será registado no Git como 'silva@semresposta.exemplo.org' se o domínio de email oculto estiver definido como 'semresposta.exemplo.org'.
password_algorithm=Algoritmo de Hash da Senha
invalid_password_algorithm=Algoritmo de hash da senha inválido
password_algorithm_helper=Definir o algoritmo de hash da senha. Os algoritmos têm requisitos e resistências distintos. `argon2` é bastante seguro, mas usa muita memória e pode ser inapropriado para sistemas pequenos.
enable_update_checker=Habilitar verificador de novidades
enable_update_checker_helper=Verifica, periodicamente, se foi lançada alguma versão nova, fazendo uma ligação ao gitea.io.
env_config_keys=Configuração do ambiente
@@ -451,6 +452,7 @@ use_scratch_code=Usar um código de recuperação
twofa_scratch_used=Você usou o seu código de recuperação. Foi reencaminhado para a página de configurações da autenticação em dois passos para poder remover o registo do seu dispositivo ou gerar um novo código de recuperação.
twofa_passcode_incorrect=A senha está errada. Se perdeu o seu dispositivo, use o código de recuperação para iniciar a sessão.
twofa_scratch_token_incorrect=O código de recuperação está errado.
twofa_required=Tem de configurar a autenticação em dois passos para obter acesso aos repositórios ou então tentar iniciar a sessão novamente.
login_userpass=Iniciar sessão
login_openid=OpenID
oauth_signup_tab=Fazer inscrição
@@ -462,6 +464,7 @@ oauth_signin_submit=Vincular conta
oauth.signin.error.general=Ocorreu um erro durante o processamento do pedido de autorização: %s: Se este erro persistir, contacte o administrador.
oauth.signin.error.access_denied=O pedido de autorização foi negado.
oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Tente mais tarde.
oauth_callback_unable_auto_reg=O registo automático está habilitado, mas o fornecedor OAuth2 %[1]s sinalizou campos em falta: %[2]s, por isso não foi possível criar uma conta automaticamente. Crie ou vincule uma conta ou contacte o administrador do sítio.
openid_connect_submit=Estabelecer ligação
openid_connect_title=Estabelecer ligação a uma conta existente
openid_connect_desc=O URI do OpenID escolhido é desconhecido. Associe-o a uma nova conta aqui.
@@ -474,6 +477,7 @@ email_domain_blacklisted=Não pode fazer um registo com o seu endereço de email
authorize_application=Autorizar aplicação
authorize_redirect_notice=Irá ser reencaminhado para %s se autorizar esta aplicação.
authorize_application_created_by=Esta aplicação foi criada por %s.
authorize_application_description=Se conceder o acesso, a aplicação terá privilégios para alterar toda a informação da conta, incluindo repositórios e organizações privados.
authorize_application_with_scopes=Com âmbitos: %s
authorize_title=Autorizar o acesso de "%s" à sua conta?
authorization_failed=A autorização falhou
@@ -503,6 +507,7 @@ activate_email.text=Por favor clique na seguinte ligação para validar o seu en
register_notify=Bem-vindo(a) a %s
register_notify.title=%[1]s, bem-vindo(a) a %[2]s
register_notify.text_1=Este é o seu email de confirmação de registo para %s!
register_notify.text_2=Agora pode iniciar a sessão com o nome de utilizador: %s.
register_notify.text_3=Se esta conta foi criada para si, <a href="%s">defina a sua senha</a> primeiro.
reset_password=Recupere a sua conta
@@ -684,6 +689,7 @@ form.name_chars_not_allowed=O nome de utilizador "%s" contém caracteres inváli
block.block=Bloquear
block.block.user=Bloquear utilizador
block.block.org=Bloquear utilizador da organização
block.block.failure=Falhou o bloqueio do utilizador: %s
block.unblock=Desbloquear
block.unblock.failure=Falhou o desbloqueio do utilizador: %s
@@ -727,6 +733,7 @@ webauthn=Autenticação em dois passos (Chaves de Segurança)
public_profile=Perfil público
biography_placeholder=Conte-nos um pouco sobre si! (Pode usar Markdown)
location_placeholder=Partilhe a sua localização aproximada com outros
profile_desc=Controle como o seu perfil é apresentado aos outros utilizadores. O seu endereço de email principal será usado para notificações, recuperação de senha e operações Git baseadas na web.
password_username_disabled=Não tem permissão para alterar o seu nome de utilizador. Entre em contacto com o administrador para saber mais detalhes.
password_full_name_disabled=Não tem permissão para alterar o seu nome completo. Entre em contacto com o administrador para saber mais detalhes.
full_name=Nome completo
@@ -805,6 +812,7 @@ activations_pending=Habilitações pendentes
can_not_add_email_activations_pending=Existe uma validação pendente. Tente de novo dentro de alguns minutos, se quiser adicionar um novo email.
delete_email=Remover
email_deletion=Remover endereço de email
email_deletion_desc=Este endereço de email e informações relacionadas serão removidos da sua conta. Os cometimentos feitos no Git com este endereço de email permanecerão inalterados. Quer continuar?
email_deletion_success=O endereço de email foi removido.
theme_update_success=O seu tema foi substituído.
theme_update_error=O tema escolhido não existe.
@@ -1013,6 +1021,8 @@ email_notifications.onmention=Enviar email somente quando mencionado(a)
email_notifications.disable=Desabilitar notificações por email
email_notifications.submit=Definir preferência do email
email_notifications.andyourown=e as suas próprias notificações
email_notifications.actions.desc=Notificações para sequências de trabalho são executadas em repositórios configurados com <a target="_blank" href="%s">Gitea Actions</a>.
email_notifications.actions.failure_only=Notificar apenas as execuções de sequências de trabalho falhadas
visibility=Visibilidade do utilizador
visibility.public=Pública
@@ -1094,6 +1104,7 @@ mirror_sync=sincronizado
mirror_sync_on_commit=Sincronizar quando forem enviados cometimentos
mirror_address=Clonar a partir do URL
mirror_address_desc=Coloque, na secção de autorização, as credenciais que, eventualmente, sejam necessárias.
mirror_address_url_invalid=O URL fornecido é inválido. Certifique-se que codifica adequadamente todos os componentes do URL.
mirror_address_protocol_invalid=O URL fornecido é inválido. Só se pode replicar a partir de endereços http(s):// ou git://.
mirror_lfs=Armazenamento de Ficheiros Grandes (LFS)
mirror_lfs_desc=Habilitar a réplica de dados LFS.
@@ -1153,6 +1164,8 @@ template.issue_labels=Rótulos das questões
template.one_item=Tem que escolher pelo menos um item do modelo
template.invalid=Tem que escolher um repositório modelo
archive.title=Este repositório está arquivado. Pode ver os seus ficheiros e cloná-lo. Não pode lançar questões, fazer pedidos de integração nem fazer envios.
archive.title_date=Este repositório foi arquivado em %s. Pode ver os ficheiros e cloná-lo. Não pode abrir questões, fazer pedidos de integração nem enviar cometimentos.
archive.issue.nocomment=Este repositório está arquivado. Não pode comentar nas questões.
archive.pull.nocomment=Este repositório está arquivado. Não pode comentar nos pedidos de integração.
@@ -1181,6 +1194,7 @@ migrate_items_releases=Lançamentos
migrate_repo=Migrar o repositório
migrate.clone_address=Migrar / clonar a partir do URL
migrate.clone_address_desc=O URL de clonagem HTTP(S) ou Git de um repositório existente
migrate.github_token_desc=Pode colocar aqui um ou mais códigos separados por vírgulas para tornar mais rápida a migração, para compensar a limitação de velocidade da API do GitHub. AVISO: O abuso desta funcionalidade poderá violar a política do seu fornecedor de serviço e levar ao bloqueio da(s) sua(a) conta(s).
migrate.clone_local_path=ou uma localização no servidor local
migrate.permission_denied=Não está autorizado a importar repositórios locais.
migrate.permission_denied_blocked=Não pode importar de servidores não permitidos, por favor peça ao administrador para verificar as configurações ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS.
@@ -1242,6 +1256,7 @@ create_new_repo_command=Criando um novo repositório na linha de comandos
push_exist_repo=Enviando, pela linha de comandos, um repositório existente
empty_message=Este repositório não contém qualquer conteúdo.
broken_message=Os dados Git subjacentes a este repositório não podem ser lidos. Contacte o administrador desta instância ou elimine este repositório.
no_branch=Este repositório não tem quaisquer ramos.
code=Código
code.desc=Aceder ao código fonte, ficheiros, cometimentos e ramos.
@@ -1387,6 +1402,8 @@ editor.failed_to_commit=Falhou ao cometer as modificações.
editor.failed_to_commit_summary=Mensagem de erro:
editor.fork_create=Faça uma derivação do repositório para propor modificações
editor.fork_create_description=Não pode editar este repositório. Ao invés disso, crie uma derivação, faça as modificações nessa derivação e crie um pedido de integração.
editor.fork_edit_description=Não pode editar este repositório. As modificações irão ser escritas na sua derivação <b>%s</b>, para que possa criar um pedido de integração.
editor.fork_not_editable=Fez uma derivação deste repositório, mas a sua derivação não é editável.
editor.fork_failed_to_push_branch=Falhou ao enviar o ramo %s para o seu repositório.
editor.fork_branch_exists=O ramo "%s" já existe na sua derivação, escolha outro nome para o ramo.
@@ -1685,6 +1702,7 @@ issues.lock_no_reason=bloqueou o diálogo e restringiu-o aos colaboradores %s
issues.unlock_comment=desbloqueou este diálogo %s
issues.lock_confirm=Bloquear
issues.unlock_confirm=Desbloquear
issues.lock.notice_1=- Os outros utilizadores não podem adicionar novos comentários a esta questão.
issues.lock.notice_2=- Você e outros colaboradores com acesso a este repositório ainda poderão deixar comentários que outros possam ver.
issues.lock.notice_3=- Poderá sempre voltar a desbloquear esta questão no futuro.
issues.unlock.notice_1=- Toda gente poderá voltar a comentar nesta questão.
@@ -1853,6 +1871,7 @@ pulls.select_commit_hold_shift_for_range=Escolha o comentimento. Mantenha premid
pulls.review_only_possible_for_full_diff=A revisão só é possível ao visualizar o diff completo
pulls.filter_changes_by_commit=Filtrar por cometimento
pulls.nothing_to_compare=Estes ramos são iguais. Não há necessidade de criar um pedido de integração.
pulls.nothing_to_compare_have_tag=Os ramos/etiquetas escolhidos são iguais.
pulls.nothing_to_compare_and_allow_empty_pr=Estes ramos são iguais. Este pedido de integração ficará vazio.
pulls.has_pull_request=`Já existe um pedido de integração entre estes ramos: <a href="%[1]s">%[2]s#%[3]d</a>`
pulls.create=Criar um pedido de integração
@@ -2015,6 +2034,7 @@ milestones.filter_sort.most_issues=Mais questões
milestones.filter_sort.least_issues=Menos questões
signing.will_sign=Este cometimento irá ser assinado com a chave "%s".
signing.wont_sign.error=Ocorreu um erro enquanto estava a ser verificado se o cometimento poderia ser assinado.
signing.wont_sign.nokey=Não existe qualquer chave disponível para assinar este cometimento.
signing.wont_sign.never=Os cometimentos nunca são assinados.
signing.wont_sign.always=Os cometimentos são sempre assinados.
@@ -2523,6 +2543,7 @@ settings.block_on_official_review_requests_desc=A integração não será possí
settings.block_outdated_branch=Bloquear integração se o pedido de integração for obsoleto
settings.block_outdated_branch_desc=A integração não será possível quando o ramo de topo estiver abaixo do ramo base.
settings.block_admin_merge_override=Os administradores têm de cumprir as regras de salvaguarda dos ramos
settings.block_admin_merge_override_desc=Os administradores têm de cumprir as regras de salvaguarda do ramo e não as podem contornar.
settings.default_branch_desc=Escolha um ramo do repositório como sendo o predefinido para pedidos de integração e cometimentos:
settings.merge_style_desc=Estilos de integração
settings.default_merge_style_desc=Tipo de integração predefinido
@@ -2549,7 +2570,10 @@ settings.matrix.homeserver_url=URL do servidor caseiro
settings.matrix.room_id=ID da sala
settings.matrix.message_type=Tipo de mensagem
settings.visibility.private.button=Tornar privado
settings.visibility.private.text=Mudar a visibilidade para privado irá tornar o repositório visível somente para membros autorizados e poderá remover a relação entre o repositório e derivações existentes, vigilâncias e favoritos.
settings.visibility.private.bullet_title=<strong>Mudar a visibilidade para privado irá:</strong>
settings.visibility.private.bullet_one=Tornar o repositório visível somente para membros autorizados.
settings.visibility.private.bullet_two=Poderá remover a relação entre o repositório e <strong>derivações</strong>, <strong>vigilâncias</strong> e <strong>favoritos</strong>.
settings.visibility.public.button=Tornar público
settings.visibility.public.text=Mudar a visibilidade para público irá tornar o repositório visível para qualquer pessoa.
settings.visibility.public.bullet_title=<strong>Mudar a visibilidade para público irá:</strong>
@@ -2804,6 +2828,7 @@ team_permission_desc=Permissão
team_unit_desc=Permitir acesso às secções do repositório
team_unit_disabled=(desabilitada)
form.name_been_taken=O nome da organização "%s" já foi tomado.
form.name_reserved=O nome de organização "%s" está reservado.
form.name_pattern_not_allowed=O padrão "%s" não é permitido no nome de uma organização.
form.create_org_not_allowed=Não tem permissão para criar uma organização.
@@ -2845,6 +2870,7 @@ settings.delete_notices_2=Esta operação irá eliminar de forma permanente todo
settings.delete_notices_3=Esta operação irá eliminar de forma permanente todos os <strong>pacotes</strong> de <strong>%s</strong>.
settings.delete_notices_4=Esta operação irá eliminar de forma permanente todos os <strong>planeamentos</strong> de <strong>%s</strong>.
settings.confirm_delete_account=Confirme a eliminação
settings.delete_failed=A eliminação da organização falhou por causa de um erro interno
settings.delete_successful=A organização <b>%s</b> foi eliminada com sucesso.
settings.hooks_desc=Adicionar automatismos web que serão despoletados para <strong>todos os repositórios</strong> desta organização.
@@ -2994,6 +3020,9 @@ dashboard.resync_all_sshprincipals=Modificar o ficheiro '.ssh/authorized_princip
dashboard.resync_all_hooks=Voltar a sincronizar automatismos de pré-acolhimento, modificação e pós-acolhimento de todos os repositórios.
dashboard.reinit_missing_repos=Reinicializar todos os repositórios Git em falta para os quais existam registos
dashboard.sync_external_users=Sincronizar dados externos do utilizador
dashboard.cleanup_hook_task_table=Limpar a tabela hook_task
dashboard.cleanup_packages=Limpar pacotes expirados
dashboard.cleanup_actions=Limpar recursos das operações expirados
dashboard.server_uptime=Tempo em funcionamento contínuo do servidor
dashboard.current_goroutine=Goroutines em execução
dashboard.current_memory_usage=Utilização de memória corrente
@@ -3430,6 +3459,7 @@ monitor.start=Início
monitor.execute_time=Tempo de execução
monitor.last_execution_result=Resultado
monitor.process.cancel=Cancelar processo
monitor.process.cancel_desc=Cancelar um processo pode resultar na perda de dados
monitor.process.children=Descendentes
monitor.queues=Filas
@@ -3701,6 +3731,7 @@ owner.settings.cargo.initialize.success=O índice do Cargo foi criado com sucess
owner.settings.cargo.rebuild=Reconstruir índice
owner.settings.cargo.rebuild.description=Reconstruir pode ser útil se o índice não estiver sincronizado com os pacotes de Cargo armazenados.
owner.settings.cargo.rebuild.error=Falhou ao reconstruir o índice do Cargo: %v
owner.settings.cargo.rebuild.success=O índice do Cargo foi reconstruído com sucesso.
owner.settings.cleanuprules.title=Gerir regras de limpeza
owner.settings.cleanuprules.add=Adicionar regra de limpeza
owner.settings.cleanuprules.edit=Editar regra de limpeza
@@ -3788,6 +3819,7 @@ runners.delete_runner=Eliminar este executor
runners.delete_runner_success=O executor foi eliminado com sucesso
runners.delete_runner_failed=Falhou ao eliminar o executor
runners.delete_runner_header=Confirme que quer eliminar este executor
runners.delete_runner_notice=Se uma tarefa estiver a correr neste executor, será terminada e marcada como tendo falhado. Isso poderá quebrar a sequência de trabalho de construção.
runners.none=Não há executores disponíveis
runners.status.unspecified=Desconhecido
runners.status.idle=Parado

View File

@@ -565,7 +565,7 @@ func createUserInContext(ctx *context.Context, tpl templates.TplName, form any,
oauth2LinkAccount(ctx, user, possibleLinkAccountData, true)
return false // user is already created here, all redirects are handled
case setting.OAuth2AccountLinkingLogin:
showLinkingLogin(ctx, &possibleLinkAccountData.AuthSource, possibleLinkAccountData.GothUser)
showLinkingLogin(ctx, possibleLinkAccountData.AuthSourceID, possibleLinkAccountData.GothUser)
return false // user will be created only after linking login
}
}
@@ -633,7 +633,7 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, possibleLinkAcc
// update external user information
if possibleLinkAccountData != nil {
if err := externalaccount.EnsureLinkExternalToUser(ctx, possibleLinkAccountData.AuthSource.ID, u, possibleLinkAccountData.GothUser); err != nil {
if err := externalaccount.EnsureLinkExternalToUser(ctx, possibleLinkAccountData.AuthSourceID, u, possibleLinkAccountData.GothUser); err != nil {
log.Error("EnsureLinkExternalToUser failed: %v", err)
}
}

View File

@@ -64,13 +64,14 @@ func TestUserLogin(t *testing.T) {
func TestSignUpOAuth2Login(t *testing.T) {
defer test.MockVariableValue(&setting.OAuth2Client.EnableAutoRegistration, true)()
_ = oauth2.Init(t.Context())
addOAuth2Source(t, "dummy-auth-source", oauth2.Source{})
t.Run("OAuth2MissingField", func(t *testing.T) {
defer test.MockVariableValue(&gothic.CompleteUserAuth, func(res http.ResponseWriter, req *http.Request) (goth.User, error) {
return goth.User{Provider: "dummy-auth-source", UserID: "dummy-user"}, nil
})()
mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")}
mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockMemStore("dummy-sid")}
ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback?code=dummy-code", mockOpt)
ctx.SetPathParam("provider", "dummy-auth-source")
SignInOAuthCallback(ctx)
@@ -84,7 +85,7 @@ func TestSignUpOAuth2Login(t *testing.T) {
})
t.Run("OAuth2CallbackError", func(t *testing.T) {
mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")}
mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockMemStore("dummy-sid")}
ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback", mockOpt)
ctx.SetPathParam("provider", "dummy-auth-source")
SignInOAuthCallback(ctx)

View File

@@ -170,7 +170,7 @@ func LinkAccountPostSignIn(ctx *context.Context) {
}
func oauth2LinkAccount(ctx *context.Context, u *user_model.User, linkAccountData *LinkAccountData, remember bool) {
oauth2SignInSync(ctx, &linkAccountData.AuthSource, u, linkAccountData.GothUser)
oauth2SignInSync(ctx, linkAccountData.AuthSourceID, u, linkAccountData.GothUser)
if ctx.Written() {
return
}
@@ -185,7 +185,7 @@ func oauth2LinkAccount(ctx *context.Context, u *user_model.User, linkAccountData
return
}
err = externalaccount.LinkAccountToUser(ctx, linkAccountData.AuthSource.ID, u, linkAccountData.GothUser)
err = externalaccount.LinkAccountToUser(ctx, linkAccountData.AuthSourceID, u, linkAccountData.GothUser)
if err != nil {
ctx.ServerError("UserLinkAccount", err)
return
@@ -295,7 +295,7 @@ func LinkAccountPostRegister(ctx *context.Context) {
Email: form.Email,
Passwd: form.Password,
LoginType: auth.OAuth2,
LoginSource: linkAccountData.AuthSource.ID,
LoginSource: linkAccountData.AuthSourceID,
LoginName: linkAccountData.GothUser.UserID,
}
@@ -304,7 +304,12 @@ func LinkAccountPostRegister(ctx *context.Context) {
return
}
source := linkAccountData.AuthSource.Cfg.(*oauth2.Source)
authSource, err := auth.GetSourceByID(ctx, linkAccountData.AuthSourceID)
if err != nil {
ctx.ServerError("GetSourceByID", err)
return
}
source := authSource.Cfg.(*oauth2.Source)
if err := syncGroupsToTeams(ctx, source, &linkAccountData.GothUser, u); err != nil {
ctx.ServerError("SyncGroupsToTeams", err)
return
@@ -318,5 +323,5 @@ func linkAccountFromContext(ctx *context.Context, user *user_model.User) error {
if linkAccountData == nil {
return errors.New("not in LinkAccount session")
}
return externalaccount.LinkAccountToUser(ctx, linkAccountData.AuthSource.ID, user, linkAccountData.GothUser)
return externalaccount.LinkAccountToUser(ctx, linkAccountData.AuthSourceID, user, linkAccountData.GothUser)
}

View File

@@ -4,6 +4,7 @@
package auth
import (
"encoding/gob"
"errors"
"fmt"
"html"
@@ -171,7 +172,7 @@ func SignInOAuthCallback(ctx *context.Context) {
gothUser.RawData = make(map[string]any)
}
gothUser.RawData["__giteaAutoRegMissingFields"] = missingFields
showLinkingLogin(ctx, authSource, gothUser)
showLinkingLogin(ctx, authSource.ID, gothUser)
return
}
u = &user_model.User{
@@ -192,7 +193,7 @@ func SignInOAuthCallback(ctx *context.Context) {
u.IsAdmin = isAdmin.ValueOrDefault(user_service.UpdateOptionField[bool]{FieldValue: false}).FieldValue
u.IsRestricted = isRestricted.ValueOrDefault(setting.Service.DefaultUserIsRestricted)
linkAccountData := &LinkAccountData{*authSource, gothUser}
linkAccountData := &LinkAccountData{authSource.ID, gothUser}
if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingDisabled {
linkAccountData = nil
}
@@ -207,7 +208,7 @@ func SignInOAuthCallback(ctx *context.Context) {
}
} else {
// no existing user is found, request attach or new account
showLinkingLogin(ctx, authSource, gothUser)
showLinkingLogin(ctx, authSource.ID, gothUser)
return
}
}
@@ -272,11 +273,12 @@ func getUserAdminAndRestrictedFromGroupClaims(source *oauth2.Source, gothUser *g
}
type LinkAccountData struct {
AuthSource auth.Source
GothUser goth.User
AuthSourceID int64
GothUser goth.User
}
func oauth2GetLinkAccountData(ctx *context.Context) *LinkAccountData {
gob.Register(LinkAccountData{})
v, ok := ctx.Session.Get("linkAccountData").(LinkAccountData)
if !ok {
return nil
@@ -284,11 +286,16 @@ func oauth2GetLinkAccountData(ctx *context.Context) *LinkAccountData {
return &v
}
func showLinkingLogin(ctx *context.Context, authSource *auth.Source, gothUser goth.User) {
if err := updateSession(ctx, nil, map[string]any{
"linkAccountData": LinkAccountData{*authSource, gothUser},
}); err != nil {
ctx.ServerError("updateSession", err)
func Oauth2SetLinkAccountData(ctx *context.Context, linkAccountData LinkAccountData) error {
gob.Register(LinkAccountData{})
return updateSession(ctx, nil, map[string]any{
"linkAccountData": linkAccountData,
})
}
func showLinkingLogin(ctx *context.Context, authSourceID int64, gothUser goth.User) {
if err := Oauth2SetLinkAccountData(ctx, LinkAccountData{authSourceID, gothUser}); err != nil {
ctx.ServerError("Oauth2SetLinkAccountData", err)
return
}
ctx.Redirect(setting.AppSubURL + "/user/link_account")
@@ -313,7 +320,7 @@ func oauth2UpdateAvatarIfNeed(ctx *context.Context, url string, u *user_model.Us
}
func handleOAuth2SignIn(ctx *context.Context, authSource *auth.Source, u *user_model.User, gothUser goth.User) {
oauth2SignInSync(ctx, authSource, u, gothUser)
oauth2SignInSync(ctx, authSource.ID, u, gothUser)
if ctx.Written() {
return
}

View File

@@ -18,9 +18,14 @@ import (
"github.com/markbates/goth"
)
func oauth2SignInSync(ctx *context.Context, authSource *auth.Source, u *user_model.User, gothUser goth.User) {
func oauth2SignInSync(ctx *context.Context, authSourceID int64, u *user_model.User, gothUser goth.User) {
oauth2UpdateAvatarIfNeed(ctx, gothUser.AvatarURL, u)
authSource, err := auth.GetSourceByID(ctx, authSourceID)
if err != nil {
ctx.ServerError("GetSourceByID", err)
return
}
oauth2Source, _ := authSource.Cfg.(*oauth2.Source)
if !authSource.IsOAuth2() || oauth2Source == nil {
ctx.ServerError("oauth2SignInSync", fmt.Errorf("source %s is not an OAuth2 source", gothUser.Provider))
@@ -45,7 +50,7 @@ func oauth2SignInSync(ctx *context.Context, authSource *auth.Source, u *user_mod
}
}
err := oauth2UpdateSSHPubIfNeed(ctx, authSource, &gothUser, u)
err = oauth2UpdateSSHPubIfNeed(ctx, authSource, &gothUser, u)
if err != nil {
log.Error("Unable to sync OAuth2 SSH public key %s: %v", gothUser.Provider, err)
}

View File

@@ -259,9 +259,10 @@ func handleRepoEmptyOrBroken(ctx *context.Context) {
}
func handleRepoViewSubmodule(ctx *context.Context, submodule *git.SubModule) {
// TODO: it needs to use git.NewCommitSubmoduleFile and SubmoduleWebLinkTree to correctly handle relative paths
submoduleRepoURL, err := giturl.ParseRepositoryURL(ctx, submodule.URL)
if err != nil {
HandleGitError(ctx, "prepareToRenderDirOrFile: ParseRepositoryURL", err)
HandleGitError(ctx, "handleRepoViewSubmodule: ParseRepositoryURL", err)
return
}
submoduleURL := giturl.MakeRepositoryWebLink(submoduleRepoURL)

View File

@@ -11,7 +11,6 @@ import (
"code.gitea.io/gitea/modules/log"
session_module "code.gitea.io/gitea/modules/session"
chiSession "gitea.com/go-chi/session"
"github.com/gorilla/sessions"
)
@@ -35,11 +34,11 @@ func (st *SessionsStore) New(r *http.Request, name string) (*sessions.Session, e
// getOrNew gets the session from the chi-session if it exists. Override permits the overriding of an unexpected object.
func (st *SessionsStore) getOrNew(r *http.Request, name string, override bool) (*sessions.Session, error) {
chiStore := chiSession.GetSession(r)
store := session_module.GetContextSession(r)
session := sessions.NewSession(st, name)
rawData := chiStore.Get(name)
rawData := store.Get(name)
if rawData != nil {
oldSession, ok := rawData.(*sessions.Session)
if ok {
@@ -56,21 +55,21 @@ func (st *SessionsStore) getOrNew(r *http.Request, name string, override bool) (
}
session.IsNew = override
session.ID = chiStore.ID() // Simply copy the session id from the chi store
session.ID = store.ID() // Simply copy the session id from the chi store
return session, chiStore.Set(name, session)
return session, store.Set(name, session)
}
// Save should persist session to the underlying store implementation.
func (st *SessionsStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
chiStore := chiSession.GetSession(r)
store := session_module.GetContextSession(r)
if session.IsNew {
_, _ = session_module.RegenerateSession(w, r)
session.IsNew = false
}
if err := chiStore.Set(session.Name(), session); err != nil {
if err := store.Set(session.Name(), session); err != nil {
return err
}
@@ -83,7 +82,7 @@ func (st *SessionsStore) Save(r *http.Request, w http.ResponseWriter, session *s
}
}
return chiStore.Release()
return store.Release()
}
type sizeWriter struct {

View File

@@ -49,7 +49,7 @@ func mockRequest(t *testing.T, reqPath string) *http.Request {
type MockContextOption struct {
Render context.Render
SessionStore *session.MockStore
SessionStore session.Store
}
// MockContext mock context for unit tests

View File

@@ -1191,7 +1191,7 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
return nil, err
}
checker, err := attribute.NewBatchChecker(gitRepo, opts.AfterCommitID, []string{attribute.LinguistVendored, attribute.LinguistGenerated, attribute.LinguistLanguage, attribute.GitlabLanguage})
checker, err := attribute.NewBatchChecker(gitRepo, opts.AfterCommitID, []string{attribute.LinguistVendored, attribute.LinguistGenerated, attribute.LinguistLanguage, attribute.GitlabLanguage, attribute.Diff})
if err != nil {
return nil, err
}
@@ -1200,6 +1200,7 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
for _, diffFile := range diff.Files {
isVendored := optional.None[bool]()
isGenerated := optional.None[bool]()
attrDiff := optional.None[string]()
attrs, err := checker.CheckPath(diffFile.Name)
if err == nil {
isVendored, isGenerated = attrs.GetVendored(), attrs.GetGenerated()
@@ -1207,6 +1208,7 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
if language.Has() {
diffFile.Language = language.Value()
}
attrDiff = attrs.Get(attribute.Diff).ToString()
}
// Populate Submodule URLs
@@ -1228,7 +1230,8 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
diffFile.Sections = append(diffFile.Sections, tailSection)
}
if !setting.Git.DisableDiffHighlight {
shouldFullFileHighlight := !setting.Git.DisableDiffHighlight && attrDiff.Value() == ""
if shouldFullFileHighlight {
if limitedContent.LeftContent != nil && limitedContent.LeftContent.buf.Len() < MaxDiffHighlightEntireFileSize {
diffFile.highlightedLeftLines = highlightCodeLines(diffFile, true /* left */, limitedContent.LeftContent.buf.String())
}

View File

@@ -174,7 +174,9 @@ func newTreeViewNodeFromEntry(ctx context.Context, repoLink string, renderedIcon
} else if subModule != nil {
submoduleFile := git.NewCommitSubmoduleFile(repoLink, node.FullPath, subModule.URL, entry.ID.String())
webLink := submoduleFile.SubmoduleWebLinkTree(ctx)
node.SubmoduleURL = webLink.CommitWebLink
if webLink != nil {
node.SubmoduleURL = webLink.CommitWebLink
}
}
}

View File

@@ -11,7 +11,7 @@
{{if eq .PullRequest.Flow 0}}
<div>git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}<origin-url data-url="{{.PullRequest.HeadRepo.Link}}"></origin-url>{{else}}origin{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}</div>
{{else}}
<div>git fetch -u origin {{.PullRequest.GetGitRefName}}:{{$localBranch}}</div>
<div>git fetch -u origin {{.PullRequest.GetGitHeadRefName}}:{{$localBranch}}</div>
{{end}}
<div>git checkout {{$localBranch}}</div>
</div>

View File

@@ -107,7 +107,7 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) {
mockLinkAccount := func(ctx *context.Context) {
authSource := auth_model.Source{ID: 1}
gothUser := goth.User{Email: "invalid-email", Name: "."}
_ = ctx.Session.Set("linkAccountData", auth.LinkAccountData{AuthSource: authSource, GothUser: gothUser})
_ = auth.Oauth2SetLinkAccountData(ctx, auth.LinkAccountData{AuthSourceID: authSource.ID, GothUser: gothUser})
}
t.Run("EnablePasswordSignInForm=false", func(t *testing.T) {

View File

@@ -141,7 +141,7 @@ td .commit-summary {
align-items: center;
overflow: hidden;
text-overflow: ellipsis;
gap: 0.25em;
gap: 0.5em;
}
@media (max-width: 767.98px) {
@@ -334,7 +334,7 @@ td .commit-summary {
display: flex;
gap: 0.5em;
margin-bottom: 8px;
min-height: 40px; /* avoid layout shift on edit */
min-height: 36px; /* avoid layout shift on edit */
}
.repository.view.issue .issue-title h1 {
@@ -342,20 +342,12 @@ td .commit-summary {
width: 100%;
font-weight: var(--font-weight-normal);
font-size: 32px;
line-height: 40px;
line-height: 36px; /* vertically center single-line text with .issue-title-buttons */
margin: 0;
padding-right: 0.25rem;
overflow-wrap: anywhere;
}
.repository.view.issue .issue-title#issue-title-display .issue-title-buttons {
margin-top: 4px; /* the title's height is 40px, fine tune to align the buttons */
}
.repository.view.issue .issue-title#issue-title-editor {
padding-top: 4px;
}
@media (max-width: 767.98px) {
.repository.view.issue .issue-title {
flex-direction: column;