Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
PravinPK authored Jan 17, 2024
2 parents 8912d28 + 62a49f5 commit 673cab5
Show file tree
Hide file tree
Showing 12 changed files with 882 additions and 184 deletions.
194 changes: 194 additions & 0 deletions .github/scripts/release_notes/android-release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

const https = require('https');
const { fetchReleaseInfoWithTagName } = require('./github-release');
const { capitalizeFirstLetter } = require('./utils');

// Maven Search REST API
// https://central.sonatype.org/search/rest-api-guide/

// Fetch the latest Android artifacts from Maven Central
async function fetchMavenArtifactInfo(groupId, capacity, timestampInMilliseconds) {
let options = {
host: 'search.maven.org',
port: 443,
timeout: 5000,
path: `/solrsearch/select?q=g:${groupId}&core=gav&rows=${capacity}&wt=json`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'User-Agent': 'server-side',
}
};

console.log(`request options: ${JSON.stringify(options)}`)

// TODO: condiser refactoring the code blow with libraries like axios.
return new Promise((resolve) => {
let reqGet = https.request(options, function (res) {
if (res.statusCode != 200) {
throw new Error(`response statusCode: ${res.statusCode}`)
}
console.log(`response statusCode: ${res.statusCode}`)

let data = [];
res.on('data', function (chunk) {
data.push(chunk);
}).on('end', function () {
let buffer = Buffer.concat(data);
let str = new TextDecoder("utf-8").decode(buffer)
let responseJson = JSON.parse(str)

let array = []
responseJson.response.docs.forEach(element => {
if (timestampInMilliseconds < element.timestamp) {
array.push(artifactInfo(element.timestamp, element.a, element.v))
}
});
resolve(array)
});
});
reqGet.on('error', function (e) {
console.error(e)
throw new Error("Got error response.")
});
reqGet.on('timeout', function () {
reqGet.destroy()
throw new Error("Request timeout.")
});
reqGet.end();
})

}

function artifactInfo(timestamp, artifactId, version) {
return {
"timestamp": timestamp,
"artifactId": artifactId,
"version": version
}
}

// Fetch the latest Android release info from GitHub
async function fetchAndroidReleaseInfo(token, groupId, timestampInMilliseconds, capacity = 10) {
let array = await fetchMavenArtifactInfo(groupId, capacity, timestampInMilliseconds);
console.log("fetchMavenArtifactInfo():")
console.log(array)
let releaseInfoArray = await Promise.all(array.map(async (item) => {
let artifactId = item.artifactId;
let version = item.version;
let extensionName = artifactIdToExtensionName(artifactId);
if (extensionName == null) {
return null;
}
let info = buildGitHubInfo(artifactId, version);
if (info == null) {
return null;
}
let releaseInfo = await fetchReleaseInfoWithTagName(token, "adobe", info.repoName, info.tagName);
// update release info with extension, version, and platform
releaseInfo.version = version;
releaseInfo.extension = extensionName;
releaseInfo.platform = 'Android';
return releaseInfo;
}));
return releaseInfoArray
}

// Convert artifactId to extension name. The extension name is used to generate the release title.
function artifactIdToExtensionName(artifactId) {
switch (artifactId) {
case "sdk-bom":
return "BOM"
case "campaignclassic":
return "Campaign Classic"
case "campaign":
return "Campaign Standard"
case "core":
case "lifecycle":
case "identity":
case "signal":
case "edge":
case "optimize":
case "places":
case "media":
case "target":
case "analytics":
case "assurance":
case "audience":
case "campaign":
return capitalizeFirstLetter(artifactId)
case "userprofile":
return "UserProfile"
case "edgeconsent":
return "EdgeConsent"
case "edgeidentity":
return "EdgeIdentity"
case "edgebridge":
return "EdgeBridge"
case "edgemedia":
return "EdgeMedia"
default:
console.log("artifactId not supported: " + artifactId)
return null
}
}

function buildGitHubInfo(artifactId, artifactVersion) {
switch (artifactId) {
case "sdk-bom":
return {
repoName: "aepsdk-commons",
tagName: "bom-" + artifactVersion
}

case "core":
case "lifecycle":
case "identity":
case "signal":
return {
repoName: `aepsdk-${artifactId}-android`,
tagName: `v${artifactVersion}-${artifactId}`
}

case "edge":
case "optimize":
case "places":
case "media":
case "target":
case "edgeidentity":
case "analytics":
case "assurance":
case "edgebridge":
case "edgeconsent":
case "edgemedia":
case "audience":
case "userprofile":
case "messaging":
case "campaignclassic":
case "campaign":
return {
repoName: `aepsdk-${artifactId}-android`,
tagName: `v${artifactVersion}`
}

default:
console.log("artifactId not supported: " + artifactId)
return null
}
}

module.exports = {
fetchMavenArtifactInfo,
fetchAndroidReleaseInfo
}
141 changes: 141 additions & 0 deletions .github/scripts/release_notes/github-release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

const https = require('https');

