NewRelease.tsx
Raw
1import config from "../../config.ts";
2import type { RepositoryRow } from "../../db/index.ts";
3import type { SessionUser } from "../../middleware/session.ts";
4import { Layout } from "../layout.tsx";
5import { RepoHeader } from "../repos/RepoHeader.tsx";
6import { RepoNav } from "../repos/RepoNav.tsx";
7
8interface NewReleaseProps {
9 user: SessionUser;
10 repo: RepositoryRow;
11 error?: string;
12 values?: {
13 create_tag?: boolean;
14 tag_name?: string;
15 revision?: string;
16 name?: string;
17 notes?: string;
18 include_source_code?: boolean;
19 };
20}
21
22export function NewRelease({ user, repo, error, values }: NewReleaseProps) {
23 const showTagFields = values?.create_tag ?? false;
24 const defaultRevision =
25 values?.revision !== undefined ? values.revision : repo.default_branch;
26 return (
27 <Layout user={user} title={`New Release — ${repo.name}`}>
28 <div class="container">
29 <RepoHeader repo={repo} />
30 <RepoNav repo={repo} active="releases" user={user} />
31 <div class="form-page">
32 <h2 class="page-title">New Release</h2>
33 {!!error && (
34 <div class="form-error" safe>
35 {error}
36 </div>
37 )}
38 <form
39 method="post"
40 action={`/${repo.name}/releases`}
41 enctype="multipart/form-data"
42 class="form"
43 >
44 <div class="form-group">
45 <label class="form-label" for="name">
46 Release title{" "}
47 <span class="form-required">*</span>
48 </label>
49 <input
50 type="text"
51 id="name"
52 name="name"
53 class="form-input"
54 required
55 maxlength={config.MAX_TITLE_BYTES}
56 value={values?.name ?? ""}
57 placeholder="e.g. Version 1.0 — Initial Release"
58 />
59 </div>
60 <div class="form-group">
61 <label class="checkbox-label">
62 <input
63 type="checkbox"
64 id="create_tag"
65 name="create_tag"
66 value="on"
67 checked={showTagFields}
68 data-toggle-target="tag-fields-group"
69 />
70 <span>Create a git tag for this release</span>
71 </label>
72 </div>
73 <div
74 id="tag-fields-group"
75 style={showTagFields ? "" : "display:none"}
76 >
77 <div class="form-group">
78 <label class="form-label" for="tag_name">
79 Tag name{" "}
80 <span class="form-required">*</span>
81 </label>
82 <input
83 type="text"
84 id="tag_name"
85 name="tag_name"
86 class="form-input"
87 maxlength={config.MAX_TITLE_BYTES}
88 pattern="[a-zA-Z0-9._\-+]+"
89 title="Letters, digits, dots, hyphens, underscores, and plus signs only"
90 value={values?.tag_name ?? ""}
91 placeholder="v1.0.0"
92 />
93 </div>
94 <div class="form-group">
95 <label class="form-label" for="revision">
96 Revision{" "}
97 <span class="form-required">*</span>
98 </label>
99 <input
100 type="text"
101 id="revision"
102 name="revision"
103 class="form-input monospace"
104 value={defaultRevision}
105 placeholder="branch, tag, or commit"
106 />
107 <p class="form-hint">
108 Branch, tag, or commit to tag.
109 </p>
110 </div>
111 </div>
112 <div class="form-group">
113 <label class="form-label" for="notes">
114 Release notes
115 </label>
116 <textarea
117 id="notes"
118 name="notes"
119 class="form-input form-textarea"
120 rows="8"
121 maxlength={config.MAX_TEXT_BODY_BYTES}
122 safe
123 >
124 {values?.notes ?? ""}
125 </textarea>
126 </div>
127 <div class="form-group">
128 <label class="checkbox-label">
129 <input
130 type="checkbox"
131 name="include_source_code"
132 value="on"
133 checked={
134 values?.include_source_code ?? false
135 }
136 />
137 <span>
138 Include source code archives (zip, tar.gz,
139 tar.zst)
140 </span>
141 </label>
142 </div>
143 <div class="form-group">
144 <label class="form-label" for="files">
145 Attach files
146 </label>
147 <input
148 type="file"
149 id="files"
150 name="files"
151 class="form-input"
152 multiple
153 />
154 <p class="form-hint">
155 You can attach multiple files to this release.
156 </p>
157 </div>
158 <div class="form-actions">
159 <button type="submit" class="btn btn-primary">
160 Create release
161 </button>
162 <a
163 href={`/${repo.name}/releases`}
164 class="btn btn-secondary"
165 >
166 Cancel
167 </a>
168 </div>
169 </form>
170 </div>
171 </div>
172 </Layout>
173 );
174}
175