Skip to content

Commit cbf5f65

Browse files
authored
Extract repeated setup steps into reusable composite actions
1 parent e095cfe commit cbf5f65

17 files changed

Lines changed: 369 additions & 326 deletions
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Set up Git
2+
3+
This composite action configures SSH authentication, Git user identity, and optional commit signing.
4+
5+
## Simple usage example
6+
7+
```yml
8+
steps:
9+
- uses: actions/checkout@v4
10+
- uses: ./.github/actions/setup-git
11+
with:
12+
ssh-private-key: ${{ secrets.GITHUB_USER_SSH_KEY }}
13+
user-email: ${{ secrets.GITHUB_USER_EMAIL }}
14+
user-name: ${{ secrets.GITHUB_USER_NAME }}
15+
```
16+
17+
## Inputs
18+
19+
| Name | Default | Description |
20+
|---------------------|-----------|------------------------------------------------------------------------------------------------------------------|
21+
| `ssh-private-key` | `''` | Private SSH key for authentication. |
22+
| `user-email` | `''` | Git user email. |
23+
| `user-name` | `''` | Git user name. |
24+
| `ssh-public-key` | `''` | Public SSH key for commit signing. |
25+
| `automated-commits` | `'false'` | Enable Git settings for automated commits (auto-tracks remote branches on push, silences ignored-file warnings). |
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Set up Git
2+
description: Set up SSH agent, Git identity, and optional commit signing.
3+
4+
inputs:
5+
ssh-private-key:
6+
description: Private SSH key for authentication.
7+
default: ''
8+
required: false
9+
user-email:
10+
description: Git user email.
11+
default: ''
12+
required: false
13+
user-name:
14+
description: Git user name.
15+
default: ''
16+
required: false
17+
ssh-public-key:
18+
description: Public SSH key for commit signing.
19+
default: ''
20+
required: false
21+
automated-commits:
22+
description: Enable Git settings for automated commits (auto-tracks remote branches on push, silences ignored-file warnings).
23+
default: 'false'
24+
required: false
25+
26+
runs:
27+
using: composite
28+
steps:
29+
- name: Set up SSH
30+
if: ${{ inputs.ssh-private-key != '' }}
31+
uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0
32+
with:
33+
ssh-private-key: ${{ inputs.ssh-private-key }}
34+
35+
- name: Set up Git identity
36+
if: ${{ inputs.user-email != '' && inputs.user-name != '' }}
37+
shell: bash
38+
run: |
39+
git config --global user.email "${{ inputs.user-email }}"
40+
git config --global user.name "${{ inputs.user-name }}"
41+
42+
- name: Set up Git configuration
43+
if: ${{ inputs.automated-commits == 'true' }}
44+
shell: bash
45+
run: |
46+
git config --global advice.addIgnoredFile false
47+
git config --global push.autoSetupRemote true
48+
49+
- name: Set up commit signing
50+
if: ${{ inputs.ssh-public-key != '' }}
51+
shell: bash
52+
run: |
53+
: # Create empty SSH private key file so Git does not complain.
54+
touch "${{ runner.temp }}/signingkey"
55+
echo "${{ inputs.ssh-public-key }}" > "${{ runner.temp }}/signingkey.pub"
56+
git config --global commit.gpgsign true
57+
git config --global gpg.format ssh
58+
git config --global user.signingkey "${{ runner.temp }}/signingkey.pub"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Set up Node
2+
3+
This composite action sets up Node.js, automatically detects lock files for dependency caching, and installs project dependencies.
4+
5+
## Simple usage example
6+
7+
```yml
8+
steps:
9+
- uses: actions/checkout@v4
10+
- uses: ./.github/actions/setup-node
11+
with:
12+
registry-url: ${{ inputs.NPM_REGISTRY_DOMAIN }}
13+
node-auth-token: ${{ secrets.NPM_REGISTRY_TOKEN }}
14+
```
15+
16+
## Inputs
17+
18+
| Name | Default | Description |
19+
|------------------------|---------------------------------|-------------------------------------------------------------------------------------------------------------|
20+
| `node-version` | `'18'` | Node version to set up. |
21+
| `node-version-file` | `''` | Path to a file containing the Node version (takes precedence over `node-version`). |
22+
| `registry-url` | `'https://npm.pkg.github.com/'` | npm registry URL. |
23+
| `node-auth-token` | `''` | Authentication token for the npm registry. |
24+
| `node-options` | `''` | Space-separated list of command-line Node options. |
25+
| `package-manager` | `'npm'` | Package manager to use (`npm` or `yarn`). **Deprecated:** yarn support will be removed in a future version. |
26+
| `install-dependencies` | `'true'` | Whether to install dependencies (`'true'` or `'false'`). |
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Set up Node
2+
description: Set up Node with cache detection and dependency installation.
3+
4+
inputs:
5+
node-version:
6+
description: Node version to set up.
7+
default: '18'
8+
required: false
9+
node-version-file:
10+
description: Path to a file containing the Node version (takes precedence over node-version).
11+
default: ''
12+
required: false
13+
registry-url:
14+
description: npm registry URL.
15+
default: 'https://npm.pkg.github.com/'
16+
required: false
17+
node-auth-token:
18+
description: Authentication token for the npm registry.
19+
default: ''
20+
required: false
21+
node-options:
22+
description: Space-separated list of command-line Node options.
23+
default: ''
24+
required: false
25+
package-manager:
26+
description: "Package manager to use (npm or yarn). Deprecated: yarn support will be removed in a future version."
27+
default: 'npm'
28+
required: false
29+
install-dependencies:
30+
description: Whether to install dependencies ('true' or 'false').
31+
default: 'true'
32+
required: false
33+
34+
runs:
35+
using: composite
36+
steps:
37+
- name: Package manager deprecation warning
38+
if: ${{ inputs.package-manager != 'npm' }}
39+
shell: bash
40+
run: |
41+
echo "::warning::The package-manager input is deprecated and will be removed soon. Please update your workflow to use npm."
42+
43+
- name: Detect cache mode
44+
id: cache-detection
45+
shell: bash
46+
run: |
47+
CACHE_MODE=""
48+
if [ "${{ inputs.package-manager }}" == 'npm' ] && { [ -f "${GITHUB_WORKSPACE}/package-lock.json" ] || [ -f "${GITHUB_WORKSPACE}/npm-shrinkwrap.json" ]; }; then
49+
CACHE_MODE="npm"
50+
elif [ "${{ inputs.package-manager }}" == 'yarn' ] && [ -f "${GITHUB_WORKSPACE}/yarn.lock" ]; then
51+
CACHE_MODE="yarn"
52+
else
53+
echo "No lock files found for ${{ inputs.package-manager }}"
54+
fi
55+
echo "cache-mode=$CACHE_MODE" >> "$GITHUB_OUTPUT"
56+
57+
- name: Set up Node
58+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
59+
env:
60+
NODE_OPTIONS: ${{ inputs.node-options }}
61+
NODE_AUTH_TOKEN: ${{ inputs.node-auth-token }}
62+
with:
63+
node-version: ${{ inputs.node-version-file && '' || inputs.node-version }}
64+
node-version-file: ${{ inputs.node-version-file }}
65+
registry-url: ${{ inputs.registry-url }}
66+
cache: ${{ steps.cache-detection.outputs.cache-mode }}
67+
68+
- name: Install dependencies
69+
if: ${{ inputs.install-dependencies == 'true' }}
70+
shell: bash
71+
run: |
72+
CACHE_MODE="${{ steps.cache-detection.outputs.cache-mode }}"
73+
if [ "${{ inputs.package-manager }}" == 'yarn' ]; then
74+
if [ "$CACHE_MODE" == 'yarn' ]; then
75+
yarn --frozen-lockfile
76+
else
77+
yarn install
78+
fi
79+
else
80+
if [ "$CACHE_MODE" == 'npm' ]; then
81+
npm ci
82+
else
83+
npm install
84+
fi
85+
fi
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Set up PHP
2+
3+
This composite action sets up PHP, validates `composer.json`/`composer.lock`, and installs Composer dependencies.
4+
5+
## Simple usage example
6+
7+
```yml
8+
steps:
9+
- uses: actions/checkout@v4
10+
- uses: ./.github/actions/setup-php
11+
with:
12+
composer-auth-json: ${{ secrets.COMPOSER_AUTH_JSON }}
13+
```
14+
15+
## Inputs
16+
17+
| Name | Default | Description |
18+
|----------------------|-------------------|-------------------------------------------------------------------------------------------|
19+
| `php-version` | `'8.2'` | PHP version to set up. |
20+
| `php-extensions` | `''` | PHP extensions to install. |
21+
| `php-tools` | `'composer'` | PHP tools to install (e.g. `composer`, `cs2pr`, `parallel-lint`). |
22+
| `coverage` | `'none'` | Code coverage driver (`none`, `xdebug`, `pcov`, or empty for default). |
23+
| `composer-install` | `'true'` | Whether to validate and install Composer dependencies (`'true'` or `'false'`). |
24+
| `composer-options` | `'--prefer-dist'` | Arguments passed to Composer install. |
25+
| `composer-auth-json` | `''` | Authentication for privately hosted packages and repositories as a JSON formatted object. |
26+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Set up PHP
2+
description: Set up PHP, validate and install Composer dependencies.
3+
4+
inputs:
5+
php-version:
6+
description: PHP version to set up.
7+
default: '8.2'
8+
required: false
9+
php-extensions:
10+
description: PHP extensions to install.
11+
default: ''
12+
required: false
13+
php-tools:
14+
description: PHP tools to install (e.g. composer, cs2pr, parallel-lint).
15+
default: 'composer'
16+
required: false
17+
coverage:
18+
description: Code coverage driver (none, xdebug, pcov, or empty for default).
19+
default: 'none'
20+
required: false
21+
composer-install:
22+
description: Whether to validate and install Composer dependencies ('true' or 'false').
23+
default: 'true'
24+
required: false
25+
composer-options:
26+
description: Arguments passed to Composer install.
27+
default: '--prefer-dist'
28+
required: false
29+
composer-auth-json:
30+
description: Authentication for privately hosted packages and repositories as a JSON formatted object.
31+
default: ''
32+
required: false
33+
34+
runs:
35+
using: composite
36+
steps:
37+
- name: Set up PHP
38+
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
39+
with:
40+
php-version: ${{ inputs.php-version }}
41+
extensions: ${{ inputs.php-extensions }}
42+
tools: ${{ inputs.php-tools }}
43+
coverage: ${{ inputs.coverage }}
44+
45+
- name: Validate composer.json and composer.lock
46+
if: ${{ inputs.composer-install == 'true' }}
47+
shell: bash
48+
run: composer validate
49+
50+
- name: Install Composer dependencies
51+
if: ${{ inputs.composer-install == 'true' }}
52+
uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0
53+
env:
54+
COMPOSER_AUTH: ${{ inputs.composer-auth-json }}
55+
with:
56+
composer-options: ${{ inputs.composer-options }}

