-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🔀 Merge pull request #1 from awesome-algorand/experimental/package-pu…
…blisher ♻️ convert to awesome-algorand
- Loading branch information
Showing
28 changed files
with
514 additions
and
676 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
|
||
/** | ||
* Get the release body and url | ||
* @param {string} repo | ||
* @param {string} tag | ||
* @param {string} [token] | ||
* @return {Promise<{body: *, url: *}>} | ||
*/ | ||
export async function getRelease(repo, tag, token) { | ||
let headers = { | ||
'Accept': 'application/vnd.github.v3+json', | ||
}; | ||
if (typeof token === 'string') { | ||
headers['Authorization'] = `Bearer ${token}`; | ||
} | ||
return await fetch(`https://api.github.com/repos/${repo}/releases/tags/${tag}`, { | ||
method: 'GET', | ||
headers, | ||
}).then(r => { | ||
if (r.status === 404) { | ||
return null; | ||
} | ||
if(r.status !== 200){ | ||
console.error(r); | ||
throw new Error(r.statusText); | ||
} | ||
return r.json().then(r => ({ | ||
body: r['body'], | ||
url: r['html_url'], | ||
})); | ||
}); | ||
} | ||
|
||
|
||
|
||
export async function getTags(repo, token) { | ||
let headers = { | ||
'Accept': 'application/vnd.github.v3+json', | ||
}; | ||
if (typeof token === 'string') { | ||
headers['Authorization'] = `Bearer ${token}`; | ||
} | ||
|
||
return await fetch(`https://api.github.com/repos/${repo}/git/refs/tags`, { | ||
method: 'GET', | ||
headers, | ||
}).then(r => { | ||
if (r.status !== 200) { | ||
console.error(r); | ||
throw new Error(r.statusText); | ||
} | ||
return r.json(); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {spawn as _spawn} from 'node:child_process'; | ||
|
||
export async function spawn(...args){ | ||
return new Promise((resolve, reject)=>{ | ||
const p = _spawn(...args) | ||
p.on('exit', code => { | ||
if(code === 0){ | ||
resolve() | ||
} else { | ||
console.log(args) | ||
reject(new Error('Command Failed')) | ||
} | ||
}) | ||
}) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import {writeFile} from 'node:fs/promises'; | ||
import {spawn} from './process.js'; | ||
import {getRelease} from './github.js'; | ||
import {resolve} from 'node:path'; | ||
/** | ||
* Pack the package and publish it | ||
* | ||
* | ||
* @param packagePath | ||
* @param url | ||
* @param name | ||
* @return {Promise<*>} | ||
*/ | ||
export async function build(packagePath, url, name) { | ||
await spawn('npm', ['run', 'clean'], {cwd: packagePath}); | ||
await spawn('npx', ['openapi-ts', '--exportCore', 'false', '-i', url, '-o', 'src', '-c', 'fetch', '--name', name], {cwd: packagePath}); | ||
await spawn('npm', ['run', 'build'], {cwd: packagePath}); | ||
} | ||
|
||
/** | ||
* Pack the package and publish it | ||
* | ||
* | ||
* @param packagePath | ||
* @return {Promise<*>} | ||
*/ | ||
export async function publish(packagePath) { | ||
await spawn('npm', ['publish'], {cwd: packagePath}); | ||
} | ||
|
||
|
||
const CONFIGS = { | ||
AlgodClient: { | ||
BASE: 'https://testnet-api.algonode.cloud', | ||
DOCS: 'https://awesome-algorand.github.io/algo-fetch/guides/clients/algod/' | ||
}, | ||
IndexerClient: { | ||
BASE: 'https://testnet-idx.algonode.cloud/', | ||
DOCS: 'https://awesome-algorand.github.io/algo-fetch/guides/clients/indexer/' | ||
}, | ||
KmdClient: { | ||
BASE: 'https://localhost:4001', | ||
DOCS: 'https://awesome-algorand.github.io/algo-fetch/guides/clients/kmd/' | ||
} | ||
} | ||
|
||
export async function release({ | ||
name, // AlgodClient | ||
packagePath, // ./packages/algod | ||
version, // [3,0,0] | ||
tag, // v3.0.0-stable | ||
repo, // algorand/go-algorand | ||
schema, // daemon/algod/api/algod.oas3.yml | ||
}, pkg, token) { | ||
console.log(`Current ${name} Version: ${pkg.version}`); | ||
const schemaUrl = `https://raw.githubusercontent.com/${repo}/${tag}/${schema}`; | ||
if (version.join('.') !== pkg.version) { | ||
console.log(`Deploying Next ${name} Version: ${version.join('.')}`); | ||
const readMeHeader = ` | ||
# ${pkg.name} | ||
> ${pkg.description} | ||
Generated ${name} for Algorand based on the [OpenAPI Specification](${schemaUrl}). | ||
See the [upstream repository](https://github.com/${repo}) for more information. | ||
## Installation | ||
\`\`\`bash | ||
npm install ${pkg.name} --save | ||
\`\`\` | ||
### Usage | ||
\`\`\`typescript | ||
import {${name}} from '${pkg.name}'; | ||
const client = new ${name}({ | ||
BASE: '${CONFIGS[name].BASE}', | ||
}) | ||
\`\`\` | ||
#### See the full [API Documentation](${CONFIGS[name].DOCS}) for more information | ||
# Change Log | ||
` | ||
try { | ||
const [major, minor, patch] = version; | ||
const ghRelease = await getRelease(repo, tag, token); | ||
if(!ghRelease){ | ||
console.error(`Failed to get release for ${name} v${major}.${minor}.${patch}-stable`); | ||
return; | ||
} | ||
await writeFile(resolve(packagePath, "README.md"), readMeHeader + ghRelease.body); | ||
pkg.version = `${major}.${minor}.${patch}`; | ||
await writeFile(resolve(packagePath, "package.json"), JSON.stringify(pkg, null, 2)); | ||
await build(packagePath, schemaUrl, name); | ||
await publish(packagePath); | ||
console.log(`Deployed ${name} ${major}.${minor}.${patch}`); | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
} else { | ||
console.log(`No new ${name} versions to deploy`); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
export const EXCLUDED_VERSIONS = [ | ||
// Swagger not commited to repo yet | ||
'v2.0.3-stable', | ||
'v2.0.4-stable', | ||
'v2.0.5-stable', | ||
'v2.0.6-stable', | ||
// No valid release | ||
'v3.7.1-stable', | ||
'v3.12.3-stable', | ||
'v3.16.1-stable', | ||
] | ||
|
||
export function sortVersions(a, b) { | ||
if (a[0] !== b[0]) { | ||
return a[0] - b[0]; | ||
} | ||
if (a[1] !== b[1]) { | ||
return a[1] - b[1]; | ||
} | ||
return a[2] - b[2]; | ||
} | ||
/** | ||
* Only stable tags that start with v | ||
* | ||
* @param {string} tag | ||
* @return {boolean} | ||
*/ | ||
export function isStable(tag){ | ||
return tag.includes('stable') && tag[0] === 'v' && !tag.includes('backport') | ||
} | ||
|
||
/** | ||
* Check if the tag is a major version | ||
* | ||
* @param {string} tag | ||
* @param {string} version | ||
* @return {boolean} | ||
*/ | ||
export function isMajorVersion(tag, version){ | ||
return getVersionFromTag(tag).split('.')[0] === version | ||
} | ||
|
||
/** | ||
* If the tag is a valid release that can be automated | ||
* | ||
* @param tag | ||
* @return {boolean} | ||
*/ | ||
export function isValid(tag){ | ||
return isStable(tag) && !EXCLUDED_VERSIONS.includes(tag) && (isMajorVersion(tag, '2') || isMajorVersion(tag, '3')) | ||
} | ||
|
||
/** | ||
* Convert a reference to a tuple | ||
* @param ref - refs/tags/v2.0.1-stable | ||
* @return {number[]} | ||
*/ | ||
export function toTuple(ref){ | ||
return getVersionFromTag(ref.replace('refs/tags/', '')).split('.').map(i=>parseInt(i)) | ||
} | ||
/** | ||
* | ||
* @param {string} tag - v2.0.1-stable | ||
* @return {string} | ||
*/ | ||
export function getVersionFromTag(tag){ | ||
return tag.replace('v', '').split('-')[0] | ||
} | ||
|
||
|
||
export function getNextVersion(currentVersion, stableReleases){ | ||
const [major, minor, patch] = currentVersion.split('.').map(i=>parseInt(i)) | ||
const results = stableReleases.filter(([m, n, p])=>{ | ||
const isMajor = m > major | ||
const isMinor = m === major && n > minor | ||
const isPatch = m === major && n === minor && p > patch | ||
return isMajor || isMinor || isPatch | ||
}) | ||
return typeof results[0] === 'undefined' ? [major, minor, patch]: results[0] | ||
} |
Oops, something went wrong.