Skip to content

Commit 6f8f839

Browse files
committed
Merge remote-tracking branch 'origin/main' into restore-squash-merge-default-comment
2 parents ac435d6 + f7cd394 commit 6f8f839

File tree

167 files changed

+6071
-1750
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+6071
-1750
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ Norwin Roosen <[email protected]> (@noerw)
4242
Kyle Dumont <[email protected]> (@kdumontnu)
4343
Patrick Schratz <[email protected]> (@pat-s)
4444
Janis Estelmann <[email protected]> (@KN4CK3R)
45+
Steven Kriegler <[email protected]> (@justusbunsi)

custom/conf/app.example.ini

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ RUN_MODE = ; prod
5151
;REDIRECT_OTHER_PORT = false
5252
;PORT_TO_REDIRECT = 80
5353
;;
54+
;; Timeout for any write to the connection. (Set to 0 to disable all timeouts.)
55+
;PER_WRITE_TIMEOUT = 30s
56+
;;
57+
;; Timeout per Kb written to connections.
58+
;PER_WRITE_PER_KB_TIMEOUT = 30s
59+
;;
5460
;; Permission for unix socket
5561
;UNIX_SOCKET_PERMISSION = 666
5662
;;
@@ -144,6 +150,14 @@ RUN_MODE = ; prod
144150
;; Enable exposure of SSH clone URL to anonymous visitors, default is false
145151
;SSH_EXPOSE_ANONYMOUS = false
146152
;;
153+
;; Timeout for any write to ssh connections. (Set to 0 to disable all timeouts.)
154+
;; Will default to the PER_WRITE_TIMEOUT.
155+
;SSH_PER_WRITE_TIMEOUT = 30s
156+
;;
157+
;; Timeout per Kb written to ssh connections.
158+
;; Will default to the PER_WRITE_PER_KB_TIMEOUT.
159+
;SSH_PER_WRITE_PER_KB_TIMEOUT = 30s
160+
;;
147161
;; Indicate whether to check minimum key size with corresponding type
148162
;MINIMUM_KEY_SIZE_CHECK = false
149163
;;
@@ -1141,20 +1155,20 @@ PATH =
11411155
;STARTUP_TIMEOUT = 30s
11421156
;;
11431157
;; Issue indexer queue, currently support: channel, levelqueue or redis, default is levelqueue (deprecated - use [queue.issue_indexer])
1144-
;ISSUE_INDEXER_QUEUE_TYPE = levelqueue
1158+
;ISSUE_INDEXER_QUEUE_TYPE = levelqueue; **DEPRECATED** use settings in `[queue.issue_indexer]`.
11451159
;;
11461160
;; When ISSUE_INDEXER_QUEUE_TYPE is levelqueue, this will be the path where the queue will be saved.
11471161
;; This can be overridden by `ISSUE_INDEXER_QUEUE_CONN_STR`.
1148-
;; default is queues/common
1149-
;ISSUE_INDEXER_QUEUE_DIR = queues/common
1162+
;; default is queues/common
1163+
;ISSUE_INDEXER_QUEUE_DIR = queues/common; **DEPRECATED** use settings in `[queue.issue_indexer]`.
11501164
;;
11511165
;; When `ISSUE_INDEXER_QUEUE_TYPE` is `redis`, this will store the redis connection string.
11521166
;; When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this is a directory or additional options of
11531167
;; the form `leveldb://path/to/db?option=value&....`, and overrides `ISSUE_INDEXER_QUEUE_DIR`.
1154-
;ISSUE_INDEXER_QUEUE_CONN_STR = "addrs=127.0.0.1:6379 db=0"
1168+
;ISSUE_INDEXER_QUEUE_CONN_STR = "addrs=127.0.0.1:6379 db=0"; **DEPRECATED** use settings in `[queue.issue_indexer]`.
11551169
;;
11561170
;; Batch queue number, default is 20
1157-
;ISSUE_INDEXER_QUEUE_BATCH_NUMBER = 20
1171+
;ISSUE_INDEXER_QUEUE_BATCH_NUMBER = 20; **DEPRECATED** use settings in `[queue.issue_indexer]`.
11581172

