Skip to content

Commit e6bd9a5

Browse files
authored
Merge pull request #1607 from shivammathur/pre-release-builds
Add windows QA builds
2 parents cf80cca + 549f61e commit e6bd9a5

File tree

7 files changed

+740
-122
lines changed

7 files changed

+740
-122
lines changed

backend/win-qa-releases.json

Lines changed: 428 additions & 0 deletions
Large diffs are not rendered by default.

downloads.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<p class="panel"><a href="download-docs.php">Documentation Download</a></p>
2121
<p class="panel"><a href="download-logos.php">PHP Logos</a></p>
2222
23-
<p class="panel"><a href="/release-candidates.php">Release Candidates</a></p>
23+
<p class="panel"><a href="/pre-release-builds.php">Pre-Release Builds</a></p>
2424
<p class="panel"><a href="/git.php">Development Sources (git)</a></p>
2525
<p class="panel"><a href="/releases/">Old Archives</a></p>
2626
';

error.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// Get URI for this request, strip leading slash
2020
// See langchooser.inc for more info on STRIPPED_URI
2121
$URI = substr($_SERVER['STRIPPED_URI'], 1);
22+
$queryString = $_SERVER['QUERY_STRING'] ?? '';
2223

2324
// ============================================================================
2425
// Mozilla Search Sidebar plugin resource file handling (need to be mirror
@@ -538,6 +539,7 @@
538539
# Removed pages
539540
"tips.php" => "urlhowto",
540541
"tips" => "urlhowto",
542+
"release-candidates.php" => "pre-release-builds",
541543
];
542544

543545
$external_redirects = [
@@ -677,7 +679,11 @@
677679
$URI = $uri_aliases[$URI];
678680
/* If it was a page alias, redirect right away */
679681
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/$URI.php")) {
680-
mirror_redirect("/$URI.php");
682+
$target = "/$URI.php";
683+
if ($queryString !== '') {
684+
$target .= (strpos($target, '?') === false ? '?' : '&') . $queryString;
685+
}
686+
mirror_redirect($target);
681687
}
682688
}
683689

get-involved.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<h3 class="content-title" id="ways-to-contribute">Four Best Ways to Contribute</h3>
2727

2828
<ol class="content-box listed">
29-
<li>Running test suites in <a href="/release-candidates.php">RC</a>
29+
<li>Running test suites in <a href="/pre-release-builds.php">RC</a>
3030
and <a href="https://php.net/releases">release</a> distributions of PHP</li>
3131
<li>Help finding and diagnosing failed tests, see
3232
the <a href="https://qa.php.net/write-test.php">phpt documentation</a></li>

openapi.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ paths:
9292
type: string
9393
format: date-time
9494

95-
"/release-candidates.php":
95+
"/pre-release-builds.php":
9696
get:
97-
summary: "Currently RC versions of PHP."
97+
summary: "Current pre-release versions of PHP."
9898
parameters:
9999
- in: query
100100
name: format

