getreadystack commited on
Commit
be24787
·
verified ·
1 Parent(s): 0d9b8d9

Upload index.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +310 -17
index.html CHANGED
@@ -1,19 +1,312 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>Maven Central Publish Gate — free online check</title>
7
+ <style>
8
+ :root{color-scheme:light}body{margin:0;font:15px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:#faf9f5;color:#1a1512}
9
+ .wrap{max-width:960px;margin:0 auto;padding:28px 18px 60px}h1{font-size:26px;margin:0 0 6px}.lede{color:#4a403a;margin:0 0 16px}
10
+ textarea{width:100%;min-height:260px;font:13px/1.45 ui-monospace,Menlo,Consolas,monospace;padding:12px;border:1px solid #d9d0c4;border-radius:8px;box-sizing:border-box}
11
+ .bar{display:flex;gap:10px;align-items:center;margin:12px 0}button{font:600 15px system-ui;padding:10px 18px;border:0;border-radius:8px;background:#1a1512;color:#fff;cursor:pointer}
12
+ input[type=date]{font:14px system-ui;padding:8px;border:1px solid #d9d0c4;border-radius:6px}
13
+ table{border-collapse:collapse;width:100%;font-size:14px;margin-top:10px}th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #eee;vertical-align:top}th{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#7a6e65}
14
+ .sev.error{color:#a8551f;font-weight:700}.sev.warn,.sev.warning{color:#96691f}.ok{color:#2a6446;font-weight:600}.sum{font-weight:600}
15
+ .note{font-size:13px;color:#7a6e65;margin-top:18px}#paid{margin-top:22px;padding:14px 16px;border:1px solid #e2d8cb;border-radius:10px;background:#fffdfa}
16
+ </style>
17
+ <script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script>
18
+ <!--yj-canon-s101--><link rel="canonical" href="https://getreadystack.com/tools/maven-central-publish-gate"></head>
19
+ <body>
20
+ <div class="wrap">
21
+ <h1>Maven Central Publish Gate</h1>
22
+ <p class="lede">Lint pom.xml against Maven Central Portal release rules: retired OSSRH endpoints, missing POM metadata, SNAPSHOT deps, signing and jar requirements. Runs entirely in your browser — nothing is uploaded.</p>
23
+ <textarea id="src" spellcheck="false">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
24
+ &lt;project xmlns="http://maven.apache.org/POM/4.0.0"
25
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
26
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
27
+ &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
28
+
29
+ &lt;groupId&gt;io.hollerith.tiles&lt;/groupId&gt;
30
+ &lt;artifactId&gt;tile-cache&lt;/artifactId&gt;
31
+ &lt;version&gt;2.4.0-SNAPSHOT&lt;/version&gt;
32
+ &lt;packaging&gt;jar&lt;/packaging&gt;
33
+
34
+ &lt;name&gt;Tile Cache&lt;/name&gt;
35
+ &lt;url&gt;https://github.com/hollerith/tile-cache&lt;/url&gt;
36
+
37
+ &lt;properties&gt;
38
+ &lt;maven.compiler.release&gt;17&lt;/maven.compiler.release&gt;
39
+ &lt;gpg.skip&gt;true&lt;/gpg.skip&gt;
40
+ &lt;/properties&gt;
41
+
42
+ &lt;repositories&gt;
43
+ &lt;repository&gt;
44
+ &lt;id&gt;internal-mirror&lt;/id&gt;
45
+ &lt;url&gt;http://repo.internal.hollerith.io/maven2&lt;/url&gt;
46
+ &lt;/repository&gt;
47
+ &lt;/repositories&gt;
48
+
49
+ &lt;distributionManagement&gt;
50
+ &lt;snapshotRepository&gt;
51
+ &lt;id&gt;ossrh&lt;/id&gt;
52
+ &lt;url&gt;https://oss.sonatype.org/content/repositories/snapshots&lt;/url&gt;
53
+ &lt;/snapshotRepository&gt;
54
+ &lt;repository&gt;
55
+ &lt;id&gt;ossrh&lt;/id&gt;
56
+ &lt;url&gt;https://oss.sonatype.org/service/local/staging/deploy/maven2/&lt;/url&gt;
57
+ &lt;/repository&gt;
58
+ &lt;/distributionManagement&gt;
59
+
60
+ &lt;dependencies&gt;
61
+ &lt;dependency&gt;
62
+ &lt;groupId&gt;org.slf4j&lt;/groupId&gt;
63
+ &lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
64
+ &lt;version&gt;2.0.13&lt;/version&gt;
65
+ &lt;/dependency&gt;
66
+ &lt;dependency&gt;
67
+ &lt;groupId&gt;io.hollerith.tiles&lt;/groupId&gt;
68
+ &lt;artifactId&gt;tile-codec&lt;/artifactId&gt;
69
+ &lt;version&gt;0.9.1-SNAPSHOT&lt;/version&gt;
70
+ &lt;/dependency&gt;
71
+ &lt;dependency&gt;
72
+ &lt;groupId&gt;com.vendor.sdk&lt;/groupId&gt;
73
+ &lt;artifactId&gt;vendor-sdk&lt;/artifactId&gt;
74
+ &lt;version&gt;4.1.0&lt;/version&gt;
75
+ &lt;scope&gt;system&lt;/scope&gt;
76
+ &lt;systemPath&gt;${project.basedir}/lib/vendor-sdk-4.1.0.jar&lt;/systemPath&gt;
77
+ &lt;/dependency&gt;
78
+ &lt;/dependencies&gt;
79
+
80
+ &lt;build&gt;
81
+ &lt;plugins&gt;
82
+ &lt;plugin&gt;
83
+ &lt;groupId&gt;org.sonatype.plugins&lt;/groupId&gt;
84
+ &lt;artifactId&gt;nexus-staging-maven-plugin&lt;/artifactId&gt;
85
+ &lt;version&gt;1.6.13&lt;/version&gt;
86
+ &lt;extensions&gt;true&lt;/extensions&gt;
87
+ &lt;configuration&gt;
88
+ &lt;serverId&gt;ossrh&lt;/serverId&gt;
89
+ &lt;nexusUrl&gt;https://oss.sonatype.org/&lt;/nexusUrl&gt;
90
+ &lt;autoReleaseAfterClose&gt;true&lt;/autoReleaseAfterClose&gt;
91
+ &lt;/configuration&gt;
92
+ &lt;/plugin&gt;
93
+ &lt;plugin&gt;
94
+ &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
95
+ &lt;artifactId&gt;maven-gpg-plugin&lt;/artifactId&gt;
96
+ &lt;version&gt;3.2.4&lt;/version&gt;
97
+ &lt;/plugin&gt;
98
+ &lt;/plugins&gt;
99
+ &lt;/build&gt;
100
+ &lt;/project&gt;</textarea>
101
+ <div class="bar"><button id="go">Check</button><label>as of <input type="date" id="today"></label></div>
102
+ <div id="out" aria-live="polite"></div>
103
+ <div id="paid"><strong>Free here:</strong> Check one open pom.xml against every Maven Central Portal release rule and see each blocking line with the fix. <strong>In the editor:</strong> Gate the whole multi-module repository at once and keep the signed-off release report as a file you own — that part asks for a licence key.</div>
104
+ <p class="note">Same engine as the VS Code extension, byte for byte.</p>
105
+ </div>
106
+ <script>var CENTRAL_RULES = [
107
+ {"id": "ossrh_endpoint", "kind": "forbid", "sev": "error",
108
+ "re": "(?:s01\\.)?oss\\.sonatype\\.org",
109
+ "ossrh_sunset": "2025-06-30",
110
+ "portal_host": "central.sonatype.com",
111
+ "msg": "OSSRH endpoint oss.sonatype.org — Sonatype closed it to releases on 2025-06-30. Deploy to the Central Portal (central.sonatype.com) instead."},
112
+
113
+ {"id": "nexus_staging_plugin", "kind": "forbid", "sev": "error",
114
+ "re": "nexus-staging-maven-plugin",
115
+ "msg": "nexus-staging-maven-plugin was retired with OSSRH. Replace it with central-publishing-maven-plugin."},
116
+
117
+ {"id": "snapshot_version", "kind": "forbid", "sev": "error",
118
+ "re": "-SNAPSHOT\\s*\u003c/version\u003e",
119
+ "msg": "A -SNAPSHOT version cannot be released: Central rejects the bundle, and a SNAPSHOT dependency makes the release unbuildable for everyone else."},
120
+
121
+ {"id": "insecure_repository", "kind": "forbid", "sev": "error",
122
+ "re": "\u003curl\u003e\\s*http://",
123
+ "msg": "Plain http:// repository URL. Maven 3.8.1 and later block insecure mirrors, so the build fails before the deploy starts."},
124
+
125
+ {"id": "system_scope_dependency", "kind": "forbid", "sev": "error",
126
+ "re": "\u003cscope\u003e\\s*system\\s*\u003c/scope\u003e",
127
+ "msg": "system-scoped dependency with a local systemPath. Central will not accept a POM that points at a jar outside the repository."},
128
+
129
+ {"id": "gpg_skipped", "kind": "forbid", "sev": "error",
130
+ "re": "\u003cgpg\\.skip\u003e\\s*true",
131
+ "msg": "gpg.skip is true, so the bundle ships unsigned. Central validation rejects any artifact without a .asc signature."},
132
+
133
+ {"id": "meta_name", "kind": "require_child", "sev": "error", "tag": "name",
134
+ "msg": "\u003cname\u003e is missing from the project metadata. Central Portal validation fails a POM without a human-readable project name."},
135
+
136
+ {"id": "meta_description", "kind": "require_child", "sev": "error", "tag": "description",
137
+ "msg": "\u003cdescription\u003e is missing. Central Portal requires a project description on every published POM."},
138
+
139
+ {"id": "meta_url", "kind": "require_child", "sev": "error", "tag": "url",
140
+ "msg": "\u003curl\u003e is missing from the project metadata. Central Portal requires a project URL."},
141
+
142
+ {"id": "meta_licenses", "kind": "require_child", "sev": "error", "tag": "licenses",
143
+ "msg": "\u003clicenses\u003e block is missing. Central Portal requires a declared licence on every published artifact."},
144
+
145
+ {"id": "meta_developers", "kind": "require_child", "sev": "error", "tag": "developers",
146
+ "msg": "\u003cdevelopers\u003e block is missing. Central Portal requires at least one named developer with contact details."},
147
+
148
+ {"id": "meta_scm", "kind": "require_child", "sev": "error", "tag": "scm",
149
+ "msg": "\u003cscm\u003e block is missing. Central Portal requires connection and developerConnection pointing at the source repository."},
150
+
151
+ {"id": "sign_plugin", "kind": "require_text", "sev": "error", "needle": "maven-gpg-plugin",
152
+ "msg": "maven-gpg-plugin is not configured. Every jar, POM and attached artifact must carry a GPG signature or the upload is rejected."},
153
+
154
+ {"id": "sources_jar", "kind": "require_text", "sev": "error", "needle": "maven-source-plugin",
155
+ "msg": "maven-source-plugin is not configured, so no -sources.jar is produced. Central requires a sources jar alongside the main artifact."},
156
+
157
+ {"id": "javadoc_jar", "kind": "require_text", "sev": "error", "needle": "maven-javadoc-plugin",
158
+ "msg": "maven-javadoc-plugin is not configured, so no -javadoc.jar is produced. Central requires a javadoc jar alongside the main artifact."},
159
+
160
+ {"id": "portal_publisher", "kind": "require_text", "sev": "warn", "needle": "central-publishing-maven-plugin",
161
+ "msg": "No central-publishing-maven-plugin. Without the Portal publisher, mvn deploy has nowhere to send the bundle now that OSSRH is closed."}
162
+ ]
163
+ ;</script>
164
+ <script>/* Maven Central Publish Gate — one brain, used by the VS Code extension and by the free web page. */
165
+ (function (root, factory) {
166
+ var RULES = (typeof module !== 'undefined' && module.exports)
167
+ ? require('./rules.json')
168
+ : root.CENTRAL_RULES;
169
+ var api = factory(RULES);
170
+ root.CENTRALGATE = api;
171
+ if (typeof module !== 'undefined' && module.exports) module.exports = api;
172
+ })(typeof window !== 'undefined' ? window : globalThis, function (RULES) {
173
+ 'use strict';
174
+
175
+ RULES = RULES || [];
176
+
177
+ function lineOf(text, index) {
178
+ var n = 1;
179
+ for (var i = 0; i < index && i < text.length; i++) if (text.charCodeAt(i) === 10) n++;
180
+ return n;
181
+ }
182
+
183
+ // Strip comments so a commented-out block never counts as present or as a violation.
184
+ function decomment(text) {
185
+ return text.replace(/<!--[\s\S]*?-->/g, function (m) {
186
+ return m.replace(/[^\n]/g, ' ');
187
+ });
188
+ }
189
+
190
+ // Direct children of <project>: depth 0 is <project> itself, depth 1 its own metadata.
191
+ function directChildren(text) {
192
+ var re = /<(\/?)([A-Za-z_][\w.\-]*)[^>]*?(\/?)>/g;
193
+ var depth = -1, m, found = Object.create(null);
194
+ while ((m = re.exec(text)) !== null) {
195
+ var closing = m[1] === '/', selfClosing = m[3] === '/', name = m[2];
196
+ if (name === 'project' && !closing) { depth = 0; continue; }
197
+ if (depth < 0) continue;
198
+ if (closing) { depth--; continue; }
199
+ depth++;
200
+ if (depth === 1) found[name] = (found[name] || m.index + 1);
201
+ if (selfClosing) depth--;
202
+ }
203
+ return found;
204
+ }
205
+
206
+ function check(text, opts) {
207
+ text = String(text == null ? '' : text);
208
+ opts = opts || {};
209
+ var today = opts.today || '';
210
+ var src = decomment(text);
211
+ var children = directChildren(src);
212
+ var findings = [];
213
+
214
+ RULES.forEach(function (rule) {
215
+ if (rule.kind === 'forbid') {
216
+ var re = new RegExp(rule.re, 'gi'), m;
217
+ while ((m = re.exec(src)) !== null) {
218
+ findings.push({
219
+ check: rule.id,
220
+ sev: rule.sev,
221
+ msg: phrase(rule, today),
222
+ line: lineOf(src, m.index)
223
+ });
224
+ if (m.index === re.lastIndex) re.lastIndex++;
225
+ }
226
+ } else if (rule.kind === 'require_child') {
227
+ if (!children[rule.tag]) {
228
+ findings.push({ check: rule.id, sev: rule.sev, msg: phrase(rule, today), line: 1 });
229
+ }
230
+ } else if (rule.kind === 'require_text') {
231
+ if (src.toLowerCase().indexOf(String(rule.needle).toLowerCase()) === -1) {
232
+ findings.push({ check: rule.id, sev: rule.sev, msg: phrase(rule, today), line: 1 });
233
+ }
234
+ }
235
+ });
236
+
237
+ findings.sort(function (a, b) { return a.line - b.line; });
238
+ return { findings: findings };
239
+ }
240
+
241
+ // The OSSRH line reads differently before and after the shutdown date, so `today` is load-bearing.
242
+ function phrase(rule, today) {
243
+ if (rule.id !== 'ossrh_endpoint' || !rule.ossrh_sunset) return rule.msg;
244
+ if (today && today < rule.ossrh_sunset) {
245
+ return 'OSSRH endpoint oss.sonatype.org — Sonatype closes it to releases on ' + rule.ossrh_sunset +
246
+ '. Move the deploy to the Central Portal (' + rule.portal_host + ') before that date.';
247
+ }
248
+ return rule.msg;
249
+ }
250
+
251
+ return { engine: { check: check }, RULES: RULES, RULE_COUNT: RULES.length };
252
+ });
253
+ </script>
254
+ <script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다.
255
+ 'use strict';
256
+ function escapeHtml(s) { return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); }
257
+ function summaryLine(res) {
258
+ const f = (res && res.findings) || []; const e = f.filter(function (x) { return String(x.sev || 'error').toLowerCase().startsWith('err'); }).length;
259
+ return f.length ? (f.length + ' finding' + (f.length === 1 ? '' : 's') + ' (' + e + ' error' + (e === 1 ? '' : 's') + ')') : 'Clean — no findings.';
260
+ }
261
+ function toText(res, label) {
262
+ const f = (res && res.findings) || [];
263
+ const lines = ['== ' + (label || '') + ' — ' + summaryLine(res)];
264
+ f.forEach(function (x) { lines.push(' ' + String(x.sev || 'error').toUpperCase().slice(0, 4) + ' ' + (x.line ? 'L' + x.line + ' ' : '') + (x.check || x.id || '') + ' ' + (x.msg || x.message || '')); });
265
+ return lines.join('\n');
266
+ }
267
+ function toHtml(res) {
268
+ const f = (res && res.findings) || [];
269
+ if (!f.length) return '<p class="ok">' + escapeHtml(summaryLine(res)) + '</p>';
270
+ const rows = f.map(function (x) { return '<tr><td class="sev ' + escapeHtml(String(x.sev || 'error')) + '">' + escapeHtml(String(x.sev || 'error')) + '</td><td>' + (x.line ? 'L' + escapeHtml(x.line) : '') + '</td><td><code>' + escapeHtml(x.check || x.id || '') + '</code></td><td>' + escapeHtml(x.msg || x.message || '') + '</td></tr>'; }).join('');
271
+ return '<p class="sum">' + escapeHtml(summaryLine(res)) + '</p><table><thead><tr><th>Level</th><th>Line</th><th>Check</th><th>What</th></tr></thead><tbody>' + rows + '</tbody></table>';
272
+ }
273
+ var CENTRALREPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml };
274
+ if (typeof module !== 'undefined' && module.exports) module.exports = CENTRALREPORT;
275
+ else window.CENTRALREPORT = CENTRALREPORT;
276
+ </script>
277
+ <script>
278
+ (function(){
279
+ var src=document.getElementById('src'), out=document.getElementById('out'), go=document.getElementById('go'), today=document.getElementById('today');
280
+ today.value=new Date().toISOString().slice(0,10);
281
+ function run(){ try { var res=window.CENTRALGATE.engine.check(src.value,{today:today.value}); out.innerHTML=window.CENTRALREPORT.toHtml(res); } catch(e){ out.innerHTML='<p class="sev error">Could not run: '+String(e.message||e)+'</p>'; } }
282
+ go.onclick=run; if (src.value.trim()) run();
283
+ })();
284
+ </script>
285
+
286
+
287
+ <section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://marketplace.visualstudio.com/items?itemName=ReadyStack.maven-central-publish-gate" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'maven-central-publish-gate',src:'mp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">VS Code Marketplace</a><a href="https://open-vsx.org/extension/readystack/maven-central-publish-gate" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'maven-central-publish-gate',src:'ovsx',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Open VSX (Cursor, VSCodium)</a><a href="https://www.npmjs.com/package/@readystack/maven-central-publish-gate" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'maven-central-publish-gate',src:'npm',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">npm</a><a href="https://hub.docker.com/r/getreadystack/maven-central-publish-gate" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'maven-central-publish-gate',src:'docker',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.maven-central-publish-gate
288
+ npx @readystack/maven-central-publish-gate &lt;file&gt;
289
+ docker run --rm -v &quot;$PWD:/w&quot; getreadystack/maven-central-publish-gate /w</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://buy.polar.sh/polar_cl_l6iN1uWt0FwWu7tBsczD0jWpP2vxFM54Wdwqb3KPi1G" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
290
+ <section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get the full rule table as a PDF</b><div style="opacity:.78;margin:.35rem 0 .8rem">All 16 rules Maven Central Publish Gate checks, each with its source and date, on printable pages you can hand to your team or auditor. We email it now, and once more only if a rule changes. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Email me the PDF</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">Sent. It arrives within the hour - check spam too.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"maven-central-publish-gate",lang:"en",source:"rule_table"})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script></section>
291
+
292
+ <section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">Read a pom.xml the way the Central Portal reads it, before you burn a release tag</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">A freelance Java release engineer bills about $80 an hour, and a rejected bundle costs a full release round-trip: retag, rebuild, re-sign, re-upload.</p><a href="https://buy.polar.sh/polar_cl_1ApNFZVJP2ES4VPRlkdZLHqQgk44gcmW4aENZ48tDsD" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section>
293
+ <!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script>
294
+
295
+ <div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div>
296
+ <script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script>
297
+
298
+ <script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script>
299
+ <section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><p style="font:400 13px/1.5 system-ui,sans-serif;color:#6b7680;margin:0 0 14px"><time datetime="2026-09-18">Updated 2026-09-18</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-09-18","author":{"@type":"Organization","name":"ReadyStack"}}</script><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Worked example</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 16px;color:#5b6570">Real numbers from this tool, line by line.</p><div class="yj-article"><p><img src="https://getreadystack.com/img/promo/sku111757_result_card.jpg" alt="Maven Central Publish Gate" loading="lazy" style="max-width:100%;border-radius:6px"></p>
300
+ <p>Sixteen blocking findings in one 78-line pom.xml. That is what the gate returned on a Java library whose maintainer, a solo open-source developer in Rotterdam, had already tagged, built and signed, ten minutes before <code>mvn deploy</code>.</p>
301
+ <p>None of the sixteen were compile errors. <code>mvn verify</code> was green. That is the whole trap: the Maven Central Portal validates publishing metadata that the build itself never reads, so a POM can be perfectly buildable and still be rejected at upload.</p>
302
+ <p>The biggest one was infrastructure. Sonatype closed <code>oss.sonatype.org</code> to releases on 2025-06-30. The POM still pointed <code>distributionManagement</code> there, and still drove the release with <code>nexus-staging-maven-plugin</code>, the plugin that retired alongside it. Two lines, written when that was the correct answer, and correct nowhere since.</p>
303
+ <p>This is exactly the kind of line a generated build file gets wrong. Ask an assistant to set up Central publishing and much of what comes back is the OSSRH staging flow, because that is what most of the internet still describes. The code compiles. The release does not land.</p>
304
+ <p>The rest were ordinary and just as fatal. The version was <code>2.4.0-SNAPSHOT</code>, and Central does not accept SNAPSHOT bundles. One dependency was itself a SNAPSHOT, which would have made the published artifact unbuildable downstream even if the upload had landed. <code>gpg.skip</code> was <code>true</code> from a CI experiment, so nothing would have carried an <code>.asc</code> signature. A vendor jar was wired in with <code>system</code> scope and a local <code>systemPath</code>, pointing at a file that exists on exactly one laptop. An internal mirror was declared over plain <code>http://</code>, blocked by Maven itself since 3.8.1.</p>
305
+ <p>And four required metadata blocks were simply absent: <code>description</code>, <code>licenses</code>, <code>developers</code>, <code>scm</code>. The Portal requires all of them. There was no <code>maven-source-plugin</code> and no <code>maven-javadoc-plugin</code>, so no <code>-sources.jar</code> and no <code>-javadoc.jar</code> would have been attached, and Central requires both.</p>
306
+ <p>Fifteen errors and one warning, raised by 13 of the gate&#x27;s 16 rules, on 78 lines.</p>
307
+ <p>Run the same gate against a release-ready POM and it returns nothing. The clean fixture that ships with the extension is 99 lines and produces 0 findings. Both files ship, so you can check the claim yourself before you trust it with a release.</p>
308
+ <p>The shutdown date is a real input, not a constant in a sentence. Hand the gate a date before 2025-06-30 and the OSSRH finding reads &#x27;Sonatype closes it to releases on 2025-06-30 — move the deploy before that date.&#x27; Hand it today&#x27;s date and it reads &#x27;closed on 2025-06-30. Deploy to the Central Portal instead.&#x27; Same rule, same file, different answer.</p>
309
+ <p>What it does not do: it reads the POM as text. It does not resolve parent POMs, interpolate properties, contact the Portal, or read your <code>settings.xml</code> or keyring. A file that passes can still fail on something only Sonatype knows, such as an unverified namespace.</p>
310
+ <p>A rejected bundle is not a five-minute fix. You retag, rebuild, re-sign, re-upload. A freelance Java release engineer bills about $80 an hour, and the round-trip eats more than the review would have. Worse, a version number you burned on a failed attempt is gone for good.</p>
311
+ <p>The free version checks the pom.xml you have open, every rule, no key and no cap. That is a finished job — you see the blockers, you fix them, you ship. The licensed version changes the scope: it gates every pom.xml in a multi-module repository in one pass and writes the result to a REPORT.md you keep.</p></div><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:30px 0 10px;color:#1b1f24">15 seconds — what it actually does</h2><video controls muted playsinline preload="none" poster="/img/promo/sku111757_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku111757_short.mp4" type="video/mp4"></video><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does Maven Central Publish Gate actually do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads a pom.xml and reports every line that the Maven Central Portal will reject at upload: the retired oss.sonatype.org endpoint, nexus-staging-maven-plugin, SNAPSHOT versions and SNAPSHOT dependencies, missing name, description, url, licenses, developers or scm blocks, missing gpg, sources and javadoc plugins, plain http repositories, and system-scoped dependencies. Sixteen rules, each with the fix on the same line.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is this for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Java and Kotlin library maintainers who publish to Maven Central from their own build rather than through a release platform. That means one-person open source projects, small platform teams shipping an internal SDK to Central, and anyone who inherited a pom.xml written when oss.sonatype.org still accepted releases and has not cut a release since.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why will a free tool not do this?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">mvn verify passes on a pom that Central rejects, because the Portal validates metadata that Maven itself never needs. A chatbot answers from training data that still describes the OSSRH staging flow Sonatype closed on 2025-06-30. The Portal itself only tells you after you upload, and only about the first thing it hits.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what does the licence key add?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free is complete for one file: open a pom.xml, get every blocker on it, fix them, ship. The licence key changes scope and ownership. It gates every pom.xml in a multi-module repository in one command, and writes the result to a REPORT.md file you keep and can attach to the release or a compliance record.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What would this cost me otherwise?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A freelance Java release engineer bills about $80 an hour. The real cost is not the review though, it is the round-trip: a rejected bundle means you retag, rebuild, re-sign and re-upload, and any version number you already burned on a failed release is gone from that repository forever.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just ask ChatGPT or another AI chat?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. Maven Central Lint - pom.xml publish requirements (sources, checks the file you open against 16 rules from a rule set dated 2026-09-20, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does Maven Central Publish Gate actually do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads a pom.xml and reports every line that the Maven Central Portal will reject at upload: the retired oss.sonatype.org endpoint, nexus-staging-maven-plugin, SNAPSHOT versions and SNAPSHOT dependencies, missing name, description, url, licenses, developers or scm blocks, missing gpg, sources and javadoc plugins, plain http repositories, and system-scoped dependencies. Sixteen rules, each with the fix on the same line."}}, {"@type": "Question", "name": "Who is this for?", "acceptedAnswer": {"@type": "Answer", "text": "Java and Kotlin library maintainers who publish to Maven Central from their own build rather than through a release platform. That means one-person open source projects, small platform teams shipping an internal SDK to Central, and anyone who inherited a pom.xml written when oss.sonatype.org still accepted releases and has not cut a release since."}}, {"@type": "Question", "name": "Why will a free tool not do this?", "acceptedAnswer": {"@type": "Answer", "text": "mvn verify passes on a pom that Central rejects, because the Portal validates metadata that Maven itself never needs. A chatbot answers from training data that still describes the OSSRH staging flow Sonatype closed on 2025-06-30. The Portal itself only tells you after you upload, and only about the first thing it hits."}}, {"@type": "Question", "name": "What is free and what does the licence key add?", "acceptedAnswer": {"@type": "Answer", "text": "Free is complete for one file: open a pom.xml, get every blocker on it, fix them, ship. The licence key changes scope and ownership. It gates every pom.xml in a multi-module repository in one command, and writes the result to a REPORT.md file you keep and can attach to the release or a compliance record."}}, {"@type": "Question", "name": "What would this cost me otherwise?", "acceptedAnswer": {"@type": "Answer", "text": "A freelance Java release engineer bills about $80 an hour. The real cost is not the review though, it is the round-trip: a rejected bundle means you retag, rebuild, re-sign and re-upload, and any version number you already burned on a failed release is gone from that repository forever."}}, {"@type": "Question", "name": "Why not just ask ChatGPT or another AI chat?", "acceptedAnswer": {"@type": "Answer", "text": "A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. Maven Central Lint - pom.xml publish requirements (sources, checks the file you open against 16 rules from a rule set dated 2026-09-20, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:111757,slug:"maven-central-publish-gate",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/cargo-publish-gate"><span class="yj-rel-t">Cargo.toml Publish Gate - crates.io</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/firmware-release-gate"><span class="yj-rel-t">Firmware Release Gate for sdkconfig and prj.conf</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/renpy-release-gate"><span class="yj-rel-t">Ren&#x27;Py Release Gate</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/pyproject-release-gate"><span class="yj-rel-t">pyproject.toml Release Gate (PEP 639)</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/content-calendar-template"><span class="yj-rel-t">Content Calendar Template with Capacity &amp; Cost Calculator for Small Content Te</span><span class="yj-rel-p">$90</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/dotnet-eol-support-gate"><span class="yj-rel-t">.NET EOL &amp; CRA Support Window Gate</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section></body>
312
  </html>