Skip to content

Commit 5ece185

Browse files
committed
build maintenance page
1 parent 3c18d2c commit 5ece185

10 files changed

Lines changed: 707 additions & 10 deletions

File tree

.gitignore

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
temp
1+
.DS_Store
2+
.env
3+
/temp
24
node_modules
35
yarn-error.log
46
yarn.lock
5-
dist/*.js
6-
career-maps.json
7-
changelog.json
8-
changelog.xml
9-
changelog_latest.json
10-
bitrise-navigation-loader.js
11-
.DS_Store
12-
.env
7+
/dist/*.js
8+
/dist/*.LICENSE.txt
9+
/dist/maintenance.html
10+
/dist/images/*
11+
/career-maps.json
12+
/changelog.json
13+
/changelog.xml
14+
/changelog_latest.json
1315
/wrangler.toml
1416
.wrangler/tmp

build.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const webpackBuild = (config) =>
1212
});
1313
});
1414

15+
const { build: buildMaintenance } = require('./src/js/maintenance/build.js');
16+
1517
const build = async () => {
1618
// Build project with Webpack
1719
let webpackStats;
@@ -26,6 +28,10 @@ const build = async () => {
2628
} else {
2729
process.stdout.write(`Webpack build completed successfully:\n${webpackStats.toString({ colors: true })}\n\n`);
2830
}
31+
32+
// Build maintenance.html (depends on dist/404.js from webpack)
33+
await buildMaintenance();
34+
process.stdout.write('Maintenance page build completed successfully.\n\n');
2935
};
3036

3137
build().catch((error) => {

index.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,23 @@ const devMiddlewareOptions = {
141141
};
142142
const app = express();
143143

144-
app.use(devMiddleware(compiler, devMiddlewareOptions));
144+
const devMiddlewareInstance = devMiddleware(compiler, devMiddlewareOptions);
145+
app.use(devMiddlewareInstance);
145146
app.use(hotMiddleware(compiler));
146147

148+
const { generateMaintenanceHtml } = require('./src/js/maintenance/build.js');
149+
150+
app.get('/maintenance.html', async (req, res) => {
151+
try {
152+
// In dev, skip JS inlining — style-loader's HMR runtime needs publicPath from script.src
153+
const html = await generateMaintenanceHtml({ skipJs: true });
154+
res.setHeader('Content-Type', 'text/html');
155+
res.end(html);
156+
} catch (error) {
157+
res.status(500).end(`Failed to generate maintenance page: ${error.message}`);
158+
}
159+
});
160+
147161
app.get(/\/.*/, async (req, res) => {
148162
const urlObject = new URL(`http://${req.hostname}${req.url}`);
149163

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"build_changelog": "node ./src/js/changelog/build.js",
3232
"build_career_maps": "node ./src/js/career-maps/build.js",
3333
"build:navigation": "node ./src/js/bitrise-navigation/build.js ./dist/bitrise-navigation-loader.js",
34+
"build:maintenance": "node ./src/js/maintenance/build.js",
3435
"check_cert:bitrise": "node ./src/js/tools/cert_check.js bitrise.io",
3536
"check_cert:docs": "node ./src/js/tools/cert_check.js docs.bitrise.io"
3637
}