11591173
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11601174
;; Repository Indexer settings
@@ -1183,7 +1197,7 @@ PATH =
11831197
;REPO_INDEXER_EXCLUDE =
11841198
;;
11851199
;;
1186-
;UPDATE_BUFFER_LEN = 20
1200+
;UPDATE_BUFFER_LEN = 20; **DEPRECATED** use settings in `[queue.issue_indexer]`.
11871201
;MAX_FILE_SIZE = 1048576
11881202

11891203
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1201,7 +1215,7 @@ PATH =
12011215
;; default to persistable-channel
12021216
;TYPE = persistable-channel
12031217
;;
1204-
;; data-dir for storing persistable queues and level queues, individual queues will default to `queues/common` meaning the queue is shared.
1218+
;; data-dir for storing persistable queues and level queues, individual queues will default to `queues/common` meaning the queue is shared.
12051219
;DATADIR = queues/
12061220
;;
12071221
;; Default queue length before a channel queue will block

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ The following configuration set `Content-Type: application/vnd.android.package-a
252252
most cases you do not need to change the default value. Alter it only if
253253
your SSH server node is not the same as HTTP node. Do not set this variable
254254
if `PROTOCOL` is set to `unix`.
255+
- `PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the connection. (Set to 0 to
256+
disable all timeouts.)
257+
- `PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to connections.
255258

256259
- `DISABLE_SSH`: **false**: Disable SSH feature when it's not available.
257260
- `START_SSH_SERVER`: **false**: When enabled, use the built-in SSH server.
@@ -268,13 +271,17 @@ The following configuration set `Content-Type: application/vnd.android.package-a
268271
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
269272
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
270273
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
274+
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models.PublicKey` and the others are strings which are shellquoted.
271275
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, [email protected], arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
272276
- `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, [email protected]**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
273277
- `SSH_SERVER_MACS`: **[email protected], hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
274278
- `SSH_SERVER_HOST_KEYS`: **ssh/gitea.rsa, ssh/gogs.rsa**: For the built-in SSH server, choose the keypairs to offer as the host key. The private key should be at `SSH_SERVER_HOST_KEY` and the public `SSH_SERVER_HOST_KEY.pub`. Relative paths are made absolute relative to the `APP_DATA_PATH`. If no key exists a 4096 bit RSA key will be created for you.
275279
- `SSH_KEY_TEST_PATH`: **/tmp**: Directory to create temporary files in when testing public keys using ssh-keygen, default is the system temporary directory.
276280
- `SSH_KEYGEN_PATH`: **ssh-keygen**: Path to ssh-keygen, default is 'ssh-keygen' which means the shell is responsible for finding out which one to call.
277281
- `SSH_EXPOSE_ANONYMOUS`: **false**: Enable exposure of SSH clone URL to anonymous visitors, default is false.
282+
- `SSH_PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the SSH connections. (Set to
283+
0 to disable all timeouts.)
284+
- `SSH_PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to SSH connections.
278285
- `MINIMUM_KEY_SIZE_CHECK`: **true**: Indicate whether to check minimum key size with corresponding type.
279286

