Skip to content

Commit 347d07c

Browse files
authored
Merge pull request #906 from wmde/feature/T411587-wbs-version-reporting
T416361 - [Release] Implement Version Report for WBS
2 parents 62b2d91 + e777da9 commit 347d07c

File tree

8 files changed

+225
-2
lines changed

8 files changed

+225
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ git pull
187187
Major releases and those containing significant changes are announced to the community. Plan with the Developer Advocate. Sync specifically on 🕑 timing as the announcement should go out shortly after the actual publish. Ideally within a couple of hours.
188188

189189
### 🚚 Releasing and Publishing
190-
Doing a release involves generating the version number bump and changelog files. Publishing images involves pushing them to DockerHub. Publishing Deploy is currently just done by pushing a new git tag to our repository.
190+
Doing a release involves generating the version number bump and changelog files. Publishing images involves pushing them to DockerHub. Publishing Deploy is currently just done by pushing a new git tag to our repository. You will need to make sure to update DEPLOY_VERSION in `deploy/docker-compose.yml` to match the version in `deploy/package.json` otherwise a related CI test will fail and not allow the release.
191191

192192
#### 🤖 Releasing and Publishing using CI
193193

build/build.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ done
3838

3939
# === Setup tags
4040

41+
IMAGE_VERSION=$(jq -r '.version' package.json)
42+
4143
# publish to Dockerhub
4244
if [ "$PUBLISH" == true ]; then
43-
IMAGE_VERSION=$(jq -r '.version' package.json)
4445
IMAGE_VERSION_MAJOR=$(echo "$IMAGE_VERSION" | cut -d '.' -f 1)
4546
IMAGE_VERSION_MINOR=$(echo "$IMAGE_VERSION" | cut -d '.' -f 1,2)
4647
TAGS+=(
@@ -94,6 +95,15 @@ for TAG in "${TAGS[@]}"; do
9495
BUILD_ARGS+=("--tag ${IMAGE_URL}:${TAG}")
9596
done
9697

98+
# === Wikibase Suite version metadata build args
99+
if [ "$IMAGE_NAME" = "wikibase" ]; then
100+
BUILD_ARGS+=("--build-arg" "WIKIBASE_IMAGE_VERSION=$IMAGE_VERSION")
101+
BUILD_TOOLS_GIT_SHA="$(git rev-parse --short HEAD 2>/dev/null || true)"
102+
if [ -n "$BUILD_TOOLS_GIT_SHA" ]; then
103+
BUILD_ARGS+=("--build-arg" "BUILD_TOOLS_GIT_SHA=$BUILD_TOOLS_GIT_SHA")
104+
fi
105+
fi
106+
97107
# === Transform vars in build.env to build args
98108

99109
while IFS='=' read -r key value; do

build/wikibase/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ FROM mediawiki AS wikibase
195195
LABEL org.opencontainers.image.source="https://github.com/wmde/wikibase-release-pipeline"
196196

197197
ARG GIT_CURRENT_REVISION
198+
ARG WIKIBASE_IMAGE_VERSION
199+
ARG BUILD_TOOLS_GIT_SHA
200+
201+
ENV WIKIBASE_IMAGE_VERSION=${WIKIBASE_IMAGE_VERSION} \
202+
BUILD_TOOLS_GIT_SHA=${BUILD_TOOLS_GIT_SHA}
198203

199204
# Set error_reporting PHP.ini settings
200205
# This is needed with PHP8+ and MediaWiki 1.39, as Wikibase contains deprecated code
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
if ( !isset( $wgAutoloadClasses ) || !is_array( $wgAutoloadClasses ) ) {
4+
$wgAutoloadClasses = [];
5+
}
6+
7+
if ( !isset( $wgAPIMetaModules ) || !is_array( $wgAPIMetaModules ) ) {
8+
$wgAPIMetaModules = [];
9+
}
10+
11+
$wgAutoloadClasses['ApiQueryWikibaseSuite'] = __DIR__ . '/includes/ApiQueryWikibaseSuite.php';
12+
$wgAPIMetaModules['wikibasesuite'] = 'ApiQueryWikibaseSuite';
13+
14+
$wgHooks['SoftwareInfo'][] = function( &$software ) {
15+
$wikibaseImageVersion = getenv( 'WIKIBASE_IMAGE_VERSION' );
16+
if ( $wikibaseImageVersion === false || trim( (string)$wikibaseImageVersion ) === '' ) {
17+
$wikibaseImageVersion = 'unknown';
18+
}
19+
20+
$software['[https://www.mediawiki.org/wiki/Wikibase/Suite Wikibase Suite Docker Image]'] = trim(
21+
(string)$wikibaseImageVersion
22+
);
23+
24+
$buildToolsSha = getenv( 'BUILD_TOOLS_GIT_SHA' );
25+
if ( $buildToolsSha !== false && trim( (string)$buildToolsSha ) !== '' ) {
26+
$software['[https://github.com/wmde/wikibase-release-pipeline Wikibase Suite Build Tools]'] = trim(
27+
(string)$buildToolsSha
28+
);
29+
}
30+
31+
$deployVersion = getenv( 'DEPLOY_VERSION' );
32+
if ( $deployVersion !== false && trim( (string)$deployVersion ) !== '' ) {
33+
$software['[https://www.mediawiki.org/wiki/Wikibase/Suite/Deploy Wikibase Suite Deploy]'] = trim(
34+
(string)$deployVersion
35+
);
36+
}
37+
38+
return true;
39+
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
use MediaWiki\Api\ApiQuery;
4+
use MediaWiki\Api\ApiQueryBase;
5+
use Wikimedia\ParamValidator\ParamValidator;
6+
7+
class ApiQueryWikibaseSuite extends ApiQueryBase {
8+
public function __construct( ApiQuery $queryModule, $moduleName ) {
9+
parent::__construct( $queryModule, $moduleName, 'wbs' );
10+
}
11+
12+
public function execute() {
13+
$params = $this->extractRequestParams();
14+
$props = $params['prop'] ?? [ 'versions' ];
15+
if ( !is_array( $props ) ) {
16+
$props = [ (string)$props ];
17+
}
18+
19+
$data = [];
20+
21+
if ( in_array( 'versions', $props, true ) ) {
22+
$data['versions'] = [
23+
'wikibase_image_version' => $this->getVersionValue( 'WIKIBASE_IMAGE_VERSION' ),
24+
'deploy_version' => $this->getVersionValue( 'DEPLOY_VERSION' ),
25+
'build_tools_git_sha' => $this->getVersionValue( 'BUILD_TOOLS_GIT_SHA' ),
26+
];
27+
}
28+
29+
$this->getResult()->addValue( 'query', $this->getModuleName(), $data );
30+
}
31+
32+
public function getAllowedParams() {
33+
return [
34+
'prop' => [
35+
ParamValidator::PARAM_TYPE => [ 'versions' ],
36+
ParamValidator::PARAM_ISMULTI => true,
37+
ParamValidator::PARAM_DEFAULT => 'versions',
38+
],
39+
];
40+
}
41+
42+
private function getVersionValue( string $envVar ): string {
43+
$value = getenv( $envVar );
44+
if ( $value === false ) {
45+
return 'unknown';
46+
}
47+
48+
$value = trim( (string)$value );
49+
if ( $value === '' ) {
50+
return 'unknown';
51+
}
52+
53+
return $value;
54+
}
55+
}

build/wikibase/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ Variables in **bold** are required on first launch without `LocalSettings.php` i
7070
| `WDQS_PUBLIC_ENDPOINT_URL` | undefined | Public URL of the WDQS API, such as the one provided by [wikibase/wdqs](https://hub.docker.com/r/wikibase/wdqs). Leave undefined to disable WDQS integration. |
7171
| `WDQS_PUBLIC_FRONTEND_URL` | undefined | Public URL of the WDQS frontend, such as [wikibase/wdqs-frontend](https://hub.docker.com/r/wikibase/wdqs-frontend). Leave undefined to disable WDQS integration. |
7272

73+
### Wikibase Suite version reporting
74+
75+
This image adds entries to the `Special:Version` page under the “Installed software” section. It reports the version of this image and, when available, the build-tools and deploy versions.
76+
77+
The same values are also exposed through the Action API metadata endpoint: `/w/api.php?action=query&meta=wikibasesuite&wbsprop=versions&format=json`
78+
7379
### Job runner
7480

7581
MediaWiki/Wikibase depends on [jobs being run in the background](https://www.mediawiki.org/wiki/Manual:Job_queue). This can be either done on HTTP request or by a dedicated job runner. The default configuration of this image requires an external job runner like this.

deploy/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ services:
2020
- wikibase-image-data:/var/www/html/images
2121
- quickstatements-data:/quickstatements/data
2222
environment:
23+
# Keep in sync with deploy/package.json version
24+
DEPLOY_VERSION: "5.0.1"
2325
METADATA_CALLBACK: ${METADATA_CALLBACK}
2426
MW_ADMIN_NAME: ${MW_ADMIN_NAME}
2527
MW_ADMIN_PASS: ${MW_ADMIN_PASS}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import page from '../../helpers/pages/page.js';
2+
3+
type WikibaseSuiteVersions = {
4+
wikibaseImageVersion: string;
5+
deployVersion: string;
6+
buildToolsGitSha: string;
7+
};
8+
9+
const getInstalledSoftwareVersionForProduct = async (
10+
productName: string
11+
): Promise<string> =>
12+
$(
13+
`//*[@id="sv-software"]//tr[td and contains(normalize-space(string(td[1])),"${ productName }")]/td[2]`
14+
).getText();
15+
16+
const normalizeVersionValue = ( value: string ): string => value.trim();
17+
const getVersionOrEmpty = (
18+
source: Record<string, string>,
19+
key: string
20+
): string => source[ key ] ?? '';
21+
22+
const getRuntimeVersionsFromWikibaseContainer =
23+
async (): Promise<WikibaseSuiteVersions> => {
24+
const runtimeOutput = await testEnv.runDockerComposeCmd(
25+
'exec -T wikibase sh -lc \'printf "wikibaseImageVersion=%s\\n" "$WIKIBASE_IMAGE_VERSION"; printf "deployVersion=%s\\n" "$DEPLOY_VERSION"; printf "buildToolsGitSha=%s\\n" "$BUILD_TOOLS_GIT_SHA"\''
26+
);
27+
const runtimeEntries = runtimeOutput
28+
.trim()
29+
.split( '\n' )
30+
.reduce( ( entries, line ) => {
31+
const [ key, ...rest ] = line.split( '=' );
32+
entries[ key ] = rest.join( '=' );
33+
return entries;
34+
}, {} as Record<string, string> );
35+
36+
return {
37+
wikibaseImageVersion:
38+
runtimeEntries.wikibaseImageVersion ?? '',
39+
deployVersion: runtimeEntries.deployVersion ?? '',
40+
buildToolsGitSha:
41+
runtimeEntries.buildToolsGitSha ?? ''
42+
};
43+
};
44+
45+
const getWikibaseSuiteApiVersions =
46+
async (): Promise<WikibaseSuiteVersions> => {
47+
const result = await browser.makeRequest(
48+
testEnv.vars.WIKIBASE_URL + '/w/api.php?action=query&meta=wikibasesuite&wbsprop=versions&format=json'
49+
);
50+
51+
const apiVersions = result.data.query.wikibasesuite.versions;
52+
return {
53+
wikibaseImageVersion:
54+
getVersionOrEmpty( apiVersions, 'wikibase_image_version' ),
55+
deployVersion: getVersionOrEmpty( apiVersions, 'deploy_version' ),
56+
buildToolsGitSha: getVersionOrEmpty( apiVersions, 'build_tools_git_sha' )
57+
};
58+
};
59+
60+
describe( 'Wikibase Suite version reporting', function () {
61+
let runtimeVersions: WikibaseSuiteVersions;
62+
63+
before( async function () {
64+
runtimeVersions = await getRuntimeVersionsFromWikibaseContainer();
65+
} );
66+
67+
it( 'Should expose suite versions through action API', async function () {
68+
const versions = await getWikibaseSuiteApiVersions();
69+
70+
expect( normalizeVersionValue( versions.wikibaseImageVersion ) ).toEqual(
71+
normalizeVersionValue( runtimeVersions.wikibaseImageVersion )
72+
);
73+
expect( normalizeVersionValue( versions.deployVersion ) ).toEqual(
74+
normalizeVersionValue( runtimeVersions.deployVersion )
75+
);
76+
expect(
77+
normalizeVersionValue( versions.buildToolsGitSha ).toLowerCase()
78+
).toEqual(
79+
normalizeVersionValue( runtimeVersions.buildToolsGitSha ).toLowerCase()
80+
);
81+
} );
82+
83+
it( 'Should include suite versions on Special:Version', async function () {
84+
await page.open( '/wiki/Special:Version' );
85+
const dockerImageVersion = await getInstalledSoftwareVersionForProduct(
86+
'Wikibase Suite Docker Image'
87+
);
88+
expect( normalizeVersionValue( dockerImageVersion ) ).toEqual(
89+
normalizeVersionValue( runtimeVersions.wikibaseImageVersion )
90+
);
91+
92+
const buildToolsVersion = await getInstalledSoftwareVersionForProduct(
93+
'Wikibase Suite Build Tools'
94+
);
95+
expect( normalizeVersionValue( buildToolsVersion ).toLowerCase() ).toEqual(
96+
normalizeVersionValue( runtimeVersions.buildToolsGitSha ).toLowerCase()
97+
);
98+
99+
const deployValue = await getInstalledSoftwareVersionForProduct(
100+
'Wikibase Suite Deploy'
101+
);
102+
expect( normalizeVersionValue( deployValue ) ).toEqual(
103+
normalizeVersionValue( runtimeVersions.deployVersion )
104+
);
105+
} );
106+
} );

0 commit comments

Comments
 (0)