src/css/maintenance.css

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Figtree:wght@400;700&family=Source+Code+Pro&display=swap');
2+
3+
* {
4+
--radii-4: 0.25rem;
5+
6+
--space-8: 0.5rem;
7+
--space-12: 0.75rem;
8+
--space-16: 1rem;
9+
10+
--sizes-24: 1.5rem;
11+
12+
--neutral-10: #201b22;
13+
--purple-10: #2b0e3f;
14+
--purple-30: #5c2a7e;
15+
--purple-40: #7b3ba5;
16+
--purple-80: #d5adeb;
17+
--red-70: #ff8091;
18+
--green-70: #77cf8f;
19+
--orange-70: #fd9730;
20+
--yellow-70: #ebba00;
21+
22+
-webkit-font-smoothing: antialiased;
23+
-moz-osx-font-smoothing: grayscale;
24+
25+
box-sizing: border-box;
26+
}
27+
28+
html, body {
29+
height: 100%;
30+
margin: 0;
31+
}
32+
33+
body {
34+
color: #fff;
35+
font-family: "Figtree", sans-serif;
36+
font-size: 16px;
37+
line-height: 1.5em;
38+
39+
/* gradient background */
40+
background-image: linear-gradient(315deg, var(--purple-30), var(--purple-10));
41+
42+
display: flex;
43+
flex-direction: column;
44+
}
45+
46+
.container {
47+
width: 100%;
48+
height: 100%;
49+
max-width: 100rem;
50+
margin-left: auto;
51+
margin-right: auto;
52+
53+
/* global padding */
54+
padding-left: 5%;
55+
padding-right: 5%;
56+
57+
/* flex container */
58+
display: flex;
59+
gap: 3rem;
60+
justify-content: center;
61+
align-items: center;
62+
}
63+
64+
img, svg {
65+
vertical-align: middle;
66+
max-width: 100%;
67+
}
68+
69+
figure {
70+
margin: 0;
71+
}
72+
73+
section {
74+
display: flex;
75+
gap: 2rem;
76+
flex-direction: column;
77+
max-width: 40%;
78+
}
79+
80+
section + figure {
81+
height: 100%;
82+
}
83+
84+
section + figure img,
85+
section + figure svg {
86+
height: 100%;
87+
margin-left: auto;
88+
margin-right: auto;
89+
padding-top: 80px;
90+
}
91+
92+
section p {
93+
font-family: "Source Code Pro", monospace;
94+
text-transform: uppercase;
95+
margin: 0 0 1rem 0;
96+
}
97+
98+
h1 {
99+
margin: 0;
100+
}
101+
102+
h2 {
103+
margin-top: 0;
104+
margin-bottom: 2rem;
105+
font-size: 3rem;
106+
font-weight: 700;
107+
line-height: 1.2;
108+
text-wrap: balance;
109+
}
110+
111+
a.button {
112+
border: 1px solid var(--purple-40);
113+
background-color: var(--purple-40);
114+
color: #fff;
115+
text-align: center;
116+
border-radius: 4px;
117+
padding: .75rem 1.5rem;
118+
text-decoration: none;
119+
display: inline-block;
120+
}
121+
122+
@media screen and (max-width: 991px) {
123+
.container {
124+
grid-column-gap: 0rem;
125+
grid-row-gap: 0rem;
126+
flex-direction: column;
127+
}
128+
129+
section {
130+
max-width: 100%;
131+
padding-top: 3rem;
132+
}
133+
134+
section + figure img,
135+
section + figure svg {
136+
padding-top: var(--space-16);
137+
}
138+
}
139+
140+
@media screen and (max-width: 767px) {
141+
h2 {
142+
font-size: 36px;
143+
}
144+
}
145+
146+
@media screen and (max-width: 479px) {
147+
h2 {
148+
font-size: 28px;
149+
line-height: 1.4em;
150+
}
151+
}
152+
153+
/** Footer */
154+
155+
156+
footer {
157+
padding: var(--space-12) var(--space-16);
158+
display: flex;
159+
align-items: center;
160+
color: var(--purple-80);
161+
}
162+
163+
footer a {
164+
color: var(--purple-80);
165+
}
166+
167+
footer div {
168+
display: flex;
169+
width: 100%;
170+
align-items: center;
171+
}
172+
173+
footer div.copyright {
174+
justify-content: center;
175+
gap: var(--space-8);
176+
font-size: 0.875rem;
177+
line-height: 1.25rem;
178+
}
179+
180+
footer div.copyright svg {
181+
width: var(--sizes-24);
182+
height: var(--sizes-24);
183+
display: inline-block;
184+
line-height: 1em;
185+
flex-shrink: 0;
186+
vertical-align: middle;
187+
}
188+
189+
footer div.copyright p {
190+
margin: 0;
191+
}
192+
193+
footer div.links {
194+
justify-content: right;
195+
gap: var(--space-8);
196+
font-size: 0.875rem;
197+
line-height: 1.25rem;
198+
}
199+
200+
footer div.links a {
201+
text-decoration: none;
202+
}
203+
204+
@media screen and (max-width: 991px) {
205+
footer {
206+
flex-direction: column;
207+
gap: var(--space-16);
208+
}
209+
210+
footer div.links {
211+
order: 1;
212+
justify-content: center;
213+
}
214+
215+
footer div.status {
216+
order: 2;
217+
justify-content: center;
218+
}
219+
220+
footer div.copyright {
221+
order: 3;
222+
}
223+
}

