diff --git a/release-notes/13038.md b/release-notes/13038.md
new file mode 100644
index 0000000000..f550237e66
--- /dev/null
+++ b/release-notes/13038.md
@@ -0,0 +1 @@
+The release assets are now listed before the source code archives on the release page.
diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl
index cc9610c77c..e3f8d3c658 100644
--- a/templates/repo/release/list.tmpl
+++ b/templates/repo/release/list.tmpl
@@ -76,31 +76,6 @@
{{ctx.Locale.Tr "repo.release.downloads"}}
{{end}}
diff --git a/tests/e2e/release.test.e2e.ts b/tests/e2e/release.test.e2e.ts
index de30794997..fb073ade40 100644
--- a/tests/e2e/release.test.e2e.ts
+++ b/tests/e2e/release.test.e2e.ts
@@ -54,18 +54,18 @@ test.describe('Releases', () => {
await expect(page).toHaveURL('/user2/repo2/releases');
await expect(page.locator('.download[open] li')).toHaveCount(3);
- await expect(page.locator('.download[open] li:nth-of-type(1)')).toContainText('Source code (ZIP)');
- await expect(page.locator('.download[open] li:nth-of-type(1) span[data-tooltip-content]')).toHaveAttribute('data-tooltip-content', 'This attachment is automatically generated.');
- await expect(page.locator('.download[open] li:nth-of-type(1) a')).toHaveAttribute('href', '/user2/repo2/archive/2.0.zip');
- await expect(page.locator('.download[open] li:nth-of-type(1) a')).toHaveAttribute('type', 'application/zip');
+ await expect(page.locator('.download[open] li:nth-of-type(1)')).toContainText('Test');
+ await expect(page.locator('.download[open] li:nth-of-type(1) a')).toHaveAttribute('href', 'https://forgejo.org/');
- await expect(page.locator('.download[open] li:nth-of-type(2)')).toContainText('Source code (TAR.GZ)');
+ await expect(page.locator('.download[open] li:nth-of-type(2)')).toContainText('Source code (ZIP)');
await expect(page.locator('.download[open] li:nth-of-type(2) span[data-tooltip-content]')).toHaveAttribute('data-tooltip-content', 'This attachment is automatically generated.');
- await expect(page.locator('.download[open] li:nth-of-type(2) a')).toHaveAttribute('href', '/user2/repo2/archive/2.0.tar.gz');
- await expect(page.locator('.download[open] li:nth-of-type(2) a')).toHaveAttribute('type', 'application/gzip');
+ await expect(page.locator('.download[open] li:nth-of-type(2) a')).toHaveAttribute('href', '/user2/repo2/archive/2.0.zip');
+ await expect(page.locator('.download[open] li:nth-of-type(2) a')).toHaveAttribute('type', 'application/zip');
- await expect(page.locator('.download[open] li:nth-of-type(3)')).toContainText('Test');
- await expect(page.locator('.download[open] li:nth-of-type(3) a')).toHaveAttribute('href', 'https://forgejo.org/');
+ await expect(page.locator('.download[open] li:nth-of-type(3)')).toContainText('Source code (TAR.GZ)');
+ await expect(page.locator('.download[open] li:nth-of-type(3) span[data-tooltip-content]')).toHaveAttribute('data-tooltip-content', 'This attachment is automatically generated.');
+ await expect(page.locator('.download[open] li:nth-of-type(3) a')).toHaveAttribute('href', '/user2/repo2/archive/2.0.tar.gz');
+ await expect(page.locator('.download[open] li:nth-of-type(3) a')).toHaveAttribute('type', 'application/gzip');
await screenshot(page);
await page.locator('.octicon-pencil').first().click();
@@ -87,10 +87,10 @@ test.describe('Releases', () => {
// Validate release page and click edit
await expect(page).toHaveURL('/user2/repo2/releases');
await expect(page.locator('.download[open] li')).toHaveCount(4);
- await expect(page.locator('.download[open] li:nth-of-type(3)')).toContainText('Test2');
- await expect(page.locator('.download[open] li:nth-of-type(3) a')).toHaveAttribute('href', 'https://gitea.io/');
- await expect(page.locator('.download[open] li:nth-of-type(4)')).toContainText('Test3');
- await expect(page.locator('.download[open] li:nth-of-type(4) a')).toHaveAttribute('href', 'https://gitea.com/');
+ await expect(page.locator('.download[open] li:nth-of-type(1)')).toContainText('Test2');
+ await expect(page.locator('.download[open] li:nth-of-type(1) a')).toHaveAttribute('href', 'https://gitea.io/');
+ await expect(page.locator('.download[open] li:nth-of-type(2)')).toContainText('Test3');
+ await expect(page.locator('.download[open] li:nth-of-type(2) a')).toHaveAttribute('href', 'https://gitea.com/');
await screenshot(page);
await page.locator('.octicon-pencil').first().click();
});
diff --git a/web_src/css/repo/release-tag.css b/web_src/css/repo/release-tag.css
index 713a268594..1a17ad5106 100644
--- a/web_src/css/repo/release-tag.css
+++ b/web_src/css/repo/release-tag.css
@@ -122,13 +122,13 @@
padding: 8px;
}
- :is(li:first-child, .start-gap + hr + li) {
+ :is(li:first-child, hr + li) {
border-top: 1px solid var(--color-secondary);
border-top-left-radius: var(--border-radius); /* stylelint-disable-line logical-css/require-logical-properties */
border-top-right-radius: var(--border-radius); /* stylelint-disable-line logical-css/require-logical-properties */
}
- :is(li:last-child, .start-gap) {
+ :is(li:last-child, li:has(+ hr)) {
border-bottom: 1px solid var(--color-secondary);
border-bottom-left-radius: var(--border-radius); /* stylelint-disable-line logical-css/require-logical-properties */
border-bottom-right-radius: var(--border-radius); /* stylelint-disable-line logical-css/require-logical-properties */