// REST API to retrieve release info
// https://docs.github.com/en/free-pro-team@latest/rest/releases/releases?apiVersion=2022-11-28#list-releases
// Example
// https://api.github.com/repos/adobe/aepsdk-react-native/releases?per_page=5
// Example
// https://api.github.com/repos/adobe/aepsdk-react-native/releases/tags/@adobe/[email protected]

// Alternative JS client: https://github.com/octokit/rest.js
// https://octokit.github.io/rest.js/v20#repos-get-release
// octokit.rest.repos.listReleases({
// owner,
// repo,
// });

async function fetchReleaseInfo(token, owner, repo, capacity = 5) {
let options = {
host: 'api.github.com',
port: 443,
timeout: 5000,
path: `/repos/${owner}/${repo}/releases?per_page=${capacity}`,
method: 'GET',
headers: {
'Accept': 'application/vnd.github+json',
'User-Agent': 'server-side',
'X-GitHub-Api-Version': '2022-11-28',
'Authorization': `Bearer ${token}`,
}
};

console.log(`request options: ${JSON.stringify(options)}`)

return new Promise((resolve) => {
let reqGet = https.request(options, function (res) {
if (res.statusCode != 200) {
throw new Error(`response statusCode: ${res.statusCode}`)
}
console.log(`response statusCode: ${res.statusCode}`)

let data = [];
res.on('data', function (chunk) {
data.push(chunk);
}).on('end', function () {
let buffer = Buffer.concat(data);
let str = new TextDecoder("utf-8").decode(buffer)
let responseJson = JSON.parse(str)
if (Array.isArray(responseJson) == false) {
throw new Error("response JSON is not an array")
}
let array = []
responseJson.forEach(element => {
array.push(releaseInfo(element.published_at, element.body, repo, element.tag_name))
});
resolve(array)
});
});
reqGet.on('error', function (e) {
console.error(e);
throw new Error("Got error response.")
});
reqGet.on('timeout', function () {
reqGet.destroy()
throw new Error("Request timeout.")
});
reqGet.end();
})
}

async function fetchReleaseInfoWithTagName(token, owner, repo, tag) {
let options = {
host: 'api.github.com',
port: 443,
timeout: 5000,
path: `/repos/${owner}/${repo}/releases/tags/${tag}`,
method: 'GET',
headers: {
'Accept': 'application/vnd.github+json',
'User-Agent': 'server-side',
'X-GitHub-Api-Version': '2022-11-28',
'Authorization': `Bearer ${token}`,
}
};

console.log(`request options: ${JSON.stringify(options)}`)

return new Promise((resolve) => {
let reqGet = https.request(options, function (res) {
if (res.statusCode != 200) {
console.error(`Error: response statusCode: ${res.statusCode}, please check if the tag (${tag}) exists in Github repo.`)
}
console.log(`response statusCode: ${res.statusCode}`)

let data = [];
res.on('data', function (chunk) {
data.push(chunk);
}).on('end', function () {
let buffer = Buffer.concat(data);
let str = new TextDecoder("utf-8").decode(buffer)
let responseJson = JSON.parse(str)
resolve(releaseInfo(responseJson.published_at, responseJson.body, repo, responseJson.tag_name))
});
});
reqGet.on('error', function (e) {
console.error(e);
throw new Error("Got error response.")
});
reqGet.on('timeout', function () {
reqGet.destroy()
throw new Error("Request timeout.")
});
reqGet.end();
})

}

function releaseInfo(published_at, body, repo_name, tag_name) {
return {
"published_at": published_at,
"body": body,
"repo_name": repo_name,
"tag_name": tag_name
}
}

module.exports = {
fetchReleaseInfo,
fetchReleaseInfoWithTagName
}
49 changes: 49 additions & 0 deletions .github/scripts/release_notes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

const timestampObj = require('./timestamp.json')
const releaseNoteMap = require('./releaseNoteMap.json')
const { saveJsonObjToFile } = require('./utils')
const { updateReleaseNotesPage, fetchAllReleaseInfo, sortReleaseInfoByDateASC } = require('./update-release-notes');

const token = process.argv[2];

if (token == undefined) {
throw new Error("token is undefined")
}

run()

async function run() {
const list = await fetchAllReleaseInfo(token, timestampObj.ts)
const sortedList = sortReleaseInfoByDateASC(list)
// 1. Update the main release page
updateReleaseNotesPage("./src/pages/home/release-notes/index.md", sortedList)
const ignoreList = ['AEP React Native', 'Roku', 'AEP Flutter']
for (const releaseInfo of sortedList) {
// We don't have separate release note pages for AEP React Native, Roku, and AEP Flutter
if (ignoreList.includes(releaseInfo.platform) || releaseInfo.extension == "BOM") {
continue
}
let filePath = releaseNoteMap[releaseInfo.extension]
if (filePath != undefined) {
// 2. Update the extension's release note page
updateReleaseNotesPage(filePath, [releaseInfo])
} else {
console.error(`Error: no release note page found for ${releaseInfo.extension}`)
}
}
let jsonObj = {
"ts": Date.now()
}
saveJsonObjToFile(jsonObj, `${__dirname}/timestamp.json`)
}
Loading

0 comments on commit 673cab5

Please sign in to comment.