Skip to content

Commit

Permalink
Added regexp matching support for verison names
Browse files Browse the repository at this point in the history
This commit adds support for filter version with a
regular expression instead of an exact match.
  • Loading branch information
thasso committed Apr 27, 2022
1 parent 76e0efd commit 61097d3
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 52 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ Note that the current implementation filters for the first 100 versions

## `version`

**Required** The name of the version that is being searched for, i.e. `1.0.0-SNAPSHOT`
**Required** A regular expression that is matched against the name of the
version that is being searched for, i.e. `1.0.0-SNAPSHOT` for an exact match
or `.*-SNAPSHOT` for all snapshots.

## `token`

Expand All @@ -32,7 +34,7 @@ A comma separated list of package version ids
## Example usage

```
- uses: castlabs/get-package-version-id-action@v1.0
- uses: castlabs/get-package-version-id-action@v2.0
id: versions
with:
versions: "1.0-SNAPSHOT"
Expand Down
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: 'Package Version IDs'
description: 'Find ids for package versions based on the version name'
inputs:
version:
description: 'The name of the version'
version:
description: 'A regular expression that is matched against the name of the version'
required: true

token:
Expand Down
141 changes: 117 additions & 24 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8471,34 +8471,127 @@ var __webpack_exports__ = {};
const core = __nccwpck_require__(2186);
const github = __nccwpck_require__(5438);

async function fetchIds(token, version) {
const octokit = github.getOctokit(token)
const {owner, repo} = github.context.repo
const response = await octokit.graphql(
`query Versions($repo: String!, $version: String!, $owner:String!) {
repository(name: $repo, owner: $owner) {
packages(first:100) {
// This is the main graphql query that we issue
// we do not filter here but rather get all package version
// and then use a filter on the results
//
// Note that this is double pagination and we need to deal with
// both cursors
const VERSIONS_QUERY = `query Versions($repo: String!, $owner:String!, $cursor_packages:String, $cursor_versions:String) {
repository(name: $repo, owner: $owner) {
packages(first:100, after: $cursor_packages) {
pageInfo {
endCursor
hasNextPage
}
nodes {
versions(first: 100, after: $cursor_versions) {
pageInfo {
endCursor
hasNextPage
}
nodes {
version(version: $version) {
id
}
id
version
}
}
}

}
`,
{
repo,
version,
owner
}
}
}`;

/**
*
* @param octokit The octokit instance
* @param repo The repo
* @param owner The ownser
* @param cursor_packages The packages cursor
* @param cursor_versions The versions cursor
* @return {Promise<*>} The raw response
*/
async function query(octokit, repo, owner, cursor_packages, cursor_versions) {
return octokit.graphql(
VERSIONS_QUERY,
{
repo,
owner,
cursor_packages,
cursor_versions
},
);
}

/**
* Takes the response from `query()` and a regex matcher and
* returns all version ids in the response where the version matches
*
* @param response The raw responses
* @param matcher The regex matcher
* @return {string[]} The version ids where the version matches
*/
function getIds(response, matcher) {
return response.repository.packages.nodes
.map(i => i.versions)
.flatMap(i => i.nodes)
.filter(i => i !== null)
.filter(i => matcher.test(i.version))
.map(i => i.id)
}

/**
* Takes the raw response from `query` and returns all version cursors
* if there are any
*
* @param response The response
* @return {string[]} All version cursors of empty array
*/
function versionCursors(response) {
return response.repository.packages.nodes
.map(i => i.version)
.filter(i => i !== null)
.map(i => i.id)
.join(',');
.map(i => i.versions)
.flatMap(i => i.pageInfo)
.filter(i => i.hasNextPage)
.map(i => i.endCursor)
}

/**
* Takes the raw response from `query` and returns all
* package cursors
*
* @param response The raw response
* @return {string[]} All package cursors if there are any
*/
function packagesCursors(response) {
return [response.repository.packages.pageInfo]
.filter(i => i.hasNextPage)
.map(i => i.endCursor)
}


async function fetchIds(token, version) {
const octokit = github.getOctokit(token)
const {owner, repo} = github.context.repo
// the matcher for the version string
const matcher = new RegExp('^' + version + '$')

// We start with a null as the first package cursor
let pkgCursors = [null];
// we collect the final results here
let versions = [];
while (pkgCursors.length > 0) {
for (const pc of pkgCursors) {
let response = await query(octokit, repo, owner, pc, null);
pkgCursors = packagesCursors(response);
versions = versions.concat(getIds(response, matcher));
for (const c of versionCursors(response)) {
response = await query(octokit, repo, owner, pc, c);
versions = versions.concat(getIds(response, matcher));
}
}
}

let results = [...new Set(versions)]
console.log(">> RESULTS ", JSON.stringify(results, null, 2))
return results
}

async function main() {
Expand All @@ -8507,12 +8600,12 @@ async function main() {
const token = core.getInput('token') || process.env.GITHUB_TOKEN;
core.info(`Fetch IDs for ${version}`)
const ids = await fetchIds(token, version);
core.info(`Found ${ids.split(',').length} ids for version '${version}': ${ids}`)
core.setOutput("ids", ids);
core.info(`Found ${ids.length} ids for version '${version}': ${ids.join(',')}`)
core.setOutput("ids", ids.join(','));
} catch (error) {
console.log(error)
core.setFailed(error.message);
}
}
}

main()
Expand Down
141 changes: 117 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,127 @@
const core = require('@actions/core');
const github = require('@actions/github');

async function fetchIds(token, version) {
const octokit = github.getOctokit(token)
const {owner, repo} = github.context.repo
const response = await octokit.graphql(
`query Versions($repo: String!, $version: String!, $owner:String!) {
repository(name: $repo, owner: $owner) {
packages(first:100) {
// This is the main graphql query that we issue
// we do not filter here but rather get all package version
// and then use a filter on the results
//
// Note that this is double pagination and we need to deal with
// both cursors
const VERSIONS_QUERY = `query Versions($repo: String!, $owner:String!, $cursor_packages:String, $cursor_versions:String) {
repository(name: $repo, owner: $owner) {
packages(first:100, after: $cursor_packages) {
pageInfo {
endCursor
hasNextPage
}
nodes {
versions(first: 100, after: $cursor_versions) {
pageInfo {
endCursor
hasNextPage
}
nodes {
version(version: $version) {
id
}
id
version
}
}
}
}
`,
{
repo,
version,
owner
}
}
}`;

/**
*
* @param octokit The octokit instance
* @param repo The repo
* @param owner The ownser
* @param cursor_packages The packages cursor
* @param cursor_versions The versions cursor
* @return {Promise<*>} The raw response
*/
async function query(octokit, repo, owner, cursor_packages, cursor_versions) {
return octokit.graphql(
VERSIONS_QUERY,
{
repo,
owner,
cursor_packages,
cursor_versions
},
);
}

/**
* Takes the response from `query()` and a regex matcher and
* returns all version ids in the response where the version matches
*
* @param response The raw responses
* @param matcher The regex matcher
* @return {string[]} The version ids where the version matches
*/
function getIds(response, matcher) {
return response.repository.packages.nodes
.map(i => i.versions)
.flatMap(i => i.nodes)
.filter(i => i !== null)
.filter(i => matcher.test(i.version))
.map(i => i.id)
}

/**
* Takes the raw response from `query` and returns all version cursors
* if there are any
*
* @param response The response
* @return {string[]} All version cursors of empty array
*/
function versionCursors(response) {
return response.repository.packages.nodes
.map(i => i.version)
.filter(i => i !== null)
.map(i => i.id)
.join(',');
.map(i => i.versions)
.flatMap(i => i.pageInfo)
.filter(i => i.hasNextPage)
.map(i => i.endCursor)
}

/**
* Takes the raw response from `query` and returns all
* package cursors
*
* @param response The raw response
* @return {string[]} All package cursors if there are any
*/
function packagesCursors(response) {
return [response.repository.packages.pageInfo]
.filter(i => i.hasNextPage)
.map(i => i.endCursor)
}


async function fetchIds(token, version) {
const octokit = github.getOctokit(token)
const {owner, repo} = github.context.repo
// the matcher for the version string
const matcher = new RegExp('^' + version + '$')

// We start with a null as the first package cursor
let pkgCursors = [null];
// we collect the final results here
let versions = [];
while (pkgCursors.length > 0) {
for (const pc of pkgCursors) {
let response = await query(octokit, repo, owner, pc, null);
pkgCursors = packagesCursors(response);
versions = versions.concat(getIds(response, matcher));
for (const c of versionCursors(response)) {
response = await query(octokit, repo, owner, pc, c);
versions = versions.concat(getIds(response, matcher));
}
}
}

let results = [...new Set(versions)]
console.log(">> RESULTS ", JSON.stringify(results, null, 2))
return results
}

async function main() {
Expand All @@ -37,12 +130,12 @@ async function main() {
const token = core.getInput('token') || process.env.GITHUB_TOKEN;
core.info(`Fetch IDs for ${version}`)
const ids = await fetchIds(token, version);
core.info(`Found ${ids.split(',').length} ids for version '${version}': ${ids}`)
core.setOutput("ids", ids);
core.info(`Found ${ids.length} ids for version '${version}': ${ids.join(',')}`)
core.setOutput("ids", ids.join(','));
} catch (error) {
console.log(error)
core.setFailed(error.message);
}
}
}

main()
Expand Down

0 comments on commit 61097d3

Please sign in to comment.