Skip to content

Commit

Permalink
manifest sourceDep check worflow (#3806)
Browse files Browse the repository at this point in the history
* First draft - manifest sourceDep check worflow

Signed-off-by: MarkAckert <[email protected]>

* lock in package versions

Signed-off-by: MarkAckert <[email protected]>

* working-dir

Signed-off-by: MarkAckert <[email protected]>

* forgot checkout

Signed-off-by: MarkAckert <[email protected]>

* handle protected/unprotected branches, fix orion

Signed-off-by: MarkAckert <[email protected]>

* static pkg version

Signed-off-by: MarkAckert <[email protected]>

* don't quit early

Signed-off-by: MarkAckert <[email protected]>

* adjust so all applicable warnings always appear

Signed-off-by: MarkAckert <[email protected]>

* few small errors

Signed-off-by: MarkAckert <[email protected]>

* correct client name

Signed-off-by: MarkAckert <[email protected]>

* restrict commit checks to sha hash

Signed-off-by: MarkAckert <[email protected]>

* empty commit (trigger)

Signed-off-by: MarkAckert <[email protected]>

* empty commit

Signed-off-by: MarkAckert <[email protected]>

---------

Signed-off-by: MarkAckert <[email protected]>
  • Loading branch information
MarkAckert authored Apr 18, 2024
1 parent 4a8cc0e commit 2d56f3e
Show file tree
Hide file tree
Showing 5 changed files with 493 additions and 9 deletions.
159 changes: 159 additions & 0 deletions .github/scripts/manifest_verification/check_sources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// This script checks that the manifest sourceDependencies are reachable.

const core = require('@actions/core');
const fs = require('fs-extra');

const results = {
success: 'found_matching_commit_or_tag',
warn: 'found_matching_branch',
fail: 'no_matching_tag_or_branch'
}

function is_sha(item) {
return /^[0-9a-f]{7}$/.test(item) || /^[0-9a-f]{40}$/.test(item)
}

function isRcOrMaster(branchName) {
return /v[0-9]\.x\/(rc|master)/i.test(branchName);
}

async function main() {

if (process.env['BASE_REF'] == null) {
core.setFailed('This script requires the BASE_REF env to bet set.');
return;
}

if (process.env['GITHUB_TOKEN'] == null) {
core.setFailed('This script requires the GITHUB_TOKEN env to be set.');
return;
}

const baseRef = process.env['BASE_REF'].trim();

const github = require('@actions/github')
const octokit = github.getOctokit(process.env['GITHUB_TOKEN']);

// expect script to be run from repo root
const sourceDeps = fs.readJSONSync('./manifest.json.template').sourceDependencies;

/**
* Source dep structure is below:
*
* [
* {
* "componentGroup": "Performance Timing Utility",
* "entries": [{
* "repository": "perf-timing",
* "tag": "master",
* "destinations": ["Zowe CLI Package"]
* }]
* },
* { ...same structure as prior...}
* ]
*/

const analyzedRepos = [];

for (const dep of sourceDeps) {
for (const entry of dep.entries) {
const repo = entry.repository;
const tag = entry.tag;

// octokit ref/commit_sha APIs work for branches/tags, and we only want to test when its an actual hash
if (is_sha(tag)) {
const isCommit = await octokit.rest.repos.getCommit({
owner: 'zowe',
repo: repo,
ref: tag
}).then((resp) => {
if (resp.status < 400) {
return true;
}
return false;
})

// Pinning repos with a commit is ok
if (isCommit) {
analyzedRepos.push({repository: repo, tag: tag, result: results.success});
continue;
}
}

// If not a commit, check repo tags
const tags = await octokit.rest.repos.listTags({
owner: 'zowe',
repo: repo,
}).then((resp) => {
if (resp.status < 400) {
return resp.data;
}
return [];
})

const knownTag = tags.find((item) => item.name === tag);
if (knownTag != null && knownTag.name.trim().length > 0) {
analyzedRepos.push({repository: repo, tag: tag, result: results.success});
continue;
}

// if we didn't find tag, look at branches
// 2 REST Requests, unset protected was operating as protected=false
const protBranches = await octokit.rest.repos.listBranches({
owner: 'zowe',
repo: repo,
protected: true
}).then((resp) => {
if (resp.status < 400) {
return resp.data;
}
return [];
})
const unProtBranches = await octokit.rest.repos.listBranches({
owner: 'zowe',
repo: repo,
protected: false
}).then((resp) => {
if (resp.status < 400) {
return resp.data;
}
return [];
})

const branches = [...protBranches, ...unProtBranches];

const knownBranch = branches.find((item) => item.name === tag);
if (knownBranch != null && knownBranch.name.trim().length > 0) {
analyzedRepos.push({repository: repo, tag: tag, result: results.warn});
continue;
}

// if we didn't find commit, tag or branch
analyzedRepos.push({repository: repo, tag: tag, result: results.fail});
}
}

let didFail = false;

const failRepos = analyzedRepos.filter((item) => item.result === results.fail);
if (failRepos != null && failRepos.length > 0) {
core.warning('There are manifest sourceDependencies without a matching tag or branch. Review the output and update the manifest.');
core.warning('The following repositories do not have a matching commit hash, tag or branch: ' + JSON.stringify(failRepos, null, {indent: 4}))
didFail = true;
}

const warnRepos = analyzedRepos.filter((item) => item.result === results.warn) ;
if (warnRepos != null && warnRepos.length > 0) {
if (isRcOrMaster(baseRef)) {
core.warning('Merges to RC and master require tags or commit hashes instead of branches for sourceDependencies.')
didFail = true
}
core.warning('The following repositories have a branch instead of tag: ' + JSON.stringify(warnRepos, null, {indent: 4}))
}

if (didFail) {
core.setFailed('The manifest validation was not successful. Review the warning output for more details.');
}

}
main()
Loading

0 comments on commit 2d56f3e

Please sign in to comment.