.github/workflows/automatic-release.yml

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ jobs:
4444
sparse-checkout-cone-mode: false
4545
path: semantic-release-repo
4646

47-
- name: Set up node
48-
uses: actions/setup-node@v4
49-
env:
50-
NODE_AUTH_TOKEN: ${{ secrets.NPM_REGISTRY_TOKEN }}
47+
- name: Set up Node
48+
uses: inpsyde/reusable-workflows/.github/actions/setup-node@main
5149
with:
5250
node-version-file: semantic-release-repo/package.json
5351
registry-url: ${{ inputs.NPM_REGISTRY_DOMAIN }}
52+
node-auth-token: ${{ secrets.NPM_REGISTRY_TOKEN }}
53+
install-dependencies: 'false'
5454

5555
- name: Install dependencies
5656
run: |
@@ -68,25 +68,13 @@ jobs:
6868
persist-credentials: false
6969
ssh-key: ${{ secrets.GITHUB_USER_SSH_KEY }}
7070

71-
- name: Set up SSH
72-
env:
73-
GITHUB_USER_SSH_KEY: ${{ secrets.GITHUB_USER_SSH_KEY }}
74-
if: ${{ env.GITHUB_USER_SSH_KEY != '' }}
75-
uses: webfactory/ssh-agent@v0.9.1
71+
- name: Set up Git
72+
uses: inpsyde/reusable-workflows/.github/actions/setup-git@main
7673
with:
77-
ssh-private-key: ${{ env.GITHUB_USER_SSH_KEY }}
78-
79-
- name: Set up signing commits
80-
env:
81-
GITHUB_USER_SSH_PUBLIC_KEY: ${{ secrets.GITHUB_USER_SSH_PUBLIC_KEY }}
82-
if: ${{ env.GITHUB_USER_SSH_PUBLIC_KEY != '' }}
83-
run: |
84-
: # Create empty SSH private key file so Git does not complain.
85-
touch "${{ runner.temp }}/signingkey"
86-
echo "${{ env.GITHUB_USER_SSH_PUBLIC_KEY }}" > "${{ runner.temp }}/signingkey.pub"
87-
git config --global commit.gpgsign true
88-
git config --global gpg.format ssh
89-
git config --global user.signingkey "${{ runner.temp }}/signingkey.pub"
74+
ssh-private-key: ${{ secrets.GITHUB_USER_SSH_KEY }}
75+
ssh-public-key: ${{ secrets.GITHUB_USER_SSH_PUBLIC_KEY }}
76+
user-email: ${{ secrets.GITHUB_USER_EMAIL }}
77+
user-name: ${{ secrets.GITHUB_USER_NAME }}
9078

