forked from upsidr/merge-gatekeeper
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Remove the document checking action.
- Add actions to handle releases. - Include specific actions for releases. - Update the documentation to explain the reason for forking. - Add a binaries (linux ARM64 AMD64). - Update the action to use Node.js instead of Docker. - Change to utilize `invoke-binary.js`
- Loading branch information
Leon Silcott
committed
Dec 10, 2024
1 parent
12e1af4
commit 9d49f88
Showing
1,439 changed files
with
591,840 additions
and
57 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<!-- action-docs-header source="action.yml" --> | ||
|
||
<!-- action-docs-header source="action.yml" --> | ||
|
||
<!-- action-docs-description source="action.yml" --> | ||
## Description | ||
|
||
Manages GitHub Action releases by validating changes and creating release PRs | ||
<!-- action-docs-description source="action.yml" --> | ||
|
||
<!-- action-docs-runs source="action.yml" --> | ||
## Runs | ||
|
||
This action is a `composite` action. | ||
<!-- action-docs-runs source="action.yml" --> | ||
|
||
<!-- action-docs-inputs source="action.yml" --> | ||
## Inputs | ||
|
||
| name | description | required | default | | ||
| --- | --- | --- | --- | | ||
| `mode` | <p>Operation mode: check (for PR validation) or release (for creating releases)</p> | `true` | `""` | | ||
| `base_branch` | <p>Base branch to create a version branch from when the version branch does not exist</p> | `false` | `main` | | ||
| `main_branch` | <p>Main default branch of the repository</p> | `false` | `main` | | ||
<!-- action-docs-inputs source="action.yml" --> | ||
|
||
<!-- action-docs-outputs source="action.yml" --> | ||
|
||
<!-- action-docs-outputs source="action.yml" --> |
189 changes: 189 additions & 0 deletions
189
.github/actions/github-actions/release-action/action.yml
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,189 @@ | ||
name: 'Action Release Manager' | ||
description: 'Manages GitHub Action releases by validating changes and creating release PRs' | ||
|
||
inputs: | ||
mode: | ||
description: 'Operation mode: check (for PR validation) or release (for creating releases)' | ||
required: true | ||
base_branch: | ||
description: 'Base branch to create a version branch from when the version branch does not exist' | ||
required: false | ||
default: 'main' | ||
main_branch: | ||
description: 'Main default branch of the repository' | ||
required: false | ||
default: 'main' | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Get changed files | ||
id: changed-files | ||
uses: tj-actions/changed-files@v45 | ||
|
||
- name: Setup Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: 20 | ||
|
||
- name: Install Semver | ||
shell: bash | ||
run: | | ||
mkdir -p /tmp/action_node_modules | ||
npm install semver --prefix /tmp/action_node_modules | ||
echo "NODE_PATH=/tmp/action_node_modules/node_modules" >> $GITHUB_ENV | ||
- name: Find and validate action directory | ||
id: find-action | ||
uses: ./.github/actions/github-actions/validate-return-modified-action | ||
with: | ||
changed_files: ${{ steps.changed-files.outputs.all_modified_files }} | ||
|
||
- name: Handle action directory validation failure | ||
if: failure() | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const errorMsg = '${{ steps.find-action.outputs.error }}' || 'Action validation failed'; | ||
if ('${{ inputs.mode }}' === 'check') { | ||
await github.rest.pulls.createReview({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
pull_number: context.issue.number, | ||
body: errorMsg, | ||
event: 'REQUEST_CHANGES' | ||
}); | ||
} | ||
core.setFailed(errorMsg); | ||
process.exit(); | ||
- name: Dismiss PR change requests if all OK | ||
if: inputs.mode == 'check' && steps.find-action.outputs.error == '' | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const reviews = await github.rest.pulls.listReviews({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
pull_number: context.issue.number | ||
}); | ||
const reviewsToDismiss = reviews.data.filter(r => r.user.login === 'github-actions[bot]' && r.state === 'CHANGES_REQUESTED'); | ||
for (const review of reviewsToDismiss) { | ||
await github.rest.pulls.dismissReview({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
pull_number: context.issue.number, | ||
review_id: review.id, | ||
message: 'Dismissing review as it is resolved by a subsequent commit' | ||
}); | ||
} | ||
- name: Determine release info | ||
if: inputs.mode == 'release' && steps.find-action.outputs.modified_action != '' | ||
id: release-info | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const { execSync } = require('child_process'); | ||
let modifiedActions; | ||
try { | ||
modifiedActions = JSON.parse('${{ steps.find-action.outputs.modified_action }}'); | ||
} catch (e) { | ||
console.log('No actions to release'); | ||
process.exit(); | ||
} | ||
if (modifiedActions.length === 0) { | ||
console.log('No actions to release'); | ||
process.exit(); | ||
} | ||
const releaseInfo = modifiedActions.map(action => { | ||
let releaseType; | ||
try { | ||
execSync(`git show "origin/${action.version}:${action.action}"`, { stdio: 'ignore' }); | ||
releaseType = "update"; | ||
} catch { | ||
releaseType = "release"; | ||
} | ||
return { | ||
action_path: action.action, | ||
version: action.version, | ||
release_type: releaseType, | ||
branch_name: `${action.version}-${releaseType}-${action.action.replace('/', '-').replace('\\', '-')}` | ||
}; | ||
}); | ||
core.setOutput('release_info', JSON.stringify(releaseInfo)); | ||
- name: Create version and release branches | ||
if: inputs.mode == 'release' && steps.find-action.outputs.modified_action != '' | ||
shell: bash | ||
run: | | ||
release_info=$(echo '${{ steps.release-info.outputs.release_info }}' | jq -c '.[]') | ||
for info in $release_info; do | ||
version=$(echo $info | jq -r '.version') | ||
branch_name=$(echo $info | jq -r '.branch_name') | ||
action_path=$(echo $info | jq -r '.action_path') | ||
release_type=$(echo $info | jq -r '.release_type') | ||
if ! git show-ref --quiet refs/heads/$version; then | ||
if ! git show-ref --quiet origin/$version; then | ||
git checkout -b ${{ inputs.base_branch }} origin/${{ inputs.base_branch }} | ||
git pull | ||
git checkout -b $version origin/$version | ||
git push origin $version | ||
else | ||
echo "Version branch $version exists remotely, checking out" | ||
git checkout -b $version origin/$version | ||
git pull | ||
fi | ||
else | ||
echo "Version branch $version already exists locally, skipping creation." | ||
git checkout $version | ||
git pull | ||
fi | ||
git config user.name 'Action Release Bot' | ||
git config user.email '[email protected]' | ||
git branch -a | ||
git fetch origin ${{ inputs.main_branch }} | ||
git checkout -b $branch_name | ||
git checkout origin/${{ inputs.main_branch }} -- $action_path | ||
git add . | ||
git commit -m "[$release_type] $version for $action_path" | ||
git push origin $branch_name | ||
done | ||
- name: Create pull requests | ||
if: inputs.mode == 'release' && steps.find-action.outputs.modified_action != '' | ||
shell: bash | ||
env: | ||
GITHUB_TOKEN: ${{ github.token }} | ||
run: | | ||
release_info=$(echo '${{ steps.release-info.outputs.release_info }}' | jq -c '.[]') | ||
for info in $release_info; do | ||
version=$(echo $info | jq -r '.version') | ||
branch_name=$(echo $info | jq -r '.branch_name') | ||
action_path=$(echo $info | jq -r '.action_path') | ||
release_type=$(echo $info | jq -r '.release_type') | ||
gh pr create \ | ||
--base "$version" \ | ||
--title "[$release_type] $version $release_type for $action_path" \ | ||
--head "$branch_name" \ | ||
--body "## What has been done: | ||
- $version $release_type for $action_path" | ||
done | ||
git checkout ${{ inputs.main_branch }} |
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,5 @@ | ||
{ | ||
"name": "release-action", | ||
"version": "0.0.2-beta", | ||
"description": "Manages GitHub Action releases by validating changes and creating release PRs" | ||
} |
32 changes: 32 additions & 0 deletions
32
.github/actions/github-actions/validate-return-modified-action/README.md
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,32 @@ | ||
<!-- action-docs-header source="action.yml" --> | ||
|
||
<!-- action-docs-header source="action.yml" --> | ||
|
||
<!-- action-docs-description source="action.yml" --> | ||
## Description | ||
|
||
Finds the GitHub Action directory that was modified in the provided list of changed files | ||
<!-- action-docs-description source="action.yml" --> | ||
|
||
<!-- action-docs-runs source="action.yml" --> | ||
## Runs | ||
|
||
This action is a `composite` action. | ||
<!-- action-docs-runs source="action.yml" --> | ||
|
||
<!-- action-docs-inputs source="action.yml" --> | ||
## Inputs | ||
|
||
| name | description | required | default | | ||
| --- | --- | --- | --- | | ||
| `changed_files` | <p>List of changed files</p> | `true` | `""` | | ||
<!-- action-docs-inputs source="action.yml" --> | ||
|
||
<!-- action-docs-outputs source="action.yml" --> | ||
## Outputs | ||
|
||
| name | description | | ||
| --- | --- | | ||
| `modified_action` | <p>Path to the modified action directory</p> | | ||
| `error` | <p>Error message if the action directory validation failed</p> | | ||
<!-- action-docs-outputs source="action.yml" --> |
122 changes: 122 additions & 0 deletions
122
.github/actions/github-actions/validate-return-modified-action/action.yml
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,122 @@ | ||
name: 'Find Modified Action' | ||
description: 'Finds the GitHub Action directory that was modified in the provided list of changed files' | ||
|
||
inputs: | ||
changed_files: | ||
description: 'List of changed files' | ||
required: true | ||
|
||
outputs: | ||
modified_action: | ||
description: 'Path to the modified action directory' | ||
value: ${{ steps.find-action.outputs.modified_action }} | ||
|
||
error: | ||
description: 'Error message if the action directory validation failed' | ||
value: ${{ steps.find-action.outputs.error }} | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Setup Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: 20 | ||
|
||
- name: Install Semver | ||
shell: bash | ||
run: | | ||
# Install semver in a separate directory to avoid polluting the git branch | ||
mkdir -p /tmp/action_node_modules | ||
npm install semver --prefix /tmp/action_node_modules | ||
echo "NODE_PATH=/tmp/action_node_modules/node_modules" >> $GITHUB_ENV | ||
- name: Find and validate action directory | ||
id: find-action | ||
uses: actions/github-script@v7 | ||
env: | ||
NODE_PATH: /tmp/action_node_modules/node_modules | ||
with: | ||
script: | | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const semver = require('semver'); | ||
function findModifiedActionDir(changedFiles) { | ||
/* For all changed files, find if they are part of an action directory | ||
and return the set of all unique action directories */ | ||
const modifiedActionDirs = new Set(); | ||
changedFiles.forEach(file => { | ||
let currentDir = path.dirname(file); | ||
// Walk up directory tree until we find action.yml/yaml or reach root | ||
while (currentDir !== '.' && currentDir !== '/') { | ||
if ( | ||
fs.existsSync(path.join(currentDir, 'action.yml')) || | ||
fs.existsSync(path.join(currentDir, 'action.yaml')) | ||
) { | ||
modifiedActionDirs.add(currentDir); | ||
break; | ||
} | ||
currentDir = path.dirname(currentDir); | ||
} | ||
}); | ||
return modifiedActionDirs; | ||
} | ||
function validateActionDir(actionDir) { | ||
/* Validate action directory's package.json */ | ||
// Validate package.json exists | ||
if (!fs.existsSync(path.join(actionDir, 'package.json'))) { | ||
throw new Error('The action directory does not contain package.json file'); | ||
} | ||
// Validate package.json content | ||
try { | ||
const packageJson = JSON.parse(fs.readFileSync(path.join(actionDir, 'package.json'), 'utf8')); | ||
if (!packageJson.version) { | ||
throw new Error('The package.json file does not contain a version field'); | ||
} | ||
if (!semver.valid(packageJson.version)) { | ||
throw new Error('The package.json file contains an invalid version field'); | ||
} | ||
} catch (error) { | ||
throw new Error(`Package.json validation failed: ${error.message}`); | ||
} | ||
} | ||
let changedFiles = `${{ inputs.changed_files }}`.split(' '); | ||
const modifiedActionDirs = findModifiedActionDir(changedFiles); | ||
// Exit if there are no modified action directories | ||
if (modifiedActionDirs.size === 0) { | ||
console.log('No action to release'); | ||
return; | ||
} | ||
for (const targetActionDir of modifiedActionDirs) { | ||
try { | ||
validateActionDir(targetActionDir); | ||
} catch (error) { | ||
core.setFailed(error.message); | ||
core.setOutput('error', error.message); | ||
return; | ||
} | ||
} | ||
// Get the action directory and version | ||
const actionDirsOutput = Array.from(modifiedActionDirs).map( | ||
dir => { | ||
const packageJson = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8')); | ||
return { | ||
"action": dir, | ||
"version": semver.prerelease(packageJson.version) ? semver.prerelease(packageJson.version)[0] : "v" + semver.major(packageJson.version) | ||
} | ||
} | ||
); | ||
// Set the output | ||
core.setOutput('modified_action', JSON.stringify(actionDirsOutput)); |
5 changes: 5 additions & 0 deletions
5
.github/actions/github-actions/validate-return-modified-action/package.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,5 @@ | ||
{ | ||
"name": "validate-return-modified-action", | ||
"version": "0.0.2-beta", | ||
"description": "Finds the GitHub Action directory that was modified in the provided list of changed files" | ||
} |
Oops, something went wrong.