280287
- `OFFLINE_MODE`: **false**: Disables use of CDN for static files and Gravatar for profile pictures.
@@ -350,10 +357,10 @@ relation to port exhaustion.
350357
- `ISSUE_INDEXER_NAME`: **gitea_issues**: Issue indexer name, available when ISSUE_INDEXER_TYPE is elasticsearch
351358
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search; available when ISSUE_INDEXER_TYPE is bleve and elasticsearch.
352359
- The next 4 configuration values are deprecated and should be set in `queue.issue_indexer` however are kept for backwards compatibility:
353-
- `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: Issue indexer queue, currently supports:`channel`, `levelqueue`, `redis`.
354-
- `ISSUE_INDEXER_QUEUE_DIR`: **queues/common**: When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this will be the path where the queue will be saved. (Previously this was `indexers/issues.queue`.)
355-
- `ISSUE_INDEXER_QUEUE_CONN_STR`: **addrs=127.0.0.1:6379 db=0**: When `ISSUE_INDEXER_QUEUE_TYPE` is `redis`, this will store the redis connection string. When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this is a directory or additional options of the form `leveldb://path/to/db?option=value&....`, and overrides `ISSUE_INDEXER_QUEUE_DIR`.
356-
- `ISSUE_INDEXER_QUEUE_BATCH_NUMBER`: **20**: Batch queue number.
360+
- `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: Issue indexer queue, currently supports:`channel`, `levelqueue`, `redis`. **DEPRECATED** use settings in `[queue.issue_indexer]`.
361+
- `ISSUE_INDEXER_QUEUE_DIR`: **queues/common**: When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this will be the path where the queue will be saved. **DEPRECATED** use settings in `[queue.issue_indexer]`.
362+
- `ISSUE_INDEXER_QUEUE_CONN_STR`: **addrs=127.0.0.1:6379 db=0**: When `ISSUE_INDEXER_QUEUE_TYPE` is `redis`, this will store the redis connection string. When `ISSUE_INDEXER_QUEUE_TYPE` is `levelqueue`, this is a directory or additional options of the form `leveldb://path/to/db?option=value&....`, and overrides `ISSUE_INDEXER_QUEUE_DIR`. **DEPRECATED** use settings in `[queue.issue_indexer]`.
363+
- `ISSUE_INDEXER_QUEUE_BATCH_NUMBER`: **20**: Batch queue number. **DEPRECATED** use settings in `[queue.issue_indexer]`.
357364