src/html/maintenance.html

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>A quick tune-up is in progress. Faster builds on the way. (Under maintenance)</title>
5+
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport">
6+
<link rel="icon" type="image/x-icon" href="favicon.ico">
7+
<link rel="icon" type="image/svg+xml" href="favicon.svg">
8+
9+
<base href="/">
10+
<link rel="stylesheet" href="maintenance.css">
11+
<link rel="stylesheet" href="404.css">
12+
<script src="404.js"></script>
13+
14+
<!-- Google Tag Manager -->
15+
<script>window.dataLayer = window.dataLayer || [];</script>
16+
<script>!function(e,t,a,r,s){e[r]=e[r]||[],e[r].push({"gtm.start":new Date().getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],n=t.createElement(a);n.defer=!0,n.setAttribute("class","optanon-category-C0002"),n.src="https://www.googletagmanager.com/gtm.js?id="+s+("dataLayer"!=r?"&l="+r:""),g.parentNode.insertBefore(n,g)}(window,document,"script","dataLayer","GTM-TZK32GR");</script>
17+
<!-- End Google Tag Manager -->
18+
</head>
19+
20+
<body>
21+
<div class="container">
22+
<section>
23+
<header>
24+
<h1>
25+
<a href="/" title="Go to dashboard">
26+
<figure>
27+
<img src="maintenance/bitrise_logo.svg" alt="bitrise" />
28+
</figure>
29+
</a>
30+
</h1>
31+
</header>
32+
<main>
33+
<p>Under maintenance</p>
34+
<h2>A quick tune-up is in progress. Faster builds on the way.</h2>
35+
</main>
36+
</section>
37+
<figure>
38+
<img class="error" src="errors/bitrise_maintenance.svg" alt="Bitrise - Under Maintenance">
39+
</figure>
40+
</div>
41+
<footer>
42+
<div class="status" id="bitrise-status">
43+
<a href="https://status.bitrise.io/" rel="noreferrer" target="_blank">Status</a>
44+
</div>
45+
<div class="copyright">
46+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
47+
<path d="M13 4.20001C13 4.7523 12.5523 5.20001 12 5.20001C11.4477 5.20001 11 4.7523 11 4.20001C11 3.64773 11.4477 3.20001 12 3.20001C12.5523 3.20001 13 3.64773 13 4.20001Z" fill="currentColor"/>
48+
<path d="M7 12C6.24056 12 5.625 12.6134 5.625 13.37H8.375C8.375 12.6134 7.75944 12 7 12Z" fill="currentColor"/>
49+
<path d="M12 16.5C13.1045 16.5 14 15.6045 14 14.5H10C10 15.6045 10.8954 16.5 12 16.5Z" fill="currentColor"/>
50+
<path d="M16.6269 12C15.8685 12 15.2537 12.6148 15.2537 13.3731H18C18 12.6148 17.3853 12 16.6269 12Z" fill="currentColor"/>
51+
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.76043 6.42355C9.51446 6.12979 14.4127 6.12979 18.1667 6.42355C19.4978 6.52771 20.5592 7.51916 20.8091 8.79927C21.4305 11.9827 21.8075 14.3632 21.9243 17.0152C21.9932 18.581 20.8015 19.8973 19.2454 20C15.1377 20.271 8.78945 20.271 4.68172 20C3.12558 19.8973 1.93388 18.581 2.00285 17.0152C2.11965 14.3632 2.49661 11.9827 3.11809 8.79927C3.368 7.51916 4.42941 6.52771 5.76043 6.42355ZM18.0107 8.41746C14.3605 8.13182 9.56663 8.13182 5.91645 8.41746C5.51168 8.44913 5.16473 8.75376 5.08103 9.18248C4.46596 12.3331 4.11118 14.5995 4.00091 17.1032C3.98014 17.5747 4.33462 17.9728 4.81336 18.0043C8.83343 18.2695 15.0937 18.2695 19.1138 18.0043C19.5925 17.9728 19.947 17.5747 19.9262 17.1032C19.816 14.5995 19.4612 12.3331 18.8461 9.18248C18.7624 8.75376 18.4155 8.44913 18.0107 8.41746Z" fill="currentColor"/>
52+
</svg>
53+
<p>&copy; <script>document.write(new Date().getFullYear())</script> Bitrise Ltd.</p>
54+
</div>
55+
<div class="links">
56+
<a target="_blank" rel="noopener" href="https://docs.bitrise.io/">Docs</a>
57+
<a target="_blank" rel="noopener" href="https://docs.bitrise.io/en/bitrise-ci/api/api-overview.html">API</a>
58+
<a target="_blank" rel="noopener" href="https://bitrise.io/pricing">Pricing</a>
59+
<a target="_blank" rel="noopener" href="https://bitrise.io/platform/devops/security">Security</a>
60+
<a target="_blank" rel="noopener" href="https://go.bitrise.io/terms-of-service">Terms</a>
61+
<a target="_blank" rel="noopener" href="https://go.bitrise.io/privacy-policy">Privacy</a>
62+
<a target="_blank" rel="noopener" href="https://bitrise.io/cookie-policy">Cookie</a>
63+
</div>
64+
</footer>
65+
66+
<!-- Google Tag Manager (noscript) -->
67+
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-TZK32GR" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
68+
<!-- End Google Tag Manager (noscript) -->
69+
</body>
70+
</html>
Lines changed: 6 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)