Skip to content

Commit

Permalink
- Remove the document checking action.
Browse files Browse the repository at this point in the history
- 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
Show file tree
Hide file tree
Showing 1,439 changed files with 591,840 additions and 57 deletions.
29 changes: 29 additions & 0 deletions .github/actions/github-actions/release-action/README.md
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 .github/actions/github-actions/release-action/action.yml
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 }}
5 changes: 5 additions & 0 deletions .github/actions/github-actions/release-action/package.json
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"
}
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" -->
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));
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"
}
Loading

0 comments on commit 9d49f88

Please sign in to comment.