9179
- name: Check presence of release.config.js
9280
run: |
@@ -113,25 +101,8 @@ jobs:
113101
run: |
114102
rm -rf workflow-repo
115103
116-
- name: Set up release environment variables
117-
env:
118-
GITHUB_USER_EMAIL: ${{ secrets.GITHUB_USER_EMAIL }}
119-
GITHUB_USER_NAME: ${{ secrets.GITHUB_USER_NAME }}
120-
run: |
121-
${{ env.GITHUB_USER_EMAIL != '' }} && echo "GIT_AUTHOR_EMAIL=${{ env.GITHUB_USER_EMAIL }}" >> $GITHUB_ENV || true
122-
${{ env.GITHUB_USER_NAME != '' }} && echo "GIT_AUTHOR_NAME=${{ env.GITHUB_USER_NAME }}" >> $GITHUB_ENV || true
123-
${{ env.GITHUB_USER_EMAIL != '' }} && echo "GIT_COMMITTER_EMAIL=${{ env.GITHUB_USER_EMAIL }}" >> $GITHUB_ENV || true
124-
${{ env.GITHUB_USER_NAME != '' }} && echo "GIT_COMMITTER_NAME=${{ env.GITHUB_USER_NAME }}" >> $GITHUB_ENV || true
125-
126104
- name: Release
127105
env:
128106
GITHUB_TOKEN: ${{ secrets.GITHUB_USER_TOKEN != '' && secrets.GITHUB_USER_TOKEN || secrets.GITHUB_TOKEN }}
129107
run: npx semantic-release
130108

131-
- name: Delete signing key files
132-
env:
133-
GITHUB_USER_SSH_PUBLIC_KEY: ${{ secrets.GITHUB_USER_SSH_PUBLIC_KEY }}
134-
if: ${{ always() && env.GITHUB_USER_SSH_PUBLIC_KEY != '' }}
135-
run: |
136-
rm -f "${{ runner.temp }}/signingkey"
137-
rm -f "${{ runner.temp }}/signingkey.pub"

0 commit comments

Comments
 (0)