diff --git a/.github/workflows/shared-release-branches.yml b/.github/workflows/shared-release-branches.yml index 824fcd3..52bae07 100644 --- a/.github/workflows/shared-release-branches.yml +++ b/.github/workflows/shared-release-branches.yml @@ -9,8 +9,6 @@ on: required: false default: '["ubuntu-latest"]' -permissions: {} - jobs: major-release-tagger: runs-on: ${{ fromJSON(inputs.runs-on) }} @@ -39,3 +37,162 @@ jobs: - uses: cloudposse/github-action-release-branch-manager@v2 with: token: ${{ steps.github-app.outputs.token }} + + release-commenter: + runs-on: ${{ fromJSON(inputs.runs-on) }} + steps: + - uses: actions/github-script@v7 + with: + result-encoding: string + retries: 3 + script: | + // Function to check if a value is unique in an array + function onlyUnique(value, index, array) { + return array.indexOf(value) === index; + } + + // Function to create or update a comment for a pull request (PR) associated with a release + async function createOrUpdateCommentForPR(pr_id, release) { + // Parameters for fetching comments related to the PR + const parameters = { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr_id, + per_page: 100, + } + + // Initialize existingComment variable + let existingComment = null; + + // Constructing the message to be posted or updated as a comment + const messageId = ``; + const message = ` + ${messageId} + These changes were released in [${release.name}](${release.html_url}). + `; + + // Iterating through all comments related to the PR + const allComments = github.paginate.iterator(github.rest.issues.listComments, parameters); + for await (comments of allComments) { + // Check if the message id is present in any of the comments + found = comments.data.find(({ body }) => { + return (body?.search(messageId) != -1) > -1; + }); + + if (found) { + break; // Exit the loop if the comment is found + } + } + + // If the comment is found, update it; otherwise, create a new comment + if (found) { + console.log(`Comment found`); + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: found.id, + body: message + }); + } else { + console.log(`Comment not found`); + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr_id, + body: message + }); + } + } + + // Retrieving the ID of the current release + release_id = context.payload.release.id; + + // Fetching details of the current release + currentReleaseResponse = await github.rest.repos.getRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id, + }); + + currentRelease = currentReleaseResponse.data; + + // Extracting tag name and target branch from the current release + currentTag = currentRelease.tag_name; + currentBranch = currentRelease.target_commitish; + + // Listing all releases of the repository + releases = await github.rest.repos.listReleases({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + + // Initializing variables for storing information about the previous release + previousRelease = null; + currentReleaseFound = false; + + // Iterating through releases to find the previous release relative to the current one + for (release of releases.data) { + if (currentReleaseFound) { + previousRelease = release; + break; + } else if (release.tag_name == currentTag) { + currentReleaseFound = true; + } + } + + // If no previous release is found, log a message and return + if (previousRelease == null) { + console.log(`No previous release found for ${currentTag}`); + return; + } + + // Comparing commits between the current and previous releases + commitsResponse = await github.rest.repos.compareCommits({ + owner: context.repo.owner, + repo: context.repo.repo, + base: previousRelease.tag_name, + head: currentRelease.tag_name, + }); + + commits = commitsResponse.data; + + // Initializing an array to store pull request numbers associated with the commits + pull_requests = []; + + // Iterating through commits to find associated pull requests and extracting their numbers + for (commit of commits.commits) { + responseCommit = await github.rest.git.getCommit({ + owner: context.repo.owner, + repo: context.repo.repo, + commit_sha: commit.sha, + }); + + // GraphQL query to fetch details about the commit, including associated pull requests + const query = ` + { + resource(url: "${context.payload.repository.html_url}/commit/${commit.sha}") { + ... on Commit { + messageHeadlineHTML + messageBodyHTML + associatedPullRequests(first: 10) { + pageInfo { hasNextPage } + edges { node { number } } + } + } + } + } + `; + + response = await github.graphql(query); + + // Extracting pull request numbers from the GraphQL response + for (edge of response.resource.associatedPullRequests.edges) { + pull_requests.push(edge.node.number); + } + } + + // Iterating through unique pull request numbers and creating or updating comments for them + for (id of pull_requests.filter(onlyUnique)) { + await createOrUpdateCommentForPR(id, currentRelease); + } +