Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ This is a monorepo containing a collection of GitHub Actions maintained by Lizar

## actions

| Action | Description | Type | Language |
|---------------------------------------------------------------|----------------------------------------------|-----------|------------------|
| [audit_repos](actions/audit_repos#readme) | Audit repositories in an organization | composite | javascript |
| [facebook_post](actions/facebook_post#readme) | Post to Facebook page/group using Graph API | docker | python |
| [monitor_space](actions/monitor_space#readme) | Monitor and track minimum free disk space | composite | bash |
| [more_space](actions/more_space#readme) | Free up disk space in GitHub Actions runners | composite | bash |
| [release_changelog](actions/release_changelog#readme) | Generate a changelog for the latest release | composite | javascript |
| [release_create](actions/release_create#readme) | Create a new release | composite | bash, javascript |
| [release_homebrew](actions/release_homebrew#readme) | Validate and update Homebrew formula | composite | bash, python |
| [release_setup](actions/release_setup#readme) | Prepare a release | docker | python |
| [screenshot](actions/screenshot#readme) | Setup cross-platform screenshot CLI tool | composite | bash |
| [setup_cuda](actions/setup_cuda#readme) | Set up NVIDIA CUDA Toolkit on Linux runners | composite | bash |
| [setup_python](actions/setup_python#readme) | Set up Python environment | composite | bash |
| [setup_virtual_desktop](actions/setup_virtual_desktop#readme) | Setup virtual desktop for GUI apps on Linux | composite | bash |
| Action | Description | Type | Language |
|---------------------------------------------------------------|-------------------------------------------------------------------------------|-----------|------------------|
| [audit_repos](actions/audit_repos#readme) | Audit repositories in an organization | composite | javascript |
| [facebook_post](actions/facebook_post#readme) | Post to Facebook page/group using Graph API | docker | python |
| [monitor_space](actions/monitor_space#readme) | Monitor and track minimum free disk space | composite | bash |
| [pinact](actions/pinact#readme) | Run pinact against repositories in an organization and create PRs for updates | composite | javascript |
| [more_space](actions/more_space#readme) | Free up disk space in GitHub Actions runners | composite | bash |
| [release_changelog](actions/release_changelog#readme) | Generate a changelog for the latest release | composite | javascript |
| [release_create](actions/release_create#readme) | Create a new release | composite | bash, javascript |
| [release_homebrew](actions/release_homebrew#readme) | Validate and update Homebrew formula | composite | bash, python |
| [release_setup](actions/release_setup#readme) | Prepare a release | docker | python |
| [screenshot](actions/screenshot#readme) | Setup cross-platform screenshot CLI tool | composite | bash |
| [setup_cuda](actions/setup_cuda#readme) | Set up NVIDIA CUDA Toolkit on Linux runners | composite | bash |
| [setup_python](actions/setup_python#readme) | Set up Python environment | composite | bash |
| [setup_virtual_desktop](actions/setup_virtual_desktop#readme) | Setup virtual desktop for GUI apps on Linux | composite | bash |

## Contributions

Expand Down
213 changes: 213 additions & 0 deletions actions/pinact/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
# pinact

A reusable action to run [pinact](https://github.com/suzuki-shunsuke/pinact) against repositories in an organization and create PRs for updates.

Pinact is a tool that updates GitHub Actions to use commit hashes instead of tags, improving security by preventing tag hijacking attacks.

## 🛠️ Prep Work

### Prerequisites

- GitHub token with permissions to:
- Read repositories
- Create branches
- Create pull requests

## 🚀 Basic Usage

See [action.yml](action.yml)

```yaml
steps:
- name: Run Pinact
uses: LizardByte/actions/actions/pinact@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
```

## 📥 Inputs

| Name | Description | Default | Required |
|----------------|---------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|----------|
| dryRun | Dry run mode. If true, will not push changes or create pull requests. | `false` | `false` |
| gitAuthorEmail | Git commit author email. | `41898282+github-actions[bot]@users.noreply.github.com` | `false` |
| gitAuthorName | Git commit author name. | `github-actions[bot]` | `false` |
| githubOrg | GitHub organization or user to process repositories from. Defaults to current repo owner. Ignored if repo is specified. | Current repository owner | `false` |
| includeForks | Include forked repositories when processing an organization. Has no effect when repo is specified. | `false` | `false` |
| pinactConfig | Pinact configuration file content (YAML). | Empty (no config file) | `false` |
| pinactRepo | Repository to use for pinact. Allows using a fork. Format: owner/repo. | `suzuki-shunsuke/pinact` | `false` |
| pinactVersion | Version of pinact to use. | `latest` | `false` |
| prBranchName | Name of the branch to create for the pull request. | `pinact-updates` | `false` |
| repo | Specific repository to run pinact on (format: owner/repo). If specified, runs only on this repo instead of all org repos. | Empty (runs on all org repos) | `false` |
| token | GitHub Token with permissions to read repositories and create pull requests. | N/A | `true` |

## 📤 Outputs

This action does not produce any outputs. It creates pull requests directly in the target repositories.

## 🔒 Security Benefits

Using pinact to update GitHub Actions provides several security benefits:

- **Prevents tag hijacking**: Tags can be moved to point to different commits, but commit hashes are immutable
- **Improves supply chain security**: Ensures the exact version of an action is used
- **Audit trail**: Makes it clear exactly which version of an action is being used

## 🖥 Example Workflows

### Dry run mode (preview changes without creating PRs)

```yaml
name: Preview Pinact Changes

on:
workflow_dispatch:

jobs:
pinact-dry-run:
runs-on: ubuntu-latest
steps:
- name: Run Pinact in dry run mode
uses: LizardByte/actions/actions/pinact@master
with:
dryRun: true
token: ${{ secrets.GITHUB_TOKEN }}
```

### Run on all repositories in an organization

```yaml
name: Update Actions with Pinact

on:
workflow_dispatch:

jobs:
pinact:
runs-on: ubuntu-latest
steps:
- name: Run Pinact on all repos
uses: LizardByte/actions/actions/pinact@master
with:
token: ${{ secrets.ORG_ADMIN_TOKEN }}
```

### Run on a specific repository

```yaml
name: Update Actions with Pinact

on:
workflow_dispatch:
inputs:
repo:
description: 'Repository to update (format: owner/repo)'
required: true

jobs:
pinact:
runs-on: ubuntu-latest
steps:
- name: Run Pinact on specific repo
uses: LizardByte/actions/actions/pinact@master
with:
repo: ${{ github.event.inputs.repo }}
token: ${{ secrets.GITHUB_TOKEN }}
```

### Using a custom pinact fork

```yaml
name: Update Actions with Pinact

on:
workflow_dispatch:

jobs:
pinact:
runs-on: ubuntu-latest
steps:
- name: Run Pinact with custom fork
uses: LizardByte/actions/actions/pinact@master
with:
pinactRepo: myorg/pinact
pinactVersion: v1.2.3
token: ${{ secrets.GITHUB_TOKEN }}
```

### Custom branch name and git author

```yaml
name: Update Actions with Pinact

on:
workflow_dispatch:

jobs:
pinact:
runs-on: ubuntu-latest
steps:
- name: Run Pinact with custom settings
uses: LizardByte/actions/actions/pinact@master
with:
prBranchName: actions-security-update
gitAuthorName: Security Bot
gitAuthorEmail: security-bot@example.com
token: ${{ secrets.GITHUB_TOKEN }}
```

### Using custom pinact configuration

```yaml
name: Update Actions with Pinact

on:
workflow_dispatch:

jobs:
pinact:
runs-on: ubuntu-latest
steps:
- name: Run Pinact with custom config
uses: LizardByte/actions/actions/pinact@master
with:
pinactConfig: |
---
# config content here
token: ${{ secrets.GITHUB_TOKEN }}
```

### Include forked repositories

```yaml
name: Update Actions with Pinact (Including Forks)

on:
workflow_dispatch:

jobs:
pinact:
runs-on: ubuntu-latest
steps:
- name: Run Pinact including forks
uses: LizardByte/actions/actions/pinact@master
with:
includeForks: true
token: ${{ secrets.ORG_ADMIN_TOKEN }}
```

## 📝 Notes

- **Dry run mode**: Use `dryRun: true` to preview changes without pushing branches or creating PRs
- The action automatically filters out archived repositories when running on an organization
- By default, forked repositories are excluded. Use `includeForks: true` to include them
- If a pull request already exists for the specified branch, it will be updated instead of creating a duplicate
- The action detects the default branch automatically and will error if it cannot be determined
- API rate limiting is handled with automatic retry and exponential backoff
- Temporary clones are created and cleaned up automatically
- The diff output is displayed for each repository where changes are made

## 🔗 See Also

- [pinact](https://github.com/suzuki-shunsuke/pinact) - The upstream pinact tool
- [audit_repos](../audit_repos) - Audit repositories in an organization
86 changes: 86 additions & 0 deletions actions/pinact/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
name: "Pinact"
description: "Run pinact against repositories in an organization and create PRs for updates."
author: "LizardByte"

branding:
icon: arrow-up-circle
color: green

inputs:
dryRun:
description: 'Dry run mode. If true, will not push changes or create pull requests.'
required: false
default: 'false'
gitAuthorEmail:
description: 'Git commit author email.'
required: false
default: '41898282+github-actions[bot]@users.noreply.github.com'
gitAuthorName:
description: 'Git commit author name.'
required: false
default: 'github-actions[bot]'
githubOrg:
description: |
GitHub organization or user to process repositories from.
Defaults to the current repository owner.
Ignored if repo is specified.
required: false
default: ''
includeForks:
description: 'Include forked repositories when processing an organization. Has no effect when repo is specified.'
required: false
default: 'false'
pinactConfig:
description: 'Pinact configuration file content (YAML).'
required: false
default: ''
pinactRepo:
description: 'Repository to use for pinact. Allows using a fork. Format: owner/repo.'
required: false
default: 'suzuki-shunsuke/pinact'
pinactVersion:
description: 'Version of pinact to use.'
required: false
default: 'latest'
prBranchName:
description: 'Name of the branch to create for the pull request.'
required: false
default: 'pinact-updates'
repo:
description: |
Specific repository to run pinact on (format: owner/repo).
If specified, runs only on this repo instead of all org repos.
required: false
default: ''
token:
description: 'GitHub Token with permissions to read repositories and create pull requests.'
required: true

runs:
using: "composite"
steps:
- name: Setup Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: 'stable'

- name: Run pinact on repositories
env:
INPUT_DRY_RUN: ${{ inputs.dryRun }}
INPUT_GIT_AUTHOR_EMAIL: ${{ inputs.gitAuthorEmail }}
INPUT_GIT_AUTHOR_NAME: ${{ inputs.gitAuthorName }}
INPUT_GITHUB_ORG: ${{ inputs.githubOrg }}
INPUT_INCLUDE_FORKS: ${{ inputs.includeForks }}
INPUT_PINACT_CONFIG: ${{ inputs.pinactConfig }}
INPUT_PINACT_REPO: ${{ inputs.pinactRepo }}
INPUT_PINACT_VERSION: ${{ inputs.pinactVersion }}
INPUT_PR_BRANCH_NAME: ${{ inputs.prBranchName }}
INPUT_REPO: ${{ inputs.repo }}
PINACT_GITHUB_TOKEN: ${{ inputs.token }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ inputs.token }}
script: |
const script = require('${{ github.action_path }}/pinact.js');
await script({ github, context, core });
10 changes: 10 additions & 0 deletions actions/pinact/ci-matrix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"runs-on": "ubuntu-latest",
"with": {
"dryRun": "true",
"repo": "LizardByte/actions",
"token": "${ secrets.GITHUB_TOKEN }"
}
}
]
Loading