358365
- `REPO_INDEXER_ENABLED`: **false**: Enables code search (uses a lot of disk space, about 6 times more than the repository size).
359366
- `REPO_INDEXER_TYPE`: **bleve**: Code search engine type, could be `bleve` or `elasticsearch`.
@@ -364,7 +371,7 @@ relation to port exhaustion.
364371
- `REPO_INDEXER_INCLUDE`: **empty**: A comma separated list of glob patterns (see https://github.com/gobwas/glob) to **include** in the index. Use `**.txt` to match any files with .txt extension. An empty list means include all files.
365372
- `REPO_INDEXER_EXCLUDE`: **empty**: A comma separated list of glob patterns (see https://github.com/gobwas/glob) to **exclude** from the index. Files that match this list will not be indexed, even if they match in `REPO_INDEXER_INCLUDE`.
366373
- `REPO_INDEXER_EXCLUDE_VENDORED`: **true**: Exclude vendored files from index.
367-
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request.
374+
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request. **DEPRECATED** use settings in `[queue.issue_indexer]`.
368375
- `MAX_FILE_SIZE`: **1048576**: Maximum size in bytes of files to be indexed.
369376
- `STARTUP_TIMEOUT`: **30s**: If the indexer takes longer than this timeout to start - fail. (This timeout will be added to the hammer time above for child processes - as bleve will not start until the previous parent is shutdown.) Set to zero to never timeout.
370377

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
date: "2021-05-13T00:00:00-00:00"
3+
title: "Repository Mirror"
4+
slug: "repo-mirror"
5+
weight: 45
6+
toc: false
7+
draft: false
8+
menu:
9+
sidebar:
10+
parent: "advanced"
11+
name: "Repository Mirror"
12+
weight: 45
13+
identifier: "repo-mirror"
14+
---
15+
16+
# Repository Mirror
17+
18+
Repository mirroring allows for the mirroring of repositories to and from external sources. You can use it to mirror branches, tags, and commits between repositories.
19+
20+
**Table of Contents**
21+
22+
{{< toc >}}
23+
24+
## Use cases
25+
26+
The following are some possible use cases for repository mirroring:
27+
28+
- You migrated to Gitea but still need to keep your project in another source. In that case, you can simply set it up to mirror to Gitea (pull) and all the essential history of commits, tags, and branches are available in your Gitea instance.
29+
- You have old projects in another source that you don’t use actively anymore, but don’t want to remove for archiving purposes. In that case, you can create a push mirror so that your active Gitea repository can push its changes to the old location.
30+
31+
## Pulling from a remote repository
32+
33+
For an existing remote repository, you can set up pull mirroring as follows:
34+
35+
1. Select **New Migration** in the **Create...** menu on the top right.
36+
2. Select the remote repository service.
37+
3. Enter a repository URL.
38+
4. If the repository needs authentication fill in your authentication information.
39+
5. Check the box **This repository will be a mirror**.
40+
5. Select **Migrate repository** to save the configuration.
41+
42+
The repository now gets mirrored periodically from the remote repository. You can force a sync by selecting **Synchronize Now** in the repository settings.
43+
44+
## Pushing to a remote repository
45+
46+
For an existing repository, you can set up push mirroring as follows:
47+
48+
1. In your repository, go to **Settings** > **Repository**, and then the **Mirror Settings** section.
49+
2. Enter a repository URL.
50+
3. If the repository needs authentication expand the **Authorization** section and fill in your authentication information.
51+
4. Select **Add Push Mirror** to save the configuration.
52+
53+
The repository now gets mirrored periodically to the remote repository. You can force a sync by selecting **Synchronize Now**. In case of an error a message displayed to help you resolve it.
54+
55+
:exclamation::exclamation: **NOTE:** This will force push to the remote repository. This will overwrite any changes in the remote repository! :exclamation::exclamation:
56+
57+
### Setting up a push mirror from Gitea to GitHub
58+
59+
To set up a mirror from Gitea to GitHub, you need to follow these steps:
60+
61+
1. Create a [GitHub personal access token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) with the *public_repo* box checked.
62+
2. Fill in the **Git Remote Repository URL**: `https://github.com/<your_github_group>/<your_github_project>.git`.
63+
3. Fill in the **Authorization** fields with your GitHub username and the personal access token.
64+
4. Select **Add Push Mirror** to save the configuration.
65+
66+
The repository pushes shortly thereafter. To force a push, select the **Synchronize Now** button.
67+
68+
### Setting up a push mirror from Gitea to GitLab
69+
70+
To set up a mirror from Gitea to GitLab, you need to follow these steps:
71+
72+
1. Create a [GitLab personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with *write_repository* scope.
73+
2. Fill in the **Git Remote Repository URL**: `https://<destination host>/<your_gitlab_group_or_name>/<your_gitlab_project>.git`.
74+
3. Fill in the **Authorization** fields with `oauth2` as **Username** and your GitLab personal access token as **Password**.
75+
4. Select **Add Push Mirror** to save the configuration.
76+
77+
The repository pushes shortly thereafter. To force a push, select the **Synchronize Now** button.
78+
79+
### Setting up a push mirror from Gitea to Bitbucket
80+
81+
To set up a mirror from Gitea to Bitbucket, you need to follow these steps:
82+
83+
1. Create a [Bitbucket app password](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/) with the *Repository Write* box checked.
84+
2. Fill in the **Git Remote Repository URL**: `https://bitbucket.org/<your_bitbucket_group_or_name>/<your_bitbucket_project>.git`.
85+
3. Fill in the **Authorization** fields with your Bitbucket username and the app password as **Password**.
86+
4. Select **Add Push Mirror** to save the configuration.
87+
88+
The repository pushes shortly thereafter. To force a push, select the **Synchronize Now** button.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ require (
5959
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
6060
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
6161
github.com/hashicorp/go-version v1.3.1
62+
github.com/hashicorp/golang-lru v0.5.1
6263
github.com/huandu/xstrings v1.3.2
6364
github.com/issue9/identicon v1.2.0
6465
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
593593
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
594594
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
595595
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
596+
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
596597
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
597598
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
598599
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=

integrations/api_issue_test.go

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ func TestAPIListIssues(t *testing.T) {
2525

2626
session := loginUser(t, owner.Name)
2727
token := getTokenForLoggedInUser(t, session)
28-
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues?state=all&token=%s",
29-
owner.Name, repo.Name, token)
30-
resp := session.MakeRequest(t, req, http.StatusOK)
28+
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner.Name, repo.Name))
29+
30+
link.RawQuery = url.Values{"token": {token}, "state": {"all"}}.Encode()
31+
resp := session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
3132
var apiIssues []*api.Issue
3233
DecodeJSON(t, resp, &apiIssues)
3334
assert.Len(t, apiIssues, models.GetCount(t, &models.Issue{RepoID: repo.ID}))
@@ -36,15 +37,34 @@ func TestAPIListIssues(t *testing.T) {
3637
}
3738

3839
// test milestone filter
39-
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues?state=all&type=all&milestones=ignore,milestone1,3,4&token=%s",
40-
owner.Name, repo.Name, token)
41-
resp = session.MakeRequest(t, req, http.StatusOK)
40+
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "type": {"all"}, "milestones": {"ignore,milestone1,3,4"}}.Encode()
41+
resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
4242
DecodeJSON(t, resp, &apiIssues)
4343
if assert.Len(t, apiIssues, 2) {
4444
assert.EqualValues(t, 3, apiIssues[0].Milestone.ID)
4545
assert.EqualValues(t, 1, apiIssues[1].Milestone.ID)
4646
}
4747

