From d6c3fbb4b9e1d6cb51fbf08d6835235ff44814c1 Mon Sep 17 00:00:00 2001 From: Ismo Vuorinen Date: Mon, 11 Nov 2024 16:22:57 +0200 Subject: [PATCH] feat: add few first actions and workflows --- .editorconfig | 15 +--- .github/workflows/pr-lint.yml | 1 - README.md | 123 +++++++++++++++++++++++++++++++++ compress-images/action.yml | 45 ++++++++++++ php-composer/action.yml | 59 ++++++++++++++++ php-laravel-phpunit/action.yml | 87 +++++++++++++++++++++++ pre-commit/action.yml | 58 ++++++++++++++++ release-monthly/action.yml | 46 ++++++++++++ set-git-config/action.yml | 31 +++++++++ 9 files changed, 450 insertions(+), 15 deletions(-) create mode 100644 README.md create mode 100644 compress-images/action.yml create mode 100644 php-composer/action.yml create mode 100644 php-laravel-phpunit/action.yml create mode 100644 pre-commit/action.yml create mode 100644 release-monthly/action.yml create mode 100644 set-git-config/action.yml diff --git a/.editorconfig b/.editorconfig index a007838..07a504e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,7 @@ end_of_line = lf indent_size = 2 indent_style = space insert_final_newline = true -max_line_length = 160 +max_line_length = off tab_width = 2 trim_trailing_whitespace = true @@ -14,16 +14,3 @@ trim_trailing_whitespace = true indent_size = 4 max_line_length = 110 tab_width = 4 - -[{*.http,*.rest}] -indent_size = 0 - -[{*.markdown,*.md}] -indent_size = 4 -tab_width = 4 - -[{*.mk,GNUmakefile,makefile}] -tab_width = 4 - -[{*.tf,*.tfvars}] -tab_width = 4 diff --git a/.github/workflows/pr-lint.yml b/.github/workflows/pr-lint.yml index f4f8670..1cbc8e6 100644 --- a/.github/workflows/pr-lint.yml +++ b/.github/workflows/pr-lint.yml @@ -4,7 +4,6 @@ name: PR Lint on: push: branches-ignore: [master, main] - # Remove the line above to run when pushing to master pull_request: branches: [master, main] diff --git a/README.md b/README.md new file mode 100644 index 0000000..003efcc --- /dev/null +++ b/README.md @@ -0,0 +1,123 @@ +# ivuorinen/actions - My Reusable GitHub Actions and Workflows + +This repository contains reusable GitHub Actions and Workflows that +I have created for my own use. Feel free to use them in your own projects. + +## Actions + +These actions are composable and can be used together to create more complex workflows. + +### `ivuorinen/actions/php-composer` + +This action sets up PHP with specified version and installs Composer dependencies. + +#### Inputs + +- `php`: PHP version to use (default: `8.3`) +- `args`: Additional arguments to pass to Composer + +#### Example + +```yaml +on: + workflow_dispatch: + workflow_call: + pull_request: + paths: + - 'composer.json' + - 'composer.lock' +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: ivuorinen/actions/php-composer@main + with: + php: '8.3' + args: '--no-dev' +``` + +### `ivuorinen/actions/set-git-config` + +This action sets up Git configuration for the repository. + +#### Inputs + +- `name`: Name to use for Git commits (default: `GitHub Actions`) +- `email`: Email to use for Git commits (default: `github-actions@github.com`) +- `token`: GitHub token to use for Git commits (default: `${{ github.token }}`) + +#### Example + +```yaml +on: + workflow_dispatch: + workflow_call: + pull_request: + paths: + - '.gitignore' +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ivuorinen/actions/set-git-config@main + with: + name: 'GitHub Actions' + email: 'github-actions@github.com' + token: ${{ secrets.GITHUB_TOKEN }} +``` + +## Workflows + +These workflows are complete examples that can be used as-is or as a starting point for your own workflows. + +### `ivuorinen/actions/compress-images` + +This workflow compresses images in a repository using [calibreapp/image-actions](https://github.com/calibreapp/image-actions). +Defined in the action is a cron job that runs At 23:00 on Sunday and if there are any changes in the repository it creates a pull request with the compressed images. + +#### Example + +```yaml +# .github/workflows/compress-images.yml +jobs: + compress-images: + uses: ivuorinen/actions/compress-images@main +``` + +### `ivuorinen/actions/release-monthly` + +This workflow creates a monthly release with the current date as the tag name. + +#### Example + +```yaml +# .github/workflows/release-monthly.yml +jobs: + release-monthly: + uses: ivuorinen/actions/release-monthly@main +``` + +### `ivuorinen/actions/php-laravel-phpunit` + +This workflow sets up PHP with Composer and runs PHPUnit tests for a Laravel project. + +#### Example + +```yaml +# .github/workflows/php-laravel-phpunit.yml +jobs: + laravel: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: ivuorinen/actions/php-composer@main + with: + php: '8.3' + args: '--no-dev' +``` + +## License + +The code in this repository is licensed under the MIT License. See the [LICENSE.md](LICENSE.md) file for details. diff --git a/compress-images/action.yml b/compress-images/action.yml new file mode 100644 index 0000000..6a8a5b3 --- /dev/null +++ b/compress-images/action.yml @@ -0,0 +1,45 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json +# +# Compress images on demand (workflow_dispatch), and at 11pm every Sunday (schedule). +# Open a Pull Request if any images can be compressed. +name: Compress Images on Demand + +on: + workflow_dispatch: + workflow_call: + schedule: + - cron: '00 23 * * 0' + +jobs: + CompressOnDemandOrSchedule: + name: calibreapp/image-actions + + runs-on: ubuntu-latest + + permissions: + contents: write + statuses: write + pull-requests: write + + steps: + - uses: ivuorinen/actions/set-git-config@main + + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Compress Images + id: calibre + uses: calibreapp/image-actions@main + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} + compressOnly: true + + - name: Create New Pull Request If Needed + if: steps.calibre.outputs.markdown != '' + uses: peter-evans/create-pull-request@v7 + with: + title: Compressed Images Nightly + branch-suffix: timestamp + commit-message: Compressed Images + body: ${{ steps.calibre.outputs.markdown }} diff --git a/php-composer/action.yml b/php-composer/action.yml new file mode 100644 index 0000000..83749e7 --- /dev/null +++ b/php-composer/action.yml @@ -0,0 +1,59 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/github-action.json +name: Run Composer Install on defined PHP version +description: "Runs Composer install on the repository" +author: "Ismo Vuorinen" +branding: + icon: package + color: gray-dark + +inputs: + php: + description: 'PHP Version to use' + required: true + default: "8.3" + args: + description: 'Arguments to pass to Composer' + required: false + default: '--no-progress --prefer-dist --optimize-autoloader' + +outputs: + lock: + description: "composer.lock or composer.json file hash" + value: ${{ steps.hash.outputs.lock }} + +runs: + using: composite + + steps: + - name: Get composer.lock or composer.json hash for caching + id: hash + shell: bash + run: | + if [ -f composer.lock ]; then + echo "lock=${{ hashFiles('**/composer.lock') }}" >> $GITHUB_OUTPUT + else + echo "lock=${{ hashFiles('**/composer.json') }}" >> $GITHUB_OUTPUT + fi + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v4 + with: + path: vendor + key: ${{ runner.os }}-php-${{ inputs.php }}-${{ runs.hash.outputs.lock }} + restore-keys: | + ${{ runner.os }}-php-${{ inputs.php }}-${{ runs.hash.outputs.lock }} + ${{ runner.os }}-php-${{ inputs.php }}- + ${{ runner.os }}-php- + + - name: PHP ${{ inputs.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ inputs.php }} + tools: composer + extensions: ${{ inputs.extensions }} + + - name: Composer Install + shell: bash + run: composer install ${{ inputs.args }} diff --git a/php-laravel-phpunit/action.yml b/php-laravel-phpunit/action.yml new file mode 100644 index 0000000..7279b03 --- /dev/null +++ b/php-laravel-phpunit/action.yml @@ -0,0 +1,87 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json +name: Laravel Setup and Composer test + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_call: + inputs: + php-version: + description: 'PHP Version to use, see https://github.com/marketplace/actions/setup-php-action#php-version-optional' + required: false + default: 'latest' + type: string + php-version-file: + description: 'PHP Version file to use, see https://github.com/marketplace/actions/setup-php-action#php-version-file-optional' + required: false + default: '.php-version' + type: string + extensions: + description: 'PHP extensions to install, see https://github.com/marketplace/actions/setup-php-action#extensions-optional' + required: false + default: 'mbstring, intl, json, pdo_sqlite, sqlite3' + type: string + coverage: + description: 'Specify code-coverage driver, see https://github.com/marketplace/actions/setup-php-action#coverage-optional' + required: false + default: 'none' + type: string + +jobs: + laravel-tests: + runs-on: ubuntu-latest + + outputs: + check_files: ${{ steps.check_files.outputs.files_exists }} + + permissions: + contents: write + statuses: write + + steps: + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ github.event.inputs.php-version }} + php-version-file: ${{ github.event.inputs.php-version-file }} + extensions: ${{ github.event.inputs.extensions }} + coverage: ${{ github.event.inputs.coverage }} + + - uses: actions/checkout@v4 + + - name: 'Check file existence' + id: check_files + uses: andstor/file-existence-action@v3 + with: + files: 'package.json, artisan' + + - name: Copy .env + if: steps.check_files.outputs.files_exists == 'true' + run: php -r "file_exists('.env') || copy('.env.example', '.env');" + + - name: Install Dependencies + if: steps.check_files.outputs.files_exists == 'true' + run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + + - name: Generate key + if: steps.check_files.outputs.files_exists == 'true' + run: php artisan key:generate + + - name: Directory Permissions + if: steps.check_files.outputs.files_exists == 'true' + run: chmod -R 777 storage bootstrap/cache + + - name: Create Database + if: steps.check_files.outputs.files_exists == 'true' + run: | + mkdir -p database + touch database/database.sqlite + + - name: Execute composer test (Unit and Feature tests) + if: steps.check_files.outputs.files_exists == 'true' + env: + DB_CONNECTION: sqlite + DB_DATABASE: database/database.sqlite + run: composer test diff --git a/pre-commit/action.yml b/pre-commit/action.yml new file mode 100644 index 0000000..c42c5bf --- /dev/null +++ b/pre-commit/action.yml @@ -0,0 +1,58 @@ +name: pre-commit +description: "Runs pre-commit on the repository and pushes the fixes back to the repository" + +branding: + icon: check-square + color: green + +inputs: + pre-commit-config: + description: "pre-commit configuration file" + required: true + base-branch: + description: "Base branch to compare against" + required: false + token: + description: "GitHub Token" + required: false + default: ${{ github.token }} + commit_user: + description: "Commit user" + required: false + default: "GitHub Actions" + commit_email: + description: "Commit email" + required: false + default: "github-actions@github.com" + +runs: + using: composite + steps: + - name: Set Git Config + uses: ivuorinen/actions/set-git-config@main + with: + token: ${{ inputs.token }} + username: ${{ inputs.commit_user }} + email: ${{ inputs.commit_email }} + + - name: Set option + id: set-option + run: | + if [ -z "${{ inputs.base-branch }}" ]; then + echo "option=--all-files" >> $GITHUB_OUTPUT + exit 0 + fi + echo "option=--from-ref ${{ inputs.base-branch }} --to-ref HEAD" >> $GITHUB_OUTPUT + shell: bash + + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 + with: + extra_args: --config ${{ inputs.pre-commit-config }} ${{ steps.set-option.outputs.option }} + + - name: Push pre-commit fixes + if: always() # Push changes even when pre-commit fails + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "style(pre-commit): autofix" + add_options: -u diff --git a/release-monthly/action.yml b/release-monthly/action.yml new file mode 100644 index 0000000..6537f29 --- /dev/null +++ b/release-monthly/action.yml @@ -0,0 +1,46 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json +name: 'Release' + +on: + workflow_dispatch: + workflow_call: + schedule: + - cron: '0 0 1 * *' # 1st of every month at midnight + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create Release + shell: bash + env: + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + run: | + # Retrieve previous release tag + previous_tag="$(gh release list --limit 1 | awk '{ print $1 }')" + previous_major="${previous_tag%%\.*}" + previous_minor="${previous_tag#*.}" + previous_minor="${previous_minor%.*}" + previous_patch="${previous_tag##*.}" + # Determine next release tag + next_major_minor="$(date +'%Y').$(date +'%-m')" + if [[ "${previous_major}.${previous_minor}" == "${next_major_minor}" ]]; then + echo "Month release already exists for year, incrementing patch number by 1" + next_patch="$((previous_patch + 1))" + else + echo "Month release does not exist for year, setting patch number to 0" + next_patch="0" + fi + # Create release + release_tag="${next_major_minor}.${next_patch}" + gh release create "${release_tag}" \ + --repo="${GITHUB_REPOSITORY}" \ + --title="${release_tag}" \ + --generate-notes diff --git a/set-git-config/action.yml b/set-git-config/action.yml new file mode 100644 index 0000000..5e43587 --- /dev/null +++ b/set-git-config/action.yml @@ -0,0 +1,31 @@ +name: set-git-config +description: "Sets git config for the action" + +branding: + icon: settings + color: gray-dark + +inputs: + token: + description: "GitHub token" + required: true + username: + description: "GitHub username action should use" + default: "github-actions" + format: string + email: + description: "GitHub email action should use" + default: "github-actions@github.com" + format: email + +runs: + using: composite + steps: + - name: Set git config + run: | + git config --local --unset-all http.https://github.com/.extraheader || true + git config --global --add url.https://x-access-token:${{ inputs.token }}@github.com/.insteadOf 'https://github.com/' + git config --global --add url.https://x-access-token:${{ inputs.token }}@github.com/.insteadOf 'git@github.com:' + git config --global user.name ${{ inputs.username }} + git config --global user.email ${{ inputs.email }} + shell: bash