mirror of
https://github.com/creyD/prettier_action.git
synced 2026-04-15 12:50:31 +02:00
Compare commits
2 Commits
claude/add
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1711cdd30 | ||
|
|
bf5539213f |
81
.github/workflows/test.yml
vendored
81
.github/workflows/test.yml
vendored
@@ -1,81 +0,0 @@
|
|||||||
name: Run Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master, dev, 'claude/**' ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master, dev ]
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Run BATS Tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Git
|
|
||||||
run: |
|
|
||||||
git config --global user.name "GitHub Actions"
|
|
||||||
git config --global user.email "actions@github.com"
|
|
||||||
|
|
||||||
- name: Install BATS
|
|
||||||
run: |
|
|
||||||
cd tests
|
|
||||||
./run_tests.sh --install-only
|
|
||||||
|
|
||||||
- name: Run unit tests
|
|
||||||
run: |
|
|
||||||
cd tests
|
|
||||||
./bats/bin/bats unit_tests.bats
|
|
||||||
|
|
||||||
- name: Run plugin validation tests
|
|
||||||
run: |
|
|
||||||
cd tests
|
|
||||||
./bats/bin/bats plugin_validation_tests.bats
|
|
||||||
|
|
||||||
- name: Run integration tests
|
|
||||||
run: |
|
|
||||||
cd tests
|
|
||||||
./bats/bin/bats integration_tests.bats
|
|
||||||
|
|
||||||
- name: Run all tests with runner script
|
|
||||||
run: |
|
|
||||||
./tests/run_tests.sh
|
|
||||||
|
|
||||||
test-action:
|
|
||||||
name: Test Action End-to-End
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Create test files
|
|
||||||
run: |
|
|
||||||
echo "const x=1;const y=2;" > test.js
|
|
||||||
echo "function foo(){return 'bar';}" > test2.js
|
|
||||||
|
|
||||||
- name: Run prettier action in dry mode
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dry: true
|
|
||||||
prettier_options: "--write --check test*.js"
|
|
||||||
no_commit: true
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
shellcheck:
|
|
||||||
name: Shellcheck
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Run ShellCheck
|
|
||||||
uses: ludeeus/action-shellcheck@master
|
|
||||||
with:
|
|
||||||
scandir: '.'
|
|
||||||
severity: warning
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,6 +2,3 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
# NPM
|
# NPM
|
||||||
node_modules/
|
node_modules/
|
||||||
# Testing
|
|
||||||
tests/bats/
|
|
||||||
tests/test_temp_*/
|
|
||||||
|
|||||||
114
README.md
114
README.md
@@ -13,25 +13,26 @@ A GitHub action for styling files with [prettier](https://prettier.io).
|
|||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
| Parameter | Required | Default | Description |
|
| Parameter | Required | Default | Description |
|
||||||
| - | :-: | :-: | - |
|
| ------------------- | :------: | :-------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| dry | :x: | `false` | Runs the action in dry mode. Files wont get changed and the action fails if there are unprettified files. Recommended to use with prettier_options --check |
|
| dry | :x: | `false` | Runs the action in dry mode. Files wont get changed and the action fails if there are unprettified files. Recommended to use with prettier_options --check |
|
||||||
| no_commit | :x: | `false` | Can be used to avoid committing the changes (useful when another workflow step commits after this one anyways; can be combined with dry mode) |
|
| no_commit | :x: | `false` | Can be used to avoid committing the changes (useful when another workflow step commits after this one anyways; can be combined with dry mode) |
|
||||||
| prettier_version | :x: | `latest` | Specific prettier version (by default use latest) |
|
| prettier_version | :x: | `latest` | Specific prettier version (by default use latest) |
|
||||||
| working_directory | :x: | `${{ github.action_path }}` | Specify a directory to cd into before installing prettier and running it, use relative file path to the repository root for example `app/` |
|
| working_directory | :x: | `${{ github.action_path }}` | Specify a directory to cd into before installing prettier and running it, use relative file path to the repository root for example `app/` |
|
||||||
| prettier_options | :x: | `"--write **/*.js"` | Prettier options (by default it applies to the whole repository) |
|
| prettier_options | :x: | `"--write **/*.js"` | Prettier options (by default it applies to the whole repository) |
|
||||||
| commit_options | :x: | - | Custom git commit options |
|
| commit_options | :x: | - | Custom `git commit` options |
|
||||||
| push_options | :x: | - | Custom git push options |
|
| add_options | :x: | - | Custom `git add` options, e.g. `--update` to only add already known files. |
|
||||||
| same_commit | :x: | `false` | Update the current commit instead of creating a new one, created by [Joren Broekema](https://github.com/jorenbroekema), this command works only with the checkout action set to fetch depth '0' (see example 2) |
|
| push_options | :x: | - | Custom `git push` options |
|
||||||
| commit_message | :x: | `"Prettified Code!"` | Custom git commit message, will be ignored if used with `same_commit` |
|
| same_commit | :x: | `false` | Update the current commit instead of creating a new one, created by [Joren Broekema](https://github.com/jorenbroekema), this command works only with the checkout action set to fetch depth '0' (see example 2) |
|
||||||
| commit_description | :x: | - | Custom git extended commit message, will be ignored if used with `same_commit` |
|
| commit_message | :x: | `"Prettified Code!"` | Custom `git commit` message, will be ignored if used with `same_commit` |
|
||||||
| file_pattern | :x: | `*` | Custom git add file pattern, can't be used with only_changed! |
|
| commit_description | :x: | - | Custom git extended commit message, will be ignored if used with `same_commit` |
|
||||||
| prettier_plugins | :x: | - | Install Prettier plugins, i.e. `"@prettier/plugin-php" "@prettier/plugin-other"`. Must be wrapped in quotes since @ is a reserved character in YAML. |
|
| file_pattern | :x: | `*` | Custom `git add` file pattern, can't be used with only_changed! |
|
||||||
| clean_node_folder | :x: | `true` | Delete the node_modules folder before committing |
|
| prettier_plugins | :x: | - | Install Prettier plugins, i.e. `"@prettier/plugin-php" "@prettier/plugin-other"`. Must be wrapped in quotes since @ is a reserved character in YAML. |
|
||||||
| only_changed | :x: | `false` | Only prettify changed files, can't be used with file_pattern! This command works only with the checkout action set to fetch depth '0' (see example 2)|
|
| clean_node_folder | :x: | `true` | Delete the node_modules folder before committing |
|
||||||
| github_token | :x: | `${{ github.token }}` | The default [GITHUB_TOKEN](https://docs.github.com/en/actions/reference/authentication-in-a-workflow#about-the-github_token-secret) or a [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)
|
| only_changed | :x: | `false` | Only prettify changed files, can't be used with file_pattern! This command works only with the checkout action set to fetch depth '0' (see example 2) |
|
||||||
| git_identity | :x: | `actions` | Set to `author` to use author's user as committer. This allows triggering [further workflow runs](https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs)
|
| github_token | :x: | `${{ github.token }}` | The default [GITHUB_TOKEN](https://docs.github.com/en/actions/reference/authentication-in-a-workflow#about-the-github_token-secret) or a [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token) |
|
||||||
| allow_other_plugins | :x: | `false` | Allow other plugins to be installed (prevents the @prettier-XYZ regex check) |
|
| git_identity | :x: | `actions` | Set to `author` to use author's user as committer. This allows triggering [further workflow runs](https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs) |
|
||||||
|
| allow_other_plugins | :x: | `false` | Allow other plugins to be installed (prevents the @prettier-XYZ regex check) |
|
||||||
|
|
||||||
> Note: using the same_commit option may lead to problems if other actions are relying on the commit being the same before and after the prettier action has ran. Keep this in mind.
|
> Note: using the same_commit option may lead to problems if other actions are relying on the commit being the same before and after the prettier action has ran. Keep this in mind.
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Prettify code
|
- name: Prettify code
|
||||||
uses: creyD/prettier_action@v4.6
|
uses: creyD/prettier_action@v4.6
|
||||||
@@ -81,7 +82,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
# Make sure the actual branch is checked out when running on pull requests
|
# Make sure the actual branch is checked out when running on pull requests
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
@@ -111,7 +112,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
@@ -142,7 +143,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
@@ -158,73 +159,6 @@ jobs:
|
|||||||
|
|
||||||
More documentation for writing a workflow can be found [here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions).
|
More documentation for writing a workflow can be found [here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions).
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
This project includes comprehensive test coverage using [BATS (Bash Automated Testing System)](https://github.com/bats-core/bats-core).
|
|
||||||
|
|
||||||
### Running Tests Locally
|
|
||||||
|
|
||||||
To run the tests locally, execute the test runner script:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./tests/run_tests.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
This script will automatically:
|
|
||||||
1. Install BATS and required dependencies if not already present
|
|
||||||
2. Run all unit tests
|
|
||||||
3. Run plugin validation tests
|
|
||||||
4. Run integration tests
|
|
||||||
|
|
||||||
### Test Structure
|
|
||||||
|
|
||||||
The test suite is organized into three main categories:
|
|
||||||
|
|
||||||
- **`tests/unit_tests.bats`** - Unit tests for bash functions in `entrypoint.sh`
|
|
||||||
- Tests for `_git_setup()` function with different identity configurations
|
|
||||||
- Tests for `_git_changed()` function for detecting file changes
|
|
||||||
|
|
||||||
- **`tests/plugin_validation_tests.bats`** - Tests for Prettier plugin validation logic
|
|
||||||
- Validates official `@prettier/plugin-*` format
|
|
||||||
- Validates community `prettier-plugin-*` format
|
|
||||||
- Validates scoped `@scope/prettier-plugin-*` format
|
|
||||||
- Ensures invalid plugin names are rejected
|
|
||||||
|
|
||||||
- **`tests/integration_tests.bats`** - Integration tests for end-to-end workflows
|
|
||||||
- Tests working directory handling
|
|
||||||
- Tests node_modules cleanup
|
|
||||||
- Tests package-lock.json restoration
|
|
||||||
- Tests file filtering for `only_changed` mode
|
|
||||||
- Tests dry run behavior
|
|
||||||
|
|
||||||
### Manual BATS Installation
|
|
||||||
|
|
||||||
If you prefer to install BATS manually:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd tests
|
|
||||||
./run_tests.sh --install-only
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run individual test files:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./tests/bats/bin/bats tests/unit_tests.bats
|
|
||||||
./tests/bats/bin/bats tests/plugin_validation_tests.bats
|
|
||||||
./tests/bats/bin/bats tests/integration_tests.bats
|
|
||||||
```
|
|
||||||
|
|
||||||
### Continuous Integration
|
|
||||||
|
|
||||||
Tests are automatically run on every push and pull request via GitHub Actions. See [`.github/workflows/test.yml`](.github/workflows/test.yml) for the CI configuration.
|
|
||||||
|
|
||||||
The CI workflow includes:
|
|
||||||
- Unit tests
|
|
||||||
- Plugin validation tests
|
|
||||||
- Integration tests
|
|
||||||
- End-to-end action testing in dry mode
|
|
||||||
- ShellCheck linting for bash scripts
|
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
|
|
||||||
Please report all bugs and feature request using the [GitHub issues function](https://github.com/creyD/prettier_action/issues/new). Thanks!
|
Please report all bugs and feature request using the [GitHub issues function](https://github.com/creyD/prettier_action/issues/new). Thanks!
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ inputs:
|
|||||||
description: Update the current commit instead of creating a new one
|
description: Update the current commit instead of creating a new one
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
|
add_options:
|
||||||
|
description: Git add options
|
||||||
|
required: false
|
||||||
commit_options:
|
commit_options:
|
||||||
description: Commit options
|
description: Commit options
|
||||||
required: false
|
required: false
|
||||||
@@ -87,6 +90,7 @@ runs:
|
|||||||
INPUT_COMMIT_MESSAGE: ${{ inputs.commit_message }}
|
INPUT_COMMIT_MESSAGE: ${{ inputs.commit_message }}
|
||||||
INPUT_COMMIT_DESCRIPTION: ${{ inputs.commit_description }}
|
INPUT_COMMIT_DESCRIPTION: ${{ inputs.commit_description }}
|
||||||
INPUT_SAME_COMMIT: ${{ inputs.same_commit }}
|
INPUT_SAME_COMMIT: ${{ inputs.same_commit }}
|
||||||
|
INPUT_ADD_OPTIONS: ${{ inputs.add_options }}
|
||||||
INPUT_COMMIT_OPTIONS: ${{ inputs.commit_options }}
|
INPUT_COMMIT_OPTIONS: ${{ inputs.commit_options }}
|
||||||
INPUT_PUSH_OPTIONS: ${{ inputs.push_options }}
|
INPUT_PUSH_OPTIONS: ${{ inputs.push_options }}
|
||||||
INPUT_FILE_PATTERN: ${{ inputs.file_pattern }}
|
INPUT_FILE_PATTERN: ${{ inputs.file_pattern }}
|
||||||
|
|||||||
@@ -125,11 +125,11 @@ if _git_changed; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Calling method to configure the git environemnt
|
# Calling method to configure the git environment
|
||||||
_git_setup
|
_git_setup
|
||||||
|
|
||||||
# Add changes to git
|
# Add changes to git
|
||||||
git add "${INPUT_FILE_PATTERN}" || echo "Problem adding your files with pattern ${INPUT_FILE_PATTERN}"
|
git add ${INPUT_ADD_OPTIONS:+"$INPUT_ADD_OPTIONS"} "${INPUT_FILE_PATTERN}" || echo -e "Problem adding your files via 'git add':\n flags: ${INPUT_ADD_OPTIONS:+"$INPUT_ADD_OPTIONS"}\n pattern: ${INPUT_FILE_PATTERN}"
|
||||||
|
|
||||||
if $INPUT_NO_COMMIT; then
|
if $INPUT_NO_COMMIT; then
|
||||||
echo "There are changes that won't be commited, you can use an external job to do so."
|
echo "There are changes that won't be commited, you can use an external job to do so."
|
||||||
|
|||||||
@@ -1,195 +0,0 @@
|
|||||||
#!/usr/bin/env bats
|
|
||||||
|
|
||||||
# Integration tests for prettier_action
|
|
||||||
# These tests verify the overall behavior of the action
|
|
||||||
|
|
||||||
load 'test_helper'
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
setup_test_repo
|
|
||||||
mock_github_env
|
|
||||||
set_default_inputs
|
|
||||||
export SCRIPT_DIR="$(cd "$(dirname "${BATS_TEST_DIRNAME}")" && pwd)"
|
|
||||||
}
|
|
||||||
|
|
||||||
teardown() {
|
|
||||||
teardown_test_repo
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Action sets correct working directory when not specified" {
|
|
||||||
export INPUT_WORKING_DIRECTORY=""
|
|
||||||
export GITHUB_ACTION_PATH="/test/path"
|
|
||||||
|
|
||||||
# We'll test that the directory change logic works correctly
|
|
||||||
# by verifying the default assignment
|
|
||||||
result=$(bash -c '
|
|
||||||
INPUT_WORKING_DIRECTORY=""
|
|
||||||
GITHUB_ACTION_PATH="/test/path"
|
|
||||||
if [ -z "$INPUT_WORKING_DIRECTORY" ]; then
|
|
||||||
INPUT_WORKING_DIRECTORY=$GITHUB_ACTION_PATH
|
|
||||||
fi
|
|
||||||
echo "$INPUT_WORKING_DIRECTORY"
|
|
||||||
')
|
|
||||||
|
|
||||||
[ "$result" = "/test/path" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Action preserves working directory when specified" {
|
|
||||||
export INPUT_WORKING_DIRECTORY="/custom/path"
|
|
||||||
|
|
||||||
result=$(bash -c '
|
|
||||||
INPUT_WORKING_DIRECTORY="/custom/path"
|
|
||||||
GITHUB_ACTION_PATH="/test/path"
|
|
||||||
if [ -z "$INPUT_WORKING_DIRECTORY" ]; then
|
|
||||||
INPUT_WORKING_DIRECTORY=$GITHUB_ACTION_PATH
|
|
||||||
fi
|
|
||||||
echo "$INPUT_WORKING_DIRECTORY"
|
|
||||||
')
|
|
||||||
|
|
||||||
[ "$result" = "/custom/path" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Clean node folder removes node_modules when it exists" {
|
|
||||||
# Create node_modules directory
|
|
||||||
mkdir -p node_modules
|
|
||||||
echo "test" > node_modules/test.txt
|
|
||||||
|
|
||||||
# Simulate the clean logic
|
|
||||||
INPUT_CLEAN_NODE_FOLDER=true
|
|
||||||
if $INPUT_CLEAN_NODE_FOLDER; then
|
|
||||||
if [ -d 'node_modules' ]; then
|
|
||||||
rm -r node_modules/
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Verify node_modules was removed
|
|
||||||
[ ! -d "node_modules" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Clean node folder handles missing node_modules gracefully" {
|
|
||||||
# Ensure no node_modules exists
|
|
||||||
[ ! -d "node_modules" ]
|
|
||||||
|
|
||||||
# Simulate the clean logic
|
|
||||||
INPUT_CLEAN_NODE_FOLDER=true
|
|
||||||
run bash -c '
|
|
||||||
if $INPUT_CLEAN_NODE_FOLDER; then
|
|
||||||
if [ -d "node_modules" ]; then
|
|
||||||
rm -r node_modules/
|
|
||||||
echo "Deleted"
|
|
||||||
else
|
|
||||||
echo "No node_modules/ folder."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
'
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
[[ "$output" =~ "No node_modules/ folder." ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Package-lock.json is restored when it exists" {
|
|
||||||
# Create a package-lock.json and commit it
|
|
||||||
echo '{"name": "test"}' > package-lock.json
|
|
||||||
git add package-lock.json
|
|
||||||
git commit -m "Add package-lock.json"
|
|
||||||
|
|
||||||
# Modify it
|
|
||||||
echo '{"name": "modified"}' > package-lock.json
|
|
||||||
|
|
||||||
# Restore it using git checkout
|
|
||||||
git checkout -- package-lock.json
|
|
||||||
|
|
||||||
# Verify it was restored
|
|
||||||
content=$(cat package-lock.json)
|
|
||||||
[[ "$content" =~ '"name": "test"' ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Package-lock.json restore handles missing file gracefully" {
|
|
||||||
# Ensure no package-lock.json exists
|
|
||||||
[ ! -f "package-lock.json" ]
|
|
||||||
|
|
||||||
# Try to restore (should not fail)
|
|
||||||
run bash -c '
|
|
||||||
if [ -f "package-lock.json" ]; then
|
|
||||||
git checkout -- package-lock.json || echo "No package-lock.json file tracked by git."
|
|
||||||
else
|
|
||||||
echo "No package-lock.json file."
|
|
||||||
fi
|
|
||||||
'
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
[[ "$output" =~ "No package-lock.json file." ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "File pattern logic for only_changed mode filters correctly" {
|
|
||||||
# Create initial commit
|
|
||||||
echo "file1" > file1.txt
|
|
||||||
echo "file2" > file2.txt
|
|
||||||
git add .
|
|
||||||
git commit -m "Initial commit"
|
|
||||||
|
|
||||||
# Modify only file1
|
|
||||||
echo "modified" > file1.txt
|
|
||||||
git add file1.txt
|
|
||||||
git commit -m "Modify file1"
|
|
||||||
|
|
||||||
# Modify both files
|
|
||||||
echo "changed1" > file1.txt
|
|
||||||
echo "changed2" > file2.txt
|
|
||||||
|
|
||||||
# Get files changed in previous commit
|
|
||||||
git diff --name-only HEAD HEAD~1 > /tmp/prev.txt
|
|
||||||
|
|
||||||
# Get files with current changes
|
|
||||||
git diff --name-only HEAD > /tmp/cur.txt
|
|
||||||
|
|
||||||
# Verify file1.txt is in prev.txt (it was changed in last commit)
|
|
||||||
run grep "file1.txt" /tmp/prev.txt
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
|
|
||||||
# Verify both files are in cur.txt (both have current changes)
|
|
||||||
run grep "file1.txt" /tmp/cur.txt
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
run grep "file2.txt" /tmp/cur.txt
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
|
|
||||||
# Files in cur.txt but not in prev.txt should be reset
|
|
||||||
# In this case, file2.txt should be reset
|
|
||||||
for file in $(comm -1 -3 /tmp/prev.txt /tmp/cur.txt); do
|
|
||||||
[ "$file" = "file2.txt" ]
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Dry run mode detects unpretty files" {
|
|
||||||
# This tests the logic flow for dry run
|
|
||||||
# We simulate detecting changes
|
|
||||||
|
|
||||||
# Create a test file
|
|
||||||
echo "test" > test.txt
|
|
||||||
|
|
||||||
# Simulate git detecting changes
|
|
||||||
run bash -c '
|
|
||||||
source tests/test_helper.bash
|
|
||||||
setup_test_repo
|
|
||||||
echo "test" > test.txt
|
|
||||||
_git_changed
|
|
||||||
'
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "No changes scenario is handled correctly" {
|
|
||||||
# Create and commit a file
|
|
||||||
echo "test" > test.txt
|
|
||||||
git add test.txt
|
|
||||||
git commit -m "Add test file"
|
|
||||||
|
|
||||||
# Verify no changes
|
|
||||||
run bash -c '
|
|
||||||
source tests/test_helper.bash
|
|
||||||
load_script_functions entrypoint.sh
|
|
||||||
_git_changed
|
|
||||||
'
|
|
||||||
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
#!/usr/bin/env bats
|
|
||||||
|
|
||||||
# Integration tests for prettier plugin validation
|
|
||||||
|
|
||||||
load 'test_helper'
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
setup_test_repo
|
|
||||||
mock_github_env
|
|
||||||
set_default_inputs
|
|
||||||
}
|
|
||||||
|
|
||||||
teardown() {
|
|
||||||
teardown_test_repo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test valid prettier plugin patterns
|
|
||||||
@test "Valid @prettier/plugin-* format should pass validation" {
|
|
||||||
# Test the regex pattern used in entrypoint.sh
|
|
||||||
plugin="@prettier/plugin-php"
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Valid prettier-plugin-* format should pass validation" {
|
|
||||||
plugin="prettier-plugin-java"
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Valid @scope/prettier-plugin-* format should pass validation" {
|
|
||||||
plugin="@company/prettier-plugin-custom"
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Invalid plugin name should fail validation" {
|
|
||||||
plugin="some-random-package"
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Invalid plugin with wrong prefix should fail validation" {
|
|
||||||
plugin="@other/plugin-something"
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Multiple valid plugins should all pass validation" {
|
|
||||||
plugins="@prettier/plugin-php prettier-plugin-java @scope/prettier-plugin-custom"
|
|
||||||
|
|
||||||
for plugin in $plugins; do
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Plugin name with uppercase should fail validation" {
|
|
||||||
plugin="@prettier/plugin-PHP"
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Plugin name with numbers or underscores should fail validation" {
|
|
||||||
plugin1="@prettier/plugin-test123"
|
|
||||||
plugin2="prettier-plugin-test_name"
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin1' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
|
|
||||||
run bash -c "echo '$plugin2' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "Official prettier plugins should be recognized" {
|
|
||||||
# List of known official prettier plugins
|
|
||||||
plugins=(
|
|
||||||
"@prettier/plugin-php"
|
|
||||||
"@prettier/plugin-ruby"
|
|
||||||
"@prettier/plugin-xml"
|
|
||||||
)
|
|
||||||
|
|
||||||
for plugin in "${plugins[@]}"; do
|
|
||||||
run bash -c "echo '$plugin' | grep -Eq '(@prettier\/plugin-|(@[a-z\-]+\/)?prettier-plugin-){1}([a-z\-]+)'"
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
done
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Test runner script for prettier_action
|
|
||||||
# This script installs BATS and runs all tests
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
||||||
BATS_VERSION="v1.11.0"
|
|
||||||
BATS_INSTALL_DIR="$SCRIPT_DIR/bats"
|
|
||||||
|
|
||||||
# Colors for output
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
echo "========================================="
|
|
||||||
echo "Prettier Action Test Runner"
|
|
||||||
echo "========================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Function to install BATS
|
|
||||||
install_bats() {
|
|
||||||
echo -e "${YELLOW}Installing BATS (Bash Automated Testing System)...${NC}"
|
|
||||||
|
|
||||||
if [ -d "$BATS_INSTALL_DIR" ]; then
|
|
||||||
echo "BATS already installed at $BATS_INSTALL_DIR"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clone BATS
|
|
||||||
git clone --depth 1 --branch "$BATS_VERSION" https://github.com/bats-core/bats-core.git "$BATS_INSTALL_DIR"
|
|
||||||
|
|
||||||
# Clone support libraries
|
|
||||||
mkdir -p "$BATS_INSTALL_DIR/test_helper"
|
|
||||||
git clone --depth 1 https://github.com/bats-core/bats-support.git "$BATS_INSTALL_DIR/test_helper/bats-support"
|
|
||||||
git clone --depth 1 https://github.com/bats-core/bats-assert.git "$BATS_INSTALL_DIR/test_helper/bats-assert"
|
|
||||||
|
|
||||||
echo -e "${GREEN}BATS installed successfully!${NC}"
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to check if BATS is available
|
|
||||||
check_bats() {
|
|
||||||
if [ -x "$BATS_INSTALL_DIR/bin/bats" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
main() {
|
|
||||||
cd "$PROJECT_ROOT"
|
|
||||||
|
|
||||||
# Check if BATS is installed, if not install it
|
|
||||||
if ! check_bats; then
|
|
||||||
install_bats
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Running tests...${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Run all test files
|
|
||||||
TEST_FILES=(
|
|
||||||
"$SCRIPT_DIR/unit_tests.bats"
|
|
||||||
"$SCRIPT_DIR/plugin_validation_tests.bats"
|
|
||||||
"$SCRIPT_DIR/integration_tests.bats"
|
|
||||||
)
|
|
||||||
|
|
||||||
FAILED=0
|
|
||||||
|
|
||||||
for test_file in "${TEST_FILES[@]}"; do
|
|
||||||
if [ -f "$test_file" ]; then
|
|
||||||
echo "Running $(basename "$test_file")..."
|
|
||||||
if "$BATS_INSTALL_DIR/bin/bats" "$test_file"; then
|
|
||||||
echo -e "${GREEN}✓ $(basename "$test_file") passed${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}✗ $(basename "$test_file") failed${NC}"
|
|
||||||
FAILED=1
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "========================================="
|
|
||||||
if [ $FAILED -eq 0 ]; then
|
|
||||||
echo -e "${GREEN}All tests passed!${NC}"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo -e "${RED}Some tests failed!${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse command line arguments
|
|
||||||
case "${1:-}" in
|
|
||||||
--install-only)
|
|
||||||
install_bats
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
--help)
|
|
||||||
echo "Usage: $0 [OPTIONS]"
|
|
||||||
echo ""
|
|
||||||
echo "Options:"
|
|
||||||
echo " --install-only Only install BATS without running tests"
|
|
||||||
echo " --help Show this help message"
|
|
||||||
echo ""
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
main
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Test helper functions for prettier_action tests
|
|
||||||
|
|
||||||
# Set up a temporary test directory
|
|
||||||
setup_test_repo() {
|
|
||||||
export TEST_TEMP_DIR="$(mktemp -d)"
|
|
||||||
cd "$TEST_TEMP_DIR" || exit 1
|
|
||||||
git init
|
|
||||||
git config user.name "Test User"
|
|
||||||
git config user.email "test@example.com"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Clean up temporary test directory
|
|
||||||
teardown_test_repo() {
|
|
||||||
if [ -n "$TEST_TEMP_DIR" ] && [ -d "$TEST_TEMP_DIR" ]; then
|
|
||||||
rm -rf "$TEST_TEMP_DIR"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a sample file for testing
|
|
||||||
create_sample_file() {
|
|
||||||
local filename="${1:-test.js}"
|
|
||||||
local content="${2:-const x=1;const y=2;}"
|
|
||||||
echo "$content" > "$filename"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a sample package.json
|
|
||||||
create_package_json() {
|
|
||||||
cat > package.json << 'EOF'
|
|
||||||
{
|
|
||||||
"name": "test-project",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "Test project"
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# Mock git environment variables for GitHub Actions
|
|
||||||
mock_github_env() {
|
|
||||||
export GITHUB_ACTOR="${GITHUB_ACTOR:-test-actor}"
|
|
||||||
export GITHUB_ACTOR_ID="${GITHUB_ACTOR_ID:-12345}"
|
|
||||||
export GITHUB_ACTION_PATH="${GITHUB_ACTION_PATH:-/app}"
|
|
||||||
export GITHUB_BASE_REF="${GITHUB_BASE_REF:-main}"
|
|
||||||
export GITHUB_STEP_SUMMARY="${GITHUB_STEP_SUMMARY:-/dev/null}"
|
|
||||||
export INPUT_GITHUB_TOKEN="${INPUT_GITHUB_TOKEN:-test-token}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set default input environment variables
|
|
||||||
set_default_inputs() {
|
|
||||||
export INPUT_WORKING_DIRECTORY="${INPUT_WORKING_DIRECTORY:-}"
|
|
||||||
export INPUT_PRETTIER_VERSION="${INPUT_PRETTIER_VERSION:-latest}"
|
|
||||||
export INPUT_PRETTIER_OPTIONS="${INPUT_PRETTIER_OPTIONS:---write **/*.js}"
|
|
||||||
export INPUT_PRETTIER_PLUGINS="${INPUT_PRETTIER_PLUGINS:-}"
|
|
||||||
export INPUT_ALLOW_OTHER_PLUGINS="${INPUT_ALLOW_OTHER_PLUGINS:-false}"
|
|
||||||
export INPUT_CLEAN_NODE_FOLDER="${INPUT_CLEAN_NODE_FOLDER:-true}"
|
|
||||||
export INPUT_ONLY_CHANGED="${INPUT_ONLY_CHANGED:-false}"
|
|
||||||
export INPUT_ONLY_CHANGED_PR="${INPUT_ONLY_CHANGED_PR:-false}"
|
|
||||||
export INPUT_FILE_PATTERN="${INPUT_FILE_PATTERN:-*}"
|
|
||||||
export INPUT_DRY="${INPUT_DRY:-false}"
|
|
||||||
export INPUT_NO_COMMIT="${INPUT_NO_COMMIT:-false}"
|
|
||||||
export INPUT_SAME_COMMIT="${INPUT_SAME_COMMIT:-false}"
|
|
||||||
export INPUT_COMMIT_MESSAGE="${INPUT_COMMIT_MESSAGE:-Automated formatting}"
|
|
||||||
export INPUT_COMMIT_DESCRIPTION="${INPUT_COMMIT_DESCRIPTION:-}"
|
|
||||||
export INPUT_COMMIT_OPTIONS="${INPUT_COMMIT_OPTIONS:-}"
|
|
||||||
export INPUT_PUSH_OPTIONS="${INPUT_PUSH_OPTIONS:-}"
|
|
||||||
export INPUT_GIT_IDENTITY="${INPUT_GIT_IDENTITY:-actions}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Load a bash script without executing it (for testing functions)
|
|
||||||
load_script_functions() {
|
|
||||||
local script_path="$1"
|
|
||||||
# Source only the function definitions, not the main program
|
|
||||||
# We extract functions by finding lines between function definitions and the main program block
|
|
||||||
sed -n '/^_git_setup/,/^}/p' "$script_path" > "$TEST_TEMP_DIR/functions.sh"
|
|
||||||
sed -n '/^_git_changed/,/^}/p' "$script_path" >> "$TEST_TEMP_DIR/functions.sh"
|
|
||||||
source "$TEST_TEMP_DIR/functions.sh"
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
#!/usr/bin/env bats
|
|
||||||
|
|
||||||
# Unit tests for prettier_action entrypoint.sh functions
|
|
||||||
|
|
||||||
load 'test_helper'
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
setup_test_repo
|
|
||||||
mock_github_env
|
|
||||||
set_default_inputs
|
|
||||||
|
|
||||||
# Load the functions from entrypoint.sh
|
|
||||||
export SCRIPT_DIR="$(cd "$(dirname "${BATS_TEST_DIRNAME}")" && pwd)"
|
|
||||||
load_script_functions "$SCRIPT_DIR/entrypoint.sh"
|
|
||||||
}
|
|
||||||
|
|
||||||
teardown() {
|
|
||||||
teardown_test_repo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test _git_setup function with 'actions' identity
|
|
||||||
@test "_git_setup creates .netrc file with correct permissions" {
|
|
||||||
export INPUT_GIT_IDENTITY="actions"
|
|
||||||
|
|
||||||
run _git_setup
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
[ -f "$HOME/.netrc" ]
|
|
||||||
|
|
||||||
# Check file permissions (should be 600)
|
|
||||||
local perms=$(stat -c "%a" "$HOME/.netrc")
|
|
||||||
[ "$perms" = "600" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "_git_setup configures git with 'actions' identity" {
|
|
||||||
export INPUT_GIT_IDENTITY="actions"
|
|
||||||
|
|
||||||
run _git_setup
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
|
|
||||||
# Check git config
|
|
||||||
local git_name=$(git config --global user.name)
|
|
||||||
local git_email=$(git config --global user.email)
|
|
||||||
|
|
||||||
[ "$git_name" = "GitHub Action" ]
|
|
||||||
[ "$git_email" = "actions@github.com" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "_git_setup configures git with 'author' identity" {
|
|
||||||
export INPUT_GIT_IDENTITY="author"
|
|
||||||
export GITHUB_ACTOR="test-user"
|
|
||||||
export GITHUB_ACTOR_ID="54321"
|
|
||||||
|
|
||||||
run _git_setup
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
|
|
||||||
# Check git config
|
|
||||||
local git_name=$(git config --global user.name)
|
|
||||||
local git_email=$(git config --global user.email)
|
|
||||||
|
|
||||||
[ "$git_name" = "test-user" ]
|
|
||||||
[ "$git_email" = "54321+test-user@users.noreply.github.com" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "_git_setup fails with invalid identity" {
|
|
||||||
export INPUT_GIT_IDENTITY="invalid"
|
|
||||||
|
|
||||||
run _git_setup
|
|
||||||
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
[[ "$output" =~ "GIT_IDENTITY must be either 'author' or 'actions'" ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "_git_changed returns true when files are modified" {
|
|
||||||
# Create and commit a file
|
|
||||||
echo "test" > test.txt
|
|
||||||
git add test.txt
|
|
||||||
git commit -m "Initial commit"
|
|
||||||
|
|
||||||
# Modify the file
|
|
||||||
echo "modified" > test.txt
|
|
||||||
|
|
||||||
run _git_changed
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "_git_changed returns false when no files are modified" {
|
|
||||||
# Create and commit a file
|
|
||||||
echo "test" > test.txt
|
|
||||||
git add test.txt
|
|
||||||
git commit -m "Initial commit"
|
|
||||||
|
|
||||||
# No modifications
|
|
||||||
run _git_changed
|
|
||||||
|
|
||||||
[ "$status" -eq 1 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "_git_changed returns true for untracked files" {
|
|
||||||
# Create a file without committing
|
|
||||||
echo "test" > untracked.txt
|
|
||||||
|
|
||||||
run _git_changed
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "_git_changed returns true for staged files" {
|
|
||||||
# Create and commit a file
|
|
||||||
echo "test" > test.txt
|
|
||||||
git add test.txt
|
|
||||||
git commit -m "Initial commit"
|
|
||||||
|
|
||||||
# Add a new file and stage it
|
|
||||||
echo "new file" > new.txt
|
|
||||||
git add new.txt
|
|
||||||
|
|
||||||
run _git_changed
|
|
||||||
|
|
||||||
[ "$status" -eq 0 ]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user