pre-release-builds.php

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
<?php
2+
$_SERVER['BASE_PAGE'] = 'qa.php';
3+
include_once __DIR__ . '/include/prepend.inc';
4+
include_once __DIR__ . '/include/release-qa.php';
5+
6+
if (isset($_GET["format"])) {
7+
$output = $QA_RELEASES;
8+
9+
if (($_GET['only'] ?? null) === 'dev_versions') {
10+
$output = $output['reported'];
11+
}
12+
13+
switch ($_GET['format'] ?? null) {
14+
case 'json':
15+
header('Content-Type: application/json; charset=UTF-8');
16+
echo json_encode($output);
17+
exit;
18+
case 'serialize':
19+
default:
20+
header('Content-Type: text/plain; charset=UTF-8');
21+
echo serialize($output);
22+
exit;
23+
}
24+
}
25+
26+
$SITE_UPDATE = date("D M d H:i:s Y T", filectime(__FILE__));
27+
28+
$SIDEBAR_DATA = '
29+
<div class="panel">
30+
Test Releases
31+
<div class="body">
32+
The downloads on this page are not meant to be run in production. They are
33+
for testing only.
34+
</div>
35+
36+
<div class="body">
37+
If you find a problem when running your library or application with these
38+
builds, please file a report on
39+
<a href="https://github.com/php/php-src/issues/">GitHub Issues</a>.
40+
</div>
41+
<br/>
42+
QA Releases API
43+
<div class="body">
44+
<p>
45+
The QA API is based on the query string.
46+
</p>
47+
<p>
48+
Pass in the <code>format</code> parameter, with <code>serialize</code> or
49+
<code>json</code> as value to obtain all information:
50+
</p>
51+
<ul>
52+
<li><a href="https://php.net/pre-release-builds.php?format=json">/pre-release-builds.php?format=json</a></li>
53+
<li><a href="https://php.net/pre-release-builds.php?format=serialize">/pre-release-builds.php?format=serialize</a></li>
54+
</ul>
55+
<p>
56+
To only try dev version numbers, add <code>only=dev_versions</code>:
57+
</p>
58+
<ul>
59+
<li><a href="https://php.net/pre-release-builds.php?format=json&only=dev_versions">/pre-release-builds.php?format=json&only=dev_versions</a></li>
60+
</ul>
61+
</div>
62+
</div>
63+
';
64+
65+
site_header("Pre-Release Builds", [
66+
'current' => 'downloads',
67+
]);
68+
69+
?>
70+
<h1>Pre-Release Builds</h1>
71+
<p>
72+
This page contains links to the Pre-release builds that the release
73+
managers create before each actual release. These builds are meant for the
74+
community to test whether no inadvertent changes have been made, and
75+
whether no regressions have been introduced.
76+
</p>
77+
78+
<h3>Source Builds:</h3>
79+
<?php if (!empty($QA_RELEASES['releases'])) : ?>
80+
<?php $plural = count($QA_RELEASES['releases']) > 1 ? 's' : ''; ?>
81+
82+
<?php foreach ($QA_RELEASES['releases'] as $pversion => $info) : ?>
83+
<h3 class="title">
84+
PHP <?php echo $info['version']; ?>
85+
</h3>
86+
<div class="content-box">
87+
88+
<ul>
89+
<?php foreach ($info['files'] as $file_type => $file_info) : ?>
90+
<li>
91+
<a href="<?php echo $file_info['path'] ?>"><?php echo "php-{$info['version']}.tar.{$file_type}"; ?></a>
92+
<span class="releasedate"><?php echo date('d M Y', strtotime($info['date'])); ?></span>
93+
<?php foreach ($QA_CHECKSUM_TYPES as $algo): ?>
94+
<span class="<?php echo $algo; ?>">
95+
<?php if (isset($file_info[$algo]) && strlen($file_info[$algo])) : ?>
96+
<?php echo $file_info[$algo]; ?>
97+
<?php else: ?>
98+
<em><small>No checksum value available</small></em>)&nbsp;
99+
<?php endif; ?>
100+
<?php endforeach; ?>
101+
</li>
102+
<?php endforeach; ?>
103+
</ul>
104+
<?php endforeach; ?>
105+
<?php else: ?>
106+
<span class='lihack'>There are no QA releases available at the moment to test.</span>
107+
<?php endif; ?>
108+
109+
<h3>Windows Builds:</h3>
110+
<?php
111+
$winQaFile = __DIR__ . '/backend/win-qa-releases.json';
112+
$winQaBase = 'https://downloads.php.net/~windows/qa/';
113+
$winQaMessage = '';
114+
$winQaReleases = [];
115+
116+
if (is_readable($winQaFile)) {
117+
$raw = @file_get_contents($winQaFile);
118+
$decoded = $raw ? json_decode($raw, true) : null;
119+
if (is_array($decoded)) {
120+
$allowedBranches = [];
121+
if (!empty($QA_RELEASES['releases'])) {
122+
foreach (array_keys($QA_RELEASES['releases']) as $pversion) {
123+
$parts = explode('.', (string) $pversion);
124+
if (count($parts) >= 2) {
125+
$branchKey = $parts[0] . '.' . $parts[1];
126+
$allowedBranches[$branchKey] = true;
127+
}
128+
}
129+
}
130+
131+
$buildLabel = static function (string $key, array $entry): string {
132+
$tool = 'VS';
133+
if (strpos($key, 'vs17') !== false) {
134+
$tool .= '17';
135+
} elseif (strpos($key, 'vs16') !== false) {
136+
$tool .= '16';
137+
} elseif (strpos($key, 'vc15') !== false) {
138+
$tool = 'VC15';
139+
}
140+
141+
$arch = (strpos($key, 'x64') !== false) ? 'x64' : ((strpos($key, 'x86') !== false) ? 'x86' : '');
142+
$ts = (strpos($key, 'nts') !== false) ? 'Non Thread Safe' : 'Thread Safe';
143+
144+
if (strncmp($key, 'nts-', 4) === 0) {
145+
$ts = 'Non Thread Safe';
146+
} elseif (strncmp($key, 'ts-', 3) === 0) {
147+
$ts = 'Thread Safe';
148+
}
149+
150+
return trim(($tool ? $tool . ' ' : '') . ($arch ? $arch . ' ' : '') . $ts);
151+
};
152+
153+
$packageNames = [
154+
'zip' => 'Zip',
155+
'debug_pack' => 'Debug Pack',
156+
'devel_pack' => 'Development package (SDK to develop PHP extensions)',
157+
];
158+
159+
$makeListItem = static function (string $label, array $fileInfo, ?string $mtime, bool $includeSha) use ($winQaBase): ?string {
160+
$path = $fileInfo['path'] ?? '';
161+
if ($path === '') {
162+
return null;
163+
}
164+
165+
$href = $winQaBase . ltrim($path, '/');
166+
$size = $fileInfo['size'] ?? '';
167+
$sha = $fileInfo['sha256'] ?? '';
168+
$hrefAttr = htmlspecialchars($href, ENT_QUOTES, 'UTF-8');
169+
$labelText = htmlspecialchars($label, ENT_QUOTES, 'UTF-8');
170+
171+
$parts = ['<a href="' . $hrefAttr . '">' . $labelText . '</a>'];
172+
if ($size !== '') {
173+
$parts[] = '<span class="size">' . htmlspecialchars($size, ENT_QUOTES, 'UTF-8') . '</span>';
174+
}
175+
176+
if ($mtime) {
177+
$timestamp = strtotime($mtime);
178+
if ($timestamp) {
179+
$parts[] = '<span class="releasedate">' . gmdate('d M Y', $timestamp) . '</span>';
180+
}
181+
}
182+
183+
if ($includeSha && $sha !== '') {
184+
$parts[] = '<span class="sha256">' . htmlspecialchars($sha, ENT_QUOTES, 'UTF-8') . '</span>';
185+
}
186+
187+
return '<li>' . implode(' ', $parts) . '</li>';
188+
};
189+
190+
foreach ($decoded as $branch => $info) {
191+
if (!is_array($info) || empty($info['version'])) {
192+
continue;
193+
}
194+
195+
if ($branch === 'comment') {
196+
continue;
197+
}
198+
199+
if (!empty($allowedBranches) && empty($allowedBranches[$branch])) {
200+
continue;
201+
}
202+
203+
$topItems = [];
204+
if (!empty($info['source']) && is_array($info['source'])) {
205+
$item = $makeListItem('Download source code', $info['source'], $info['source']['mtime'] ?? null, false);
206+
if ($item !== null) {
207+
$topItems[] = $item;
208+
}
209+
}
210+
211+
if (!empty($info['test_pack']) && is_array($info['test_pack'])) {
212+
$item = $makeListItem('Download tests package (phpt)', $info['test_pack'], $info['test_pack']['mtime'] ?? null, false);
213+
if ($item !== null) {
214+
$topItems[] = $item;
215+
}
216+
}
217+
218+
$builds = [];
219+
foreach ($info as $buildKey => $entry) {
220+
if (!is_array($entry) || in_array($buildKey, ['version', 'source', 'test_pack'], true)) {
221+
continue;
222+
}
223+
224+
$label = $buildLabel($buildKey, $entry);
225+
if ($label === '') {
226+
continue;
227+
}
228+
229+
$packageItems = [];
230+
foreach ($packageNames as $pkgKey => $pkgLabel) {
231+
if (empty($entry[$pkgKey]) || !is_array($entry[$pkgKey])) {
232+
continue;
233+
}
234+
235+
$rendered = $makeListItem($pkgLabel, $entry[$pkgKey], $entry['mtime'] ?? null, true);
236+
if ($rendered !== null) {
237+
$packageItems[] = $rendered;
238+
}
239+
}
240+
241+
if (empty($packageItems)) {
242+
continue;
243+
}
244+
245+
$builds[] = [
246+
'label' => $label,
247+
'items' => $packageItems,
248+
];
249+
}
250+
251+
if (empty($topItems) && empty($builds)) {
252+
continue;
253+
}
254+
255+
$winQaReleases[] = [
256+
'version_label' => $info['version'],
257+
'top_items' => $topItems,
258+
'builds' => $builds,
259+
];
260+
}
261+
} else {
262+
$winQaMessage = 'Windows QA release index could not be parsed.';
263+
}
264+
} else {
265+
$winQaMessage = 'Windows QA release index is unavailable.';
266+
}
267+
268+
if ($winQaMessage !== '') {
269+
echo '<p>', htmlspecialchars($winQaMessage), '</p>';
270+
} elseif (empty($winQaReleases)) {
271+
echo "<p>No Windows QA builds match the currently active QA releases.</p>";
272+
} else {
273+
foreach ($winQaReleases as $release) {
274+
$versionLabel = $release['version_label'];
275+
276+
echo '<h3 class="title">PHP ', htmlspecialchars($versionLabel), '</h3>';
277+
echo '<div class="content-box windows-qa">';
278+
if (!empty($release['top_items'])) {
279+
echo '<ul class="windows-qa-list">';
280+
foreach ($release['top_items'] as $item) {
281+
echo $item;
282+
}
283+
echo '</ul>';
284+
}
285+
286+
foreach ($release['builds'] as $build) {
287+
echo '<h5 style="margin:-10px 0 0 10px;">' . $build['label'] . '</h5>';
288+
echo '<ul class="windows-qa-list">';
289+
foreach ($build['items'] as $item) {
290+
echo $item;
291+
}
292+
echo '</ul>';
293+
}
294+
echo '</div>';
295+
}
296+
}
297+
?>
298+
299+
<?php
300+
site_footer(['sidebar' => $SIDEBAR_DATA]);
301+

0 commit comments

Comments
 (0)