48+
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "created_by": {"user2"}}.Encode()
49+
resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
50+
DecodeJSON(t, resp, &apiIssues)
51+
if assert.Len(t, apiIssues, 1) {
52+
assert.EqualValues(t, 5, apiIssues[0].ID)
53+
}
54+
55+
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "assigned_by": {"user1"}}.Encode()
56+
resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
57+
DecodeJSON(t, resp, &apiIssues)
58+
if assert.Len(t, apiIssues, 1) {
59+
assert.EqualValues(t, 1, apiIssues[0].ID)
60+
}
61+
62+
link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "mentioned_by": {"user4"}}.Encode()
63+
resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
64+
DecodeJSON(t, resp, &apiIssues)
65+
if assert.Len(t, apiIssues, 1) {
66+
assert.EqualValues(t, 1, apiIssues[0].ID)
67+
}
4868
}
4969

5070
func TestAPICreateIssue(t *testing.T) {
@@ -202,6 +222,20 @@ func TestAPISearchIssues(t *testing.T) {
202222
resp = session.MakeRequest(t, req, http.StatusOK)
203223
DecodeJSON(t, resp, &apiIssues)
204224
assert.Len(t, apiIssues, 1)
225+
226+
query = url.Values{"milestones": {"milestone1"}, "state": {"all"}}
227+
link.RawQuery = query.Encode()
228+
req = NewRequest(t, "GET", link.String())
229+
resp = session.MakeRequest(t, req, http.StatusOK)
230+
DecodeJSON(t, resp, &apiIssues)
231+
assert.Len(t, apiIssues, 1)
232+
233+
query = url.Values{"milestones": {"milestone1,milestone3"}, "state": {"all"}}
234+
link.RawQuery = query.Encode()
235+
req = NewRequest(t, "GET", link.String())
236+
resp = session.MakeRequest(t, req, http.StatusOK)
237+
DecodeJSON(t, resp, &apiIssues)
238+
assert.Len(t, apiIssues, 2)
205239
}
206240

207241
func TestAPISearchIssuesWithLabels(t *testing.T) {

0 commit comments

Comments
 (0)