Replaced the environment dependency version resolution to use the Docker HTTP API
Since it's possible that the latest git tag isn't a Docker page we should get the latest version directly from Docker instead. This commit adds support for the `/v2/repositories/library/<image>/tags` endpoint and figures out the latest version from the response.
This commit is contained in:
parent
07bbf56ace
commit
2e7f1056e0
|
@ -5,7 +5,7 @@ if [[ $1 ]]; then
|
|||
# Set environment variables for Docker
|
||||
#
|
||||
if ! [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
|
||||
WP_VERSION=$(git ls-remote --tags https://github.com/wordpress/wordpress.git | cut -f3 -d/ | grep -E '^\d+\.\d+(.\d+)*$' | tail -n 1)
|
||||
WP_VERSION=$(./bin/get-latest-docker-tag.js wordpress 5 2> /dev/null)
|
||||
fi
|
||||
if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
|
||||
export WORDPRESS_VERSION=$WP_VERSION
|
||||
|
@ -14,8 +14,7 @@ if [[ $1 ]]; then
|
|||
fi
|
||||
|
||||
if ! [[ $TRAVIS_PHP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
|
||||
PVER=$(git ls-remote --tags https://github.com/php/php-src.git | cut -f3 -d/ | grep -E '^php-\d+\.\d+(.\d+)*$' | tail -n 1)
|
||||
TRAVIS_PHP_VERSION=${PVER/php-/}
|
||||
TRAVIS_PHP_VERSION=$(./bin/get-latest-docker-tag.js php 7 2> /dev/null)
|
||||
fi
|
||||
if [[ $TRAVIS_PHP_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
|
||||
export DC_PHP_VERSION=$TRAVIS_PHP_VERSION
|
||||
|
@ -24,8 +23,7 @@ if [[ $1 ]]; then
|
|||
fi
|
||||
|
||||
if ! [[ $TRAVIS_MARIADB_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
|
||||
MVER=$(git ls-remote --tags https://github.com/mariadb/server.git | cut -f3 -d/ | grep -E '^mariadb-\d\d\.\d+(.\d+)*$' | tail -n 1)
|
||||
TRAVIS_MARIADB_VERSION=${MVER/mariadb-/}
|
||||
TRAVIS_MARIADB_VERSION=$(./bin/get-latest-docker-tag.js mariadb 10 2> /dev/null)
|
||||
fi
|
||||
if [[ $TRAVIS_MARIADB_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then
|
||||
export DC_MARIADB_VERSION=$TRAVIS_MARIADB_VERSION
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const https = require( 'https' );
|
||||
const semver = require( 'semver' );
|
||||
|
||||
/**
|
||||
* Fetches the latest tag from a page using the Docker HTTP api.
|
||||
*
|
||||
* @param {string} image The image we're looking at the tags for.
|
||||
* @param {string} nameSearch The string we're searching for in the name.
|
||||
* @param {number} page The page we want to request.
|
||||
* @return {Promise} A promise resolving to the JSON content for the page.
|
||||
*/
|
||||
async function fetchLatestTagFromPage( image, nameSearch, page ) {
|
||||
return new Promise(
|
||||
( resolve, reject ) => {
|
||||
const queryParams = new URLSearchParams( {
|
||||
page_size: 100,
|
||||
ordering: 'last_updated',
|
||||
page: page,
|
||||
name: nameSearch
|
||||
} );
|
||||
const options = {
|
||||
hostname: 'hub.docker.com',
|
||||
port: 443,
|
||||
path: '/v2/repositories/library/' + image + '/tags?' + queryParams.toString(),
|
||||
method: 'GET',
|
||||
};
|
||||
|
||||
const req = https.request(options, (res) => {
|
||||
let data = '';
|
||||
|
||||
res.on( 'data', d => { data += d; } );
|
||||
res.on( 'end', () => {
|
||||
data = JSON.parse( data );
|
||||
if ( ! data.count ) {
|
||||
reject( "No image '" + image + '" found' );
|
||||
} else {
|
||||
let latestTag = null;
|
||||
for ( let tag of data.results ) {
|
||||
tag.semver = tag.name.match( /^\d+\.\d+(.\d+)*$/ );
|
||||
if ( ! tag.semver ) {
|
||||
continue;
|
||||
}
|
||||
tag.semver = semver.coerce( tag.semver[0] );
|
||||
if ( ! latestTag || semver.gt( tag.semver, latestTag.semver ) ) {
|
||||
latestTag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
resolve( {
|
||||
latestTag,
|
||||
isLastPage: ! data.next,
|
||||
} );
|
||||
}
|
||||
} )
|
||||
});
|
||||
req.end();
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the latest version of the image that meets our name criteria.
|
||||
*
|
||||
* @param {string} image The image we're searching for.
|
||||
* @param {string} nameSearch The name we're searching for.
|
||||
* @return {Promise} A promise resolving to the latest version of a package.
|
||||
*/
|
||||
function findLatestVersion( image, nameSearch ) {
|
||||
let page = 1;
|
||||
let earliestUpdated = null;
|
||||
let latestVersion = null;
|
||||
|
||||
// Repeat the requests until we've read as many pages as necessary.
|
||||
const paginationFn = function ( result ) {
|
||||
// We can save on unnecessarily loading every page by short-circuiting when
|
||||
// the number of days between the first recorded version and the
|
||||
// one from this page becomes excessive.
|
||||
const lastUpdate = Date.parse( result.latestTag.last_updated );
|
||||
if ( ! earliestUpdated ) {
|
||||
earliestUpdated = lastUpdate;
|
||||
} else {
|
||||
const daysSinceEarliestUpdate = ( earliestUpdated - lastUpdate ) / ( 1000 * 3600 * 24 );
|
||||
if ( daysSinceEarliestUpdate > 15 ) {
|
||||
result.isLastPage = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! latestVersion || semver.gt( result.latestTag.semver, latestVersion ) ) {
|
||||
latestVersion = result.latestTag.semver;
|
||||
}
|
||||
|
||||
if ( ! result.isLastPage ) {
|
||||
return fetchLatestTagFromPage( image, nameSearch, ++page ).then( paginationFn );
|
||||
}
|
||||
|
||||
return latestVersion.toString();
|
||||
};
|
||||
|
||||
return fetchLatestTagFromPage( image, nameSearch, page ).then( paginationFn );
|
||||
}
|
||||
|
||||
const image = process.argv[2];
|
||||
const nameSearch = process.argv[3];
|
||||
if ( ! image || ! nameSearch ) {
|
||||
console.error( 'Usage: get-latest-docker-tag.js <image> <name-search>' );
|
||||
process.exit( 1 );
|
||||
}
|
||||
|
||||
findLatestVersion( image, nameSearch ).then(
|
||||
( latestVersion ) => {
|
||||
console.info( latestVersion );
|
||||
process.exit( 0 );
|
||||
},
|
||||
( error ) => {
|
||||
console.error( error );
|
||||
process.exit( 1 );
|
||||
}
|
||||
)
|
|
@ -97,6 +97,13 @@
|
|||
"browserslist": "^4.12.0",
|
||||
"invariant": "^2.2.4",
|
||||
"semver": "^5.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/core": {
|
||||
|
@ -134,6 +141,11 @@
|
|||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -174,6 +186,13 @@
|
|||
"invariant": "^2.2.4",
|
||||
"levenary": "^1.1.1",
|
||||
"semver": "^5.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/helper-create-class-features-plugin": {
|
||||
|
@ -980,6 +999,13 @@
|
|||
"invariant": "^2.2.2",
|
||||
"levenary": "^1.1.1",
|
||||
"semver": "^5.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/preset-modules": {
|
||||
|
@ -4585,6 +4611,13 @@
|
|||
"semver": "^5.5.0",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"crypto-random-string": {
|
||||
|
@ -4923,6 +4956,13 @@
|
|||
"react-is": "^16.13.1",
|
||||
"react-test-renderer": "^16.0.0-0",
|
||||
"semver": "^5.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"enzyme-adapter-utils": {
|
||||
|
@ -4936,6 +4976,13 @@
|
|||
"object.fromentries": "^2.0.2",
|
||||
"prop-types": "^15.7.2",
|
||||
"semver": "^5.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"enzyme-shallow-equal": {
|
||||
|
@ -8693,6 +8740,13 @@
|
|||
"requires": {
|
||||
"pify": "^4.0.1",
|
||||
"semver": "^5.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"makeerror": {
|
||||
|
@ -9049,6 +9103,11 @@
|
|||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9086,6 +9145,13 @@
|
|||
"semver": "^5.5.0",
|
||||
"shellwords": "^0.1.1",
|
||||
"which": "^1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-pty": {
|
||||
|
@ -9112,6 +9178,13 @@
|
|||
"resolve": "^1.10.0",
|
||||
"semver": "2 || 3 || 4 || 5",
|
||||
"validate-npm-package-license": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"normalize-path": {
|
||||
|
@ -9382,6 +9455,14 @@
|
|||
"registry-auth-token": "^3.0.1",
|
||||
"registry-url": "^3.0.3",
|
||||
"semver": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"parent-module": {
|
||||
|
@ -10220,9 +10301,10 @@
|
|||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"semver-diff": {
|
||||
"version": "2.1.0",
|
||||
|
@ -10231,6 +10313,14 @@
|
|||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^5.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"set-blocking": {
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
"@babel/polyfill": "^7.8.3",
|
||||
"@babel/preset-env": "^7.8.4",
|
||||
"@wordpress/eslint-plugin": "^4.0.0",
|
||||
"ndb": "^1.1.5"
|
||||
"ndb": "^1.1.5",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
|
Loading…
Reference in New Issue