Compare commits

...

22 Commits

Author SHA1 Message Date
github-actions[bot]
a261fcd118 chore: update action references to v2025 (0fa9a68f07) (#333) 2025-11-03 12:59:49 +02:00
a1c0435c22 chore: update action references for release v2025.11.02 (#332)
This commit updates all internal action references to point to the current
commit SHA in preparation for release v2025.11.02.
2025-11-02 20:53:11 +02:00
2f1c73dd8b fix: release timeout wasn't accepting command (#331) 2025-11-02 19:39:44 +02:00
fd49ff6968 fix: ask_confirmation tty redirection (#330) 2025-11-02 17:10:27 +02:00
renovate[bot]
82edd1dc12 chore(deps): update github/codeql-action action (v4.31.0 → v4.31.2) (#327)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-02 12:19:40 +00:00
63a18808a0 feat: extended release make target, fixes (#329)
* feat: extended release make target, fixes

* fix: cr comments
2025-11-02 14:16:32 +02:00
renovate[bot]
8527166fbb chore(deps): update pre-commit hook bridgecrewio/checkov (3.2.487 → 3.2.489) (#325)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-31 15:15:27 +02:00
fb5a978260 fix(pr-lint): add token fallback, fix shellspec checksum (#326) 2025-10-31 15:09:46 +02:00
renovate[bot]
ca7fc1a5ff chore(deps)!: update node (v22.21.0 → v24.11.0) (#324)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-28 20:07:29 +02:00
42a40cfaf1 chore: update root readme, generation listing (#322)
* chore: update root readme, generation listing

* fix: grammar fix, example version from real date to example

* chore: add docstrings to `chore/update` (#323)

Docstrings generation was requested by @ivuorinen.

* https://github.com/ivuorinen/actions/pull/322#issuecomment-3457571306

The following files were modified:

* `generate_listing.cjs`

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-28 19:18:26 +02:00
b06748cbef fix(set-git-config): remove credentials cleaning, it's automatic (#321) 2025-10-28 18:35:58 +02:00
cbbb0c8b8c fix: node-setup caching, validate-inputs optional_inputs type (#320)
* fix: node-setup caching, validate-inputs optional_inputs type

* test(validate-inputs): dict optional_inputs backward compatibility

Verify that legacy dict format for optional_inputs correctly generates
conventions from dict keys. Updates existing test to expect list type
for optional_inputs default.
2025-10-27 23:56:17 +02:00
renovate[bot]
1a8997715c chore(deps)!: update actions/upload-artifact (v4.6.2 → v5.0.0) (#316)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 14:15:31 +02:00
renovate[bot]
f50ab425b8 chore(deps)!: update actions/github-script (v7.1.0 → v8.0.0) (#315)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 12:07:05 +02:00
github-actions[bot]
41b1778849 chore: update action references to v2025 (0fa9a68f07) (#319)
This commit updates all internal action references to point to the latest v2025 tag SHA.
2025-10-27 12:03:38 +02:00
renovate[bot]
bbb05559e6 chore(deps): update actions/github-script action (v7.0.1 → v7.1.0) (#313)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 11:58:55 +02:00
renovate[bot]
7c18e12b06 chore(deps): update github/codeql-action action (v4.30.9 → v4.31.0) (#318)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 09:11:49 +02:00
renovate[bot]
88053f4197 chore(deps): update pre-commit hook renovatebot/pre-commit-hooks (41.149.2 → 41.159.4) (#306)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-26 22:49:50 +00:00
renovate[bot]
ee9a4877e8 chore(deps)!: update actions/download-artifact (v5.0.0 → v6.0.0) (#314) 2025-10-27 00:46:39 +02:00
renovate[bot]
c32f2813f0 chore(deps): update peter-evans/create-pull-request action (v7.0.5 → v7.0.8) (#310)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-26 22:12:35 +00:00
renovate[bot]
e416c272b5 chore(deps): update astral-sh/setup-uv action (v7.1.1 → v7.1.2) (#317)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-27 00:06:21 +02:00
74968d942f chore: update action references for release v2025.10.26 (#312)
This commit updates all internal action references to point to the current
commit SHA in preparation for release v2025.10.26.
2025-10-27 00:00:02 +02:00
52 changed files with 865 additions and 265 deletions

View File

@@ -17,7 +17,7 @@ runs:
using: composite using: composite
steps: steps:
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1 uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
with: with:
enable-cache: true enable-cache: true
@@ -33,7 +33,7 @@ runs:
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with: with:
node-version: '22' node-version: '24'
cache: npm cache: npm
- name: Install Node dependencies - name: Install Node dependencies

View File

@@ -117,21 +117,21 @@ jobs:
- name: Upload Trivy results - name: Upload Trivy results
if: steps.verify-sarif.outputs.has_trivy == 'true' if: steps.verify-sarif.outputs.has_trivy == 'true'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: 'trivy-results.sarif' sarif_file: 'trivy-results.sarif'
category: 'trivy' category: 'trivy'
- name: Upload Gitleaks results - name: Upload Gitleaks results
if: steps.verify-sarif.outputs.has_gitleaks == 'true' if: steps.verify-sarif.outputs.has_gitleaks == 'true'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: 'gitleaks-report.sarif' sarif_file: 'gitleaks-report.sarif'
category: 'gitleaks' category: 'gitleaks'
- name: Archive security reports - name: Archive security reports
if: always() if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with: with:
name: security-reports-${{ github.run_id }} name: security-reports-${{ github.run_id }}
path: | path: |

View File

@@ -37,15 +37,15 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
queries: security-and-quality queries: security-and-quality
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/autobuild@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
category: '/language:${{matrix.language}}' category: '/language:${{matrix.language}}'

View File

@@ -1,3 +1,4 @@
---
name: Monthly issue metrics name: Monthly issue metrics
on: on:
workflow_dispatch: workflow_dispatch:
@@ -29,7 +30,7 @@ jobs:
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV" echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
- name: Run issue-metrics tool - name: Run issue-metrics tool
uses: github/issue-metrics@c640329f02bd24b12b91d51cd385f0b1c25cefb9 # v3.25.1 uses: github/issue-metrics@637a24e71b78bc10881e61972b19ea9ff736e14a # v3.25.2
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SEARCH_QUERY: 'repo:ivuorinen/actions is:issue created:${{ env.last_month }} -reason:"not planned"' SEARCH_QUERY: 'repo:ivuorinen/actions is:issue created:${{ env.last_month }} -reason:"not planned"'

View File

@@ -91,7 +91,7 @@ jobs:
- name: Upload Reports - name: Upload Reports
if: always() if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with: with:
name: MegaLinter reports name: MegaLinter reports
path: | path: |
@@ -101,7 +101,7 @@ jobs:
- name: Upload SARIF Report - name: Upload SARIF Report
if: always() && hashFiles('megalinter-reports/sarif/*.sarif') if: always() && hashFiles('megalinter-reports/sarif/*.sarif')
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: megalinter-reports/sarif sarif_file: megalinter-reports/sarif
category: megalinter category: megalinter

View File

@@ -73,14 +73,14 @@ jobs:
if: always() if: always()
- name: Upload SARIF file - name: Upload SARIF file
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
if: always() && hashFiles('_tests/reports/test-results.sarif') != '' if: always() && hashFiles('_tests/reports/test-results.sarif') != ''
with: with:
sarif_file: _tests/reports/test-results.sarif sarif_file: _tests/reports/test-results.sarif
category: github-actions-tests category: github-actions-tests
- name: Upload unit test results - name: Upload unit test results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
if: always() if: always()
with: with:
name: unit-test-results name: unit-test-results
@@ -133,7 +133,7 @@ jobs:
fi fi
- name: Upload integration test results - name: Upload integration test results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
if: always() && steps.check-integration-reports.outputs.reports-found == 'true' if: always() && steps.check-integration-reports.outputs.reports-found == 'true'
with: with:
name: integration-test-results name: integration-test-results
@@ -167,7 +167,7 @@ jobs:
run: make test-coverage run: make test-coverage
- name: Upload coverage report - name: Upload coverage report
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with: with:
name: coverage-report name: coverage-report
path: _tests/coverage/ path: _tests/coverage/
@@ -263,7 +263,7 @@ jobs:
steps: steps:
- name: Download test results - name: Download test results
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with: with:
pattern: '*-test-results' pattern: '*-test-results'
merge-multiple: true merge-multiple: true

View File

@@ -49,7 +49,7 @@ jobs:
- name: Create Pull Request - name: Create Pull Request
if: steps.action-versioning.outputs.updated == 'true' if: steps.action-versioning.outputs.updated == 'true'
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'chore: update action references to ${{ steps.version.outputs.major }}' commit-message: 'chore: update action references to ${{ steps.version.outputs.major }}'
@@ -78,7 +78,7 @@ jobs:
- name: Check for Annual Bump - name: Check for Annual Bump
if: steps.action-versioning.outputs.needs-annual-bump == 'true' if: steps.action-versioning.outputs.needs-annual-bump == 'true'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with: with:
script: | script: |
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();

2
.nvmrc
View File

@@ -1 +1 @@
v22 24

View File

@@ -84,12 +84,12 @@ repos:
args: ['-shellcheck='] args: ['-shellcheck=']
- repo: https://github.com/renovatebot/pre-commit-hooks - repo: https://github.com/renovatebot/pre-commit-hooks
rev: 41.149.2 rev: 41.159.4
hooks: hooks:
- id: renovate-config-validator - id: renovate-config-validator
- repo: https://github.com/bridgecrewio/checkov.git - repo: https://github.com/bridgecrewio/checkov.git
rev: '3.2.487' rev: '3.2.489'
hooks: hooks:
- id: checkov - id: checkov
args: args:

View File

@@ -4,10 +4,6 @@
# * For JavaScript, use typescript # * For JavaScript, use typescript
# Special requirements: # Special requirements:
# * csharp: Requires the presence of a .sln file in the project folder. # * csharp: Requires the presence of a .sln file in the project folder.
language: bash
# whether to use the project's gitignore file to ignore files
# Added on 2025-04-07
ignore_all_files_in_gitignore: true ignore_all_files_in_gitignore: true
# list of additional paths to ignore # list of additional paths to ignore
# same syntax as gitignore, so you can use * and ** # same syntax as gitignore, so you can use * and **
@@ -66,3 +62,8 @@ excluded_tools: []
initial_prompt: '' initial_prompt: ''
project_name: 'actions' project_name: 'actions'
languages:
- bash
- python
included_optional_tools: []
encoding: utf-8

View File

@@ -1,7 +1,7 @@
# Makefile for GitHub Actions repository # Makefile for GitHub Actions repository
# Provides organized task management with parallel execution capabilities # Provides organized task management with parallel execution capabilities
.PHONY: help all docs lint format check clean install-tools test test-unit test-integration test-coverage generate-tests generate-tests-dry test-generate-tests docker-build docker-push docker-test docker-login docker-all release update-version-refs bump-major-version check-version-refs .PHONY: help all docs update-catalog lint format check clean install-tools test test-unit test-integration test-coverage generate-tests generate-tests-dry test-generate-tests docker-build docker-push docker-test docker-login docker-all release release-dry release-prep release-tag release-undo update-version-refs bump-major-version check-version-refs
.DEFAULT_GOAL := help .DEFAULT_GOAL := help
# Colors for output # Colors for output
@@ -43,7 +43,7 @@ help: ## Show this help message
@echo " make check # Quick syntax checks" @echo " make check # Quick syntax checks"
# Main targets # Main targets
all: install-tools update-validators docs format lint precommit ## Generate docs, format, lint, and run pre-commit all: install-tools update-validators docs update-catalog format lint precommit ## Generate docs, format, lint, and run pre-commit
@echo "$(GREEN)✅ All tasks completed successfully$(RESET)" @echo "$(GREEN)✅ All tasks completed successfully$(RESET)"
docs: ## Generate documentation for all actions docs: ## Generate documentation for all actions
@@ -66,6 +66,16 @@ docs: ## Generate documentation for all actions
done; \ done; \
[ $$failed -eq 0 ] && echo "$(GREEN)✅ All documentation updated successfully$(RESET)" || { echo "$(RED)$$failed documentation updates failed$(RESET)"; exit 1; } [ $$failed -eq 0 ] && echo "$(GREEN)✅ All documentation updated successfully$(RESET)" || { echo "$(RED)$$failed documentation updates failed$(RESET)"; exit 1; }
update-catalog: ## Update action catalog in README.md
@echo "$(BLUE)📚 Updating action catalog...$(RESET)"
@if command -v npm >/dev/null 2>&1; then \
npm run update-catalog; \
else \
echo "$(RED)❌ npm not found. Please install Node.js$(RESET)"; \
exit 1; \
fi
@echo "$(GREEN)✅ Action catalog updated$(RESET)"
update-validators: ## Update validation rules for all actions update-validators: ## Update validation rules for all actions
@echo "$(BLUE)🔧 Updating validation rules...$(RESET)" @echo "$(BLUE)🔧 Updating validation rules...$(RESET)"
@if command -v uv >/dev/null 2>&1; then \ @if command -v uv >/dev/null 2>&1; then \
@@ -149,12 +159,36 @@ fix-local-refs-dry: ## Preview local action reference fixes (dry run)
release: ## Create a new release with version tags (usage: make release [VERSION=v2025.10.18]) release: ## Create a new release with version tags (usage: make release [VERSION=v2025.10.18])
@VERSION_TO_USE=$$(if [ -n "$(VERSION)" ]; then echo "$(VERSION)"; else date +v%Y.%m.%d; fi); \ @VERSION_TO_USE=$$(if [ -n "$(VERSION)" ]; then echo "$(VERSION)"; else date +v%Y.%m.%d; fi); \
echo "$(BLUE)🚀 Creating release $$VERSION_TO_USE...$(RESET)"; \ echo "$(BLUE)🚀 Creating release $$VERSION_TO_USE...$(RESET)"; \
sh _tools/release.sh "$$VERSION_TO_USE"; \ sh _tools/release.sh "$$VERSION_TO_USE"
echo "$(GREEN)✅ Release created$(RESET)"; \
echo ""; \ release-dry: ## Preview release without making changes (usage: make release-dry VERSION=v2025.11.01)
echo "$(YELLOW)Next steps:$(RESET)"; \ @if [ -z "$(VERSION)" ]; then \
echo " 1. Review changes: git show HEAD"; \ VERSION_TO_USE=$$(date +v%Y.%m.%d); \
echo " 2. Push tags: git push origin main --tags --force-with-lease" else \
VERSION_TO_USE="$(VERSION)"; \
fi; \
echo "$(BLUE)🔍 Previewing release $$VERSION_TO_USE (dry run)...$(RESET)"; \
sh _tools/release.sh --dry-run "$$VERSION_TO_USE"
release-prep: ## Update action refs and commit (no tags) (usage: make release-prep [VERSION=v2025.11.01])
@VERSION_TO_USE=$$(if [ -n "$(VERSION)" ]; then echo "$(VERSION)"; else date +v%Y.%m.%d; fi); \
echo "$(BLUE)🔧 Preparing release $$VERSION_TO_USE...$(RESET)"; \
sh _tools/release.sh --prep-only "$$VERSION_TO_USE"; \
echo "$(GREEN)✅ Preparation complete$(RESET)"; \
echo "$(YELLOW)Next: make release-tag VERSION=$$VERSION_TO_USE$(RESET)"
release-tag: ## Create tags only (assumes prep done) (usage: make release-tag VERSION=v2025.11.01)
@if [ -z "$(VERSION)" ]; then \
echo "$(RED)❌ Error: VERSION parameter required for release-tag$(RESET)"; \
echo "Usage: make release-tag VERSION=v2025.11.01"; \
exit 1; \
fi; \
echo "$(BLUE)🏷️ Creating tags for release $(VERSION)...$(RESET)"; \
sh _tools/release.sh --tag-only "$(VERSION)"
release-undo: ## Rollback the most recent release (delete tags and reset HEAD)
@echo "$(BLUE)🔙 Rolling back release...$(RESET)"; \
sh _tools/release-undo.sh
update-version-refs: ## Update all action references to a specific version tag (usage: make update-version-refs MAJOR=v2025) update-version-refs: ## Update all action references to a specific version tag (usage: make update-version-refs MAJOR=v2025)
@if [ -z "$(MAJOR)" ]; then \ @if [ -z "$(MAJOR)" ]; then \

182
README.md
View File

@@ -22,53 +22,54 @@ Each action is fully self-contained and can be used independently in any GitHub
## 📚 Action Catalog ## 📚 Action Catalog
This repository contains **43 reusable GitHub Actions** for CI/CD automation. This repository contains **44 reusable GitHub Actions** for CI/CD automation.
### Quick Reference (43 Actions) ### Quick Reference (44 Actions)
| Icon | Action | Category | Description | Key Features | | Icon | Action | Category | Description | Key Features |
|:----:|:-------------------------------------------------------|:-----------|:----------------------------------------------------------------|:---------------------------------------------| |:----:|:-------------------------------------------------------|:-----------|:----------------------------------------------------------------|:---------------------------------------------|
| 🔀 | [`action-versioning`][action-versioning] | Utilities | Automatically update SHA-pinned action references to match l... | Token auth, Outputs |
| 📦 | [`ansible-lint-fix`][ansible-lint-fix] | Linting | Lints and fixes Ansible playbooks, commits changes, and uplo... | Token auth, Outputs | | 📦 | [`ansible-lint-fix`][ansible-lint-fix] | Linting | Lints and fixes Ansible playbooks, commits changes, and uplo... | Token auth, Outputs |
| ✅ | [`biome-check`][biome-check] | Linting | Run Biome check on the repository | Token auth, Outputs | | ✅ | [`biome-check`][biome-check] | Linting | Run Biome check on the repository | Token auth, Outputs |
| ✅ | [`biome-fix`][biome-fix] | Linting | Run Biome fix on the repository | Token auth, Outputs | | ✅ | [`biome-fix`][biome-fix] | Linting | Run Biome fix on the repository | Token auth, Outputs |
| 🛡️ | [`codeql-analysis`][codeql-analysis] | Other | Run CodeQL security analysis for a single language with conf... | Auto-detection, Token auth, Outputs | | 🛡️ | [`codeql-analysis`][codeql-analysis] | Repository | Run CodeQL security analysis for a single language with conf... | Auto-detection, Token auth, Outputs |
| 💾 | [`common-cache`][common-cache] | Repository | Standardized caching strategy for all actions | Caching, Outputs | | 💾 | [`common-cache`][common-cache] | Repository | Standardized caching strategy for all actions | Caching, Outputs |
| 📦 | [`common-file-check`][common-file-check] | Repository | A reusable action to check if a specific file or type of fil... | Outputs | | 📦 | [`common-file-check`][common-file-check] | Repository | A reusable action to check if a specific file or type of fil... | Outputs |
| 🔄 | [`common-retry`][common-retry] | Repository | Standardized retry utility for network operations and flaky ... | Outputs | | 🔄 | [`common-retry`][common-retry] | Repository | Standardized retry utility for network operations and flaky ... | Outputs |
| 🖼️ | [`compress-images`][compress-images] | Repository | Compress images on demand (workflow_dispatch), and at 11pm e... | Token auth, Outputs | | 🖼️ | [`compress-images`][compress-images] | Repository | Compress images on demand (workflow_dispatch), and at 11pm e... | Token auth, Outputs |
| 📝 | [`csharp-build`][csharp-build] | Build | Builds and tests C# projects. | Auto-detection, Outputs | | 📝 | [`csharp-build`][csharp-build] | Build | Builds and tests C# projects. | Auto-detection, Token auth, Outputs |
| 📝 | [`csharp-lint-check`][csharp-lint-check] | Linting | Runs linters like StyleCop or dotnet-format for C# code styl... | Auto-detection, Outputs | | 📝 | [`csharp-lint-check`][csharp-lint-check] | Linting | Runs linters like StyleCop or dotnet-format for C# code styl... | Auto-detection, Token auth, Outputs |
| 📦 | [`csharp-publish`][csharp-publish] | Publishing | Publishes a C# project to GitHub Packages. | Auto-detection, Token auth, Outputs | | 📦 | [`csharp-publish`][csharp-publish] | Publishing | Publishes a C# project to GitHub Packages. | Auto-detection, Token auth, Outputs |
| 📦 | [`docker-build`][docker-build] | Build | Builds a Docker image for multiple architectures with enhanc... | Caching, Auto-detection, Token auth, Outputs | | 📦 | [`docker-build`][docker-build] | Build | Builds a Docker image for multiple architectures with enhanc... | Caching, Auto-detection, Token auth, Outputs |
| ☁️ | [`docker-publish`][docker-publish] | Publishing | Publish a Docker image to GitHub Packages and Docker Hub. | Auto-detection, Outputs | | ☁️ | [`docker-publish`][docker-publish] | Publishing | Publish a Docker image to GitHub Packages and Docker Hub. | Auto-detection, Token auth, Outputs |
| 📦 | [`docker-publish-gh`][docker-publish-gh] | Publishing | Publishes a Docker image to GitHub Packages with advanced se... | Caching, Auto-detection, Token auth, Outputs | | 📦 | [`docker-publish-gh`][docker-publish-gh] | Publishing | Publishes a Docker image to GitHub Packages with advanced se... | Caching, Auto-detection, Token auth, Outputs |
| 📦 | [`docker-publish-hub`][docker-publish-hub] | Publishing | Publishes a Docker image to Docker Hub with enhanced securit... | Caching, Auto-detection, Outputs | | 📦 | [`docker-publish-hub`][docker-publish-hub] | Publishing | Publishes a Docker image to Docker Hub with enhanced securit... | Caching, Auto-detection, Outputs |
| 📝 | [`dotnet-version-detect`][dotnet-version-detect] | Setup | Detects .NET SDK version from global.json or defaults to a s... | Auto-detection, Outputs | | 📝 | [`dotnet-version-detect`][dotnet-version-detect] | Setup | Detects .NET SDK version from global.json or defaults to a s... | Auto-detection, Token auth, Outputs |
| ✅ | [`eslint-check`][eslint-check] | Linting | Run ESLint check on the repository with advanced configurati... | Caching, Outputs | | ✅ | [`eslint-check`][eslint-check] | Linting | Run ESLint check on the repository with advanced configurati... | Caching, Token auth, Outputs |
| 📝 | [`eslint-fix`][eslint-fix] | Linting | Fixes ESLint violations in a project. | Token auth, Outputs | | 📝 | [`eslint-fix`][eslint-fix] | Linting | Fixes ESLint violations in a project. | Token auth, Outputs |
| 🏷️ | [`github-release`][github-release] | Repository | Creates a GitHub release with a version and changelog. | Outputs | | 🏷️ | [`github-release`][github-release] | Repository | Creates a GitHub release with a version and changelog. | Outputs |
| 📦 | [`go-build`][go-build] | Build | Builds the Go project. | Caching, Auto-detection, Outputs | | 📦 | [`go-build`][go-build] | Build | Builds the Go project. | Caching, Auto-detection, Token auth, Outputs |
| 📝 | [`go-lint`][go-lint] | Linting | Run golangci-lint with advanced configuration, caching, and ... | Caching, Outputs | | 📝 | [`go-lint`][go-lint] | Linting | Run golangci-lint with advanced configuration, caching, and ... | Caching, Token auth, Outputs |
| 📝 | [`go-version-detect`][go-version-detect] | Setup | Detects the Go version from the project's go.mod file or def... | Auto-detection, Outputs | | 📝 | [`go-version-detect`][go-version-detect] | Setup | Detects the Go version from the project's go.mod file or def... | Auto-detection, Token auth, Outputs |
| 🖥️ | [`node-setup`][node-setup] | Setup | Sets up Node.js env with advanced version management, cachin... | Caching, Auto-detection, Token auth, Outputs | | 🖥️ | [`node-setup`][node-setup] | Setup | Sets up Node.js env with advanced version management, cachin... | Caching, Auto-detection, Token auth, Outputs |
| 📦 | [`npm-publish`][npm-publish] | Publishing | Publishes the package to the NPM registry with configurable ... | Outputs | | 📦 | [`npm-publish`][npm-publish] | Publishing | Publishes the package to the NPM registry with configurable ... | Token auth, Outputs |
| 🖥️ | [`php-composer`][php-composer] | Testing | Runs Composer install on a repository with advanced caching ... | Auto-detection, Token auth, Outputs | | 🖥️ | [`php-composer`][php-composer] | Testing | Runs Composer install on a repository with advanced caching ... | Auto-detection, Token auth, Outputs |
| 💻 | [`php-laravel-phpunit`][php-laravel-phpunit] | Testing | Setup PHP, install dependencies, generate key, create databa... | Auto-detection, Token auth, Outputs | | 💻 | [`php-laravel-phpunit`][php-laravel-phpunit] | Testing | Setup PHP, install dependencies, generate key, create databa... | Auto-detection, Token auth, Outputs |
| ✅ | [`php-tests`][php-tests] | Testing | Run PHPUnit tests on the repository | Token auth, Outputs | | ✅ | [`php-tests`][php-tests] | Testing | Run PHPUnit tests on the repository | Token auth, Outputs |
| 📝 | [`php-version-detect`][php-version-detect] | Setup | Detects the PHP version from the project's composer.json, ph... | Auto-detection, Outputs | | 📝 | [`php-version-detect`][php-version-detect] | Setup | Detects the PHP version from the project's composer.json, ph... | Auto-detection, Token auth, Outputs |
| ✅ | [`pr-lint`][pr-lint] | Linting | Runs MegaLinter against pull requests | Caching, Auto-detection, Token auth, Outputs | | ✅ | [`pr-lint`][pr-lint] | Linting | Runs MegaLinter against pull requests | Caching, Auto-detection, Token auth, Outputs |
| 📦 | [`pre-commit`][pre-commit] | Linting | Runs pre-commit on the repository and pushes the fixes back ... | Auto-detection, Token auth, Outputs | | 📦 | [`pre-commit`][pre-commit] | Linting | Runs pre-commit on the repository and pushes the fixes back ... | Auto-detection, Token auth, Outputs |
| ✅ | [`prettier-check`][prettier-check] | Linting | Run Prettier check on the repository with advanced configura... | Caching, Outputs | | ✅ | [`prettier-check`][prettier-check] | Linting | Run Prettier check on the repository with advanced configura... | Caching, Token auth, Outputs |
| 📝 | [`prettier-fix`][prettier-fix] | Linting | Run Prettier to fix code style violations | Token auth, Outputs | | 📝 | [`prettier-fix`][prettier-fix] | Linting | Run Prettier to fix code style violations | Token auth, Outputs |
| 📝 | [`python-lint-fix`][python-lint-fix] | Linting | Lints and fixes Python files, commits changes, and uploads S... | Caching, Auto-detection, Token auth, Outputs | | 📝 | [`python-lint-fix`][python-lint-fix] | Linting | Lints and fixes Python files, commits changes, and uploads S... | Caching, Auto-detection, Token auth, Outputs |
| 📝 | [`python-version-detect`][python-version-detect] | Setup | Detects Python version from project configuration files or d... | Auto-detection, Outputs | | 📝 | [`python-version-detect`][python-version-detect] | Setup | Detects Python version from project configuration files or d... | Auto-detection, Token auth, Outputs |
| 📝 | [`python-version-detect-v2`][python-version-detect-v2] | Setup | Detects Python version from project configuration files usin... | Auto-detection, Outputs | | 📝 | [`python-version-detect-v2`][python-version-detect-v2] | Setup | Detects Python version from project configuration files usin... | Auto-detection, Token auth, Outputs |
| 📦 | [`release-monthly`][release-monthly] | Repository | Creates a release for the current month, incrementing patch ... | Token auth, Outputs | | 📦 | [`release-monthly`][release-monthly] | Repository | Creates a release for the current month, incrementing patch ... | Token auth, Outputs |
| 🔀 | [`set-git-config`][set-git-config] | Setup | Sets Git configuration for actions. | Token auth, Outputs | | 🔀 | [`set-git-config`][set-git-config] | Setup | Sets Git configuration for actions. | Token auth, Outputs |
| 📦 | [`stale`][stale] | Repository | A GitHub Action to close stale issues and pull requests. | Token auth, Outputs | | 📦 | [`stale`][stale] | Repository | A GitHub Action to close stale issues and pull requests. | Token auth, Outputs |
| 🏷️ | [`sync-labels`][sync-labels] | Repository | Sync labels from a YAML file to a GitHub repository | Token auth, Outputs | | 🏷️ | [`sync-labels`][sync-labels] | Repository | Sync labels from a YAML file to a GitHub repository | Token auth, Outputs |
| 🖥️ | [`terraform-lint-fix`][terraform-lint-fix] | Linting | Lints and fixes Terraform files with advanced validation and... | Token auth, Outputs | | 🖥️ | [`terraform-lint-fix`][terraform-lint-fix] | Linting | Lints and fixes Terraform files with advanced validation and... | Token auth, Outputs |
| 🛡️ | [`validate-inputs`][validate-inputs] | Other | Centralized Python-based input validation for GitHub Actions... | Token auth, Outputs | | 🛡️ | [`validate-inputs`][validate-inputs] | Validation | Centralized Python-based input validation for GitHub Actions... | Token auth, Outputs |
| 📦 | [`version-file-parser`][version-file-parser] | Utilities | Universal parser for common version detection files (.tool-v... | Auto-detection, Outputs | | 📦 | [`version-file-parser`][version-file-parser] | Utilities | Universal parser for common version detection files (.tool-v... | Auto-detection, Outputs |
| ✅ | [`version-validator`][version-validator] | Utilities | Validates and normalizes version strings using customizable ... | Auto-detection, Outputs | | ✅ | [`version-validator`][version-validator] | Utilities | Validates and normalizes version strings using customizable ... | Auto-detection, Outputs |
@@ -78,20 +79,21 @@ This repository contains **43 reusable GitHub Actions** for CI/CD automation.
| Action | Description | Languages | Features | | Action | Description | Languages | Features |
|:----------------------------------------------------------|:------------------------------------------------------|:--------------------------------|:---------------------------------------------| |:----------------------------------------------------------|:------------------------------------------------------|:--------------------------------|:---------------------------------------------|
| 📝 [`dotnet-version-detect`][dotnet-version-detect] | Detects .NET SDK version from global.json or defau... | C#, .NET | Auto-detection, Outputs | | 📝 [`dotnet-version-detect`][dotnet-version-detect] | Detects .NET SDK version from global.json or defau... | C#, .NET | Auto-detection, Token auth, Outputs |
| 📝 [`go-version-detect`][go-version-detect] | Detects the Go version from the project's go.mod f... | Go | Auto-detection, Outputs | | 📝 [`go-version-detect`][go-version-detect] | Detects the Go version from the project's go.mod f... | Go | Auto-detection, Token auth, Outputs |
| 🖥️ [`node-setup`][node-setup] | Sets up Node.js env with advanced version manageme... | Node.js, JavaScript, TypeScript | Caching, Auto-detection, Token auth, Outputs | | 🖥️ [`node-setup`][node-setup] | Sets up Node.js env with advanced version manageme... | Node.js, JavaScript, TypeScript | Caching, Auto-detection, Token auth, Outputs |
| 📝 [`php-version-detect`][php-version-detect] | Detects the PHP version from the project's compose... | PHP | Auto-detection, Outputs | | 📝 [`php-version-detect`][php-version-detect] | Detects the PHP version from the project's compose... | PHP | Auto-detection, Token auth, Outputs |
| 📝 [`python-version-detect`][python-version-detect] | Detects Python version from project configuration ... | Python | Auto-detection, Outputs | | 📝 [`python-version-detect`][python-version-detect] | Detects Python version from project configuration ... | Python | Auto-detection, Token auth, Outputs |
| 📝 [`python-version-detect-v2`][python-version-detect-v2] | Detects Python version from project configuration ... | Python | Auto-detection, Outputs | | 📝 [`python-version-detect-v2`][python-version-detect-v2] | Detects Python version from project configuration ... | Python | Auto-detection, Token auth, Outputs |
| 🔀 [`set-git-config`][set-git-config] | Sets Git configuration for actions. | - | Token auth, Outputs | | 🔀 [`set-git-config`][set-git-config] | Sets Git configuration for actions. | - | Token auth, Outputs |
#### 🛠️ Utilities (2 actions) #### 🛠️ Utilities (3 actions)
| Action | Description | Languages | Features | | Action | Description | Languages | Features |
|:------------------------------------------------|:------------------------------------------------------|:----------|:------------------------| |:------------------------------------------------|:------------------------------------------------------|:----------------------------|:------------------------|
| 📦 [`version-file-parser`][version-file-parser] | Universal parser for common version detection file... | - | Auto-detection, Outputs | | 🔀 [`action-versioning`][action-versioning] | Automatically update SHA-pinned action references ... | - | Token auth, Outputs |
| [`version-validator`][version-validator] | Validates and normalizes version strings using cus... | - | Auto-detection, Outputs | | 📦 [`version-file-parser`][version-file-parser] | Universal parser for common version detection file... | Multiple Languages | Auto-detection, Outputs |
| ✅ [`version-validator`][version-validator] | Validates and normalizes version strings using cus... | Semantic Versioning, CalVer | Auto-detection, Outputs |
#### 📝 Linting (13 actions) #### 📝 Linting (13 actions)
@@ -100,13 +102,13 @@ This repository contains **43 reusable GitHub Actions** for CI/CD automation.
| 📦 [`ansible-lint-fix`][ansible-lint-fix] | Lints and fixes Ansible playbooks, commits changes... | Ansible, YAML | Token auth, Outputs | | 📦 [`ansible-lint-fix`][ansible-lint-fix] | Lints and fixes Ansible playbooks, commits changes... | Ansible, YAML | Token auth, Outputs |
| ✅ [`biome-check`][biome-check] | Run Biome check on the repository | JavaScript, TypeScript, JSON | Token auth, Outputs | | ✅ [`biome-check`][biome-check] | Run Biome check on the repository | JavaScript, TypeScript, JSON | Token auth, Outputs |
| ✅ [`biome-fix`][biome-fix] | Run Biome fix on the repository | JavaScript, TypeScript, JSON | Token auth, Outputs | | ✅ [`biome-fix`][biome-fix] | Run Biome fix on the repository | JavaScript, TypeScript, JSON | Token auth, Outputs |
| 📝 [`csharp-lint-check`][csharp-lint-check] | Runs linters like StyleCop or dotnet-format for C#... | C#, .NET | Auto-detection, Outputs | | 📝 [`csharp-lint-check`][csharp-lint-check] | Runs linters like StyleCop or dotnet-format for C#... | C#, .NET | Auto-detection, Token auth, Outputs |
| ✅ [`eslint-check`][eslint-check] | Run ESLint check on the repository with advanced c... | JavaScript, TypeScript | Caching, Outputs | | ✅ [`eslint-check`][eslint-check] | Run ESLint check on the repository with advanced c... | JavaScript, TypeScript | Caching, Token auth, Outputs |
| 📝 [`eslint-fix`][eslint-fix] | Fixes ESLint violations in a project. | JavaScript, TypeScript | Token auth, Outputs | | 📝 [`eslint-fix`][eslint-fix] | Fixes ESLint violations in a project. | JavaScript, TypeScript | Token auth, Outputs |
| 📝 [`go-lint`][go-lint] | Run golangci-lint with advanced configuration, cac... | Go | Caching, Outputs | | 📝 [`go-lint`][go-lint] | Run golangci-lint with advanced configuration, cac... | Go | Caching, Token auth, Outputs |
| ✅ [`pr-lint`][pr-lint] | Runs MegaLinter against pull requests | - | Caching, Auto-detection, Token auth, Outputs | | ✅ [`pr-lint`][pr-lint] | Runs MegaLinter against pull requests | Conventional Commits | Caching, Auto-detection, Token auth, Outputs |
| 📦 [`pre-commit`][pre-commit] | Runs pre-commit on the repository and pushes the f... | - | Auto-detection, Token auth, Outputs | | 📦 [`pre-commit`][pre-commit] | Runs pre-commit on the repository and pushes the f... | Python, Multiple Languages | Auto-detection, Token auth, Outputs |
| ✅ [`prettier-check`][prettier-check] | Run Prettier check on the repository with advanced... | JavaScript, TypeScript, Markdown, YAML, JSON | Caching, Outputs | | ✅ [`prettier-check`][prettier-check] | Run Prettier check on the repository with advanced... | JavaScript, TypeScript, Markdown, YAML, JSON | Caching, Token auth, Outputs |
| 📝 [`prettier-fix`][prettier-fix] | Run Prettier to fix code style violations | JavaScript, TypeScript, Markdown, YAML, JSON | Token auth, Outputs | | 📝 [`prettier-fix`][prettier-fix] | Run Prettier to fix code style violations | JavaScript, TypeScript, Markdown, YAML, JSON | Token auth, Outputs |
| 📝 [`python-lint-fix`][python-lint-fix] | Lints and fixes Python files, commits changes, and... | Python | Caching, Auto-detection, Token auth, Outputs | | 📝 [`python-lint-fix`][python-lint-fix] | Lints and fixes Python files, commits changes, and... | Python | Caching, Auto-detection, Token auth, Outputs |
| 🖥️ [`terraform-lint-fix`][terraform-lint-fix] | Lints and fixes Terraform files with advanced vali... | Terraform, HCL | Token auth, Outputs | | 🖥️ [`terraform-lint-fix`][terraform-lint-fix] | Lints and fixes Terraform files with advanced vali... | Terraform, HCL | Token auth, Outputs |
@@ -123,37 +125,45 @@ This repository contains **43 reusable GitHub Actions** for CI/CD automation.
| Action | Description | Languages | Features | | Action | Description | Languages | Features |
|:----------------------------------|:------------------------------------------------------|:----------|:---------------------------------------------| |:----------------------------------|:------------------------------------------------------|:----------|:---------------------------------------------|
| 📝 [`csharp-build`][csharp-build] | Builds and tests C# projects. | C#, .NET | Auto-detection, Outputs | | 📝 [`csharp-build`][csharp-build] | Builds and tests C# projects. | C#, .NET | Auto-detection, Token auth, Outputs |
| 📦 [`docker-build`][docker-build] | Builds a Docker image for multiple architectures w... | Docker | Caching, Auto-detection, Token auth, Outputs | | 📦 [`docker-build`][docker-build] | Builds a Docker image for multiple architectures w... | Docker | Caching, Auto-detection, Token auth, Outputs |
| 📦 [`go-build`][go-build] | Builds the Go project. | Go | Caching, Auto-detection, Outputs | | 📦 [`go-build`][go-build] | Builds the Go project. | Go | Caching, Auto-detection, Token auth, Outputs |
#### 🚀 Publishing (5 actions) #### 🚀 Publishing (5 actions)
| Action | Description | Languages | Features | | Action | Description | Languages | Features |
|:----------------------------------------------|:------------------------------------------------------|:-------------|:---------------------------------------------| |:----------------------------------------------|:------------------------------------------------------|:-------------|:---------------------------------------------|
| 📦 [`csharp-publish`][csharp-publish] | Publishes a C# project to GitHub Packages. | C#, .NET | Auto-detection, Token auth, Outputs | | 📦 [`csharp-publish`][csharp-publish] | Publishes a C# project to GitHub Packages. | C#, .NET | Auto-detection, Token auth, Outputs |
| ☁️ [`docker-publish`][docker-publish] | Publish a Docker image to GitHub Packages and Dock... | Docker | Auto-detection, Outputs | | ☁️ [`docker-publish`][docker-publish] | Publish a Docker image to GitHub Packages and Dock... | Docker | Auto-detection, Token auth, Outputs |
| 📦 [`docker-publish-gh`][docker-publish-gh] | Publishes a Docker image to GitHub Packages with a... | Docker | Caching, Auto-detection, Token auth, Outputs | | 📦 [`docker-publish-gh`][docker-publish-gh] | Publishes a Docker image to GitHub Packages with a... | Docker | Caching, Auto-detection, Token auth, Outputs |
| 📦 [`docker-publish-hub`][docker-publish-hub] | Publishes a Docker image to Docker Hub with enhanc... | Docker | Caching, Auto-detection, Outputs | | 📦 [`docker-publish-hub`][docker-publish-hub] | Publishes a Docker image to Docker Hub with enhanc... | Docker | Caching, Auto-detection, Outputs |
| 📦 [`npm-publish`][npm-publish] | Publishes the package to the NPM registry with con... | Node.js, npm | Outputs | | 📦 [`npm-publish`][npm-publish] | Publishes the package to the NPM registry with con... | Node.js, npm | Token auth, Outputs |
#### 📦 Repository (8 actions) #### 📦 Repository (9 actions)
| Action | Description | Languages | Features | | Action | Description | Languages | Features |
|:--------------------------------------------|:------------------------------------------------------|:----------|:--------------------| |:--------------------------------------------|:------------------------------------------------------|:--------------------------------------------------------|:------------------------------------|
| 💾 [`common-cache`][common-cache] | Standardized caching strategy for all actions | - | Caching, Outputs | | 🛡️ [`codeql-analysis`][codeql-analysis] | Run CodeQL security analysis for a single language... | JavaScript, TypeScript, Python, Java, C#, C++, Go, Ruby | Auto-detection, Token auth, Outputs |
| 📦 [`common-file-check`][common-file-check] | A reusable action to check if a specific file or t... | - | Outputs | | 💾 [`common-cache`][common-cache] | Standardized caching strategy for all actions | - | Caching, Outputs |
| 🔄 [`common-retry`][common-retry] | Standardized retry utility for network operations ... | - | Outputs | | 📦 [`common-file-check`][common-file-check] | A reusable action to check if a specific file or t... | - | Outputs |
| 🖼️ [`compress-images`][compress-images] | Compress images on demand (workflow_dispatch), and... | - | Token auth, Outputs | | 🔄 [`common-retry`][common-retry] | Standardized retry utility for network operations ... | - | Outputs |
| 🏷 [`github-release`][github-release] | Creates a GitHub release with a version and change... | - | Outputs | | 🖼 [`compress-images`][compress-images] | Compress images on demand (workflow_dispatch), and... | - | Token auth, Outputs |
| 📦 [`release-monthly`][release-monthly] | Creates a release for the current month, increment... | - | Token auth, Outputs | | 🏷️ [`github-release`][github-release] | Creates a GitHub release with a version and change... | - | Outputs |
| 📦 [`stale`][stale] | A GitHub Action to close stale issues and pull req... | - | Token auth, Outputs | | 📦 [`release-monthly`][release-monthly] | Creates a release for the current month, increment... | - | Token auth, Outputs |
| 🏷️ [`sync-labels`][sync-labels] | Sync labels from a YAML file to a GitHub repositor... | - | Token auth, Outputs | | 📦 [`stale`][stale] | A GitHub Action to close stale issues and pull req... | - | Token auth, Outputs |
| 🏷️ [`sync-labels`][sync-labels] | Sync labels from a YAML file to a GitHub repositor... | YAML, GitHub | Token auth, Outputs |
#### ✅ Validation (1 action)
| Action | Description | Languages | Features |
|:-----------------------------------------|:------------------------------------------------------|:---------------------|:--------------------|
| 🛡️ [`validate-inputs`][validate-inputs] | Centralized Python-based input validation for GitH... | YAML, GitHub Actions | Token auth, Outputs |
### Feature Matrix ### Feature Matrix
| Action | Caching | Auto-detection | Token auth | Outputs | | Action | Caching | Auto-detection | Token auth | Outputs |
|:-------------------------------------------------------|:-------:|:--------------:|:----------:|:-------:| |:-------------------------------------------------------|:-------:|:--------------:|:----------:|:-------:|
| [`action-versioning`][action-versioning] | - | - | ✅ | ✅ |
| [`ansible-lint-fix`][ansible-lint-fix] | - | - | ✅ | ✅ | | [`ansible-lint-fix`][ansible-lint-fix] | - | - | ✅ | ✅ |
| [`biome-check`][biome-check] | - | - | ✅ | ✅ | | [`biome-check`][biome-check] | - | - | ✅ | ✅ |
| [`biome-fix`][biome-fix] | - | - | ✅ | ✅ | | [`biome-fix`][biome-fix] | - | - | ✅ | ✅ |
@@ -162,33 +172,33 @@ This repository contains **43 reusable GitHub Actions** for CI/CD automation.
| [`common-file-check`][common-file-check] | - | - | - | ✅ | | [`common-file-check`][common-file-check] | - | - | - | ✅ |
| [`common-retry`][common-retry] | - | - | - | ✅ | | [`common-retry`][common-retry] | - | - | - | ✅ |
| [`compress-images`][compress-images] | - | - | ✅ | ✅ | | [`compress-images`][compress-images] | - | - | ✅ | ✅ |
| [`csharp-build`][csharp-build] | - | ✅ | - | ✅ | | [`csharp-build`][csharp-build] | - | ✅ | | ✅ |
| [`csharp-lint-check`][csharp-lint-check] | - | ✅ | - | ✅ | | [`csharp-lint-check`][csharp-lint-check] | - | ✅ | | ✅ |
| [`csharp-publish`][csharp-publish] | - | ✅ | ✅ | ✅ | | [`csharp-publish`][csharp-publish] | - | ✅ | ✅ | ✅ |
| [`docker-build`][docker-build] | ✅ | ✅ | ✅ | ✅ | | [`docker-build`][docker-build] | ✅ | ✅ | ✅ | ✅ |
| [`docker-publish`][docker-publish] | - | ✅ | - | ✅ | | [`docker-publish`][docker-publish] | - | ✅ | | ✅ |
| [`docker-publish-gh`][docker-publish-gh] | ✅ | ✅ | ✅ | ✅ | | [`docker-publish-gh`][docker-publish-gh] | ✅ | ✅ | ✅ | ✅ |
| [`docker-publish-hub`][docker-publish-hub] | ✅ | ✅ | - | ✅ | | [`docker-publish-hub`][docker-publish-hub] | ✅ | ✅ | - | ✅ |
| [`dotnet-version-detect`][dotnet-version-detect] | - | ✅ | - | ✅ | | [`dotnet-version-detect`][dotnet-version-detect] | - | ✅ | | ✅ |
| [`eslint-check`][eslint-check] | ✅ | - | - | ✅ | | [`eslint-check`][eslint-check] | ✅ | - | | ✅ |
| [`eslint-fix`][eslint-fix] | - | - | ✅ | ✅ | | [`eslint-fix`][eslint-fix] | - | - | ✅ | ✅ |
| [`github-release`][github-release] | - | - | - | ✅ | | [`github-release`][github-release] | - | - | - | ✅ |
| [`go-build`][go-build] | ✅ | ✅ | - | ✅ | | [`go-build`][go-build] | ✅ | ✅ | | ✅ |
| [`go-lint`][go-lint] | ✅ | - | - | ✅ | | [`go-lint`][go-lint] | ✅ | - | | ✅ |
| [`go-version-detect`][go-version-detect] | - | ✅ | - | ✅ | | [`go-version-detect`][go-version-detect] | - | ✅ | | ✅ |
| [`node-setup`][node-setup] | ✅ | ✅ | ✅ | ✅ | | [`node-setup`][node-setup] | ✅ | ✅ | ✅ | ✅ |
| [`npm-publish`][npm-publish] | - | - | - | ✅ | | [`npm-publish`][npm-publish] | - | - | | ✅ |
| [`php-composer`][php-composer] | - | ✅ | ✅ | ✅ | | [`php-composer`][php-composer] | - | ✅ | ✅ | ✅ |
| [`php-laravel-phpunit`][php-laravel-phpunit] | - | ✅ | ✅ | ✅ | | [`php-laravel-phpunit`][php-laravel-phpunit] | - | ✅ | ✅ | ✅ |
| [`php-tests`][php-tests] | - | - | ✅ | ✅ | | [`php-tests`][php-tests] | - | - | ✅ | ✅ |
| [`php-version-detect`][php-version-detect] | - | ✅ | - | ✅ | | [`php-version-detect`][php-version-detect] | - | ✅ | | ✅ |
| [`pr-lint`][pr-lint] | ✅ | ✅ | ✅ | ✅ | | [`pr-lint`][pr-lint] | ✅ | ✅ | ✅ | ✅ |
| [`pre-commit`][pre-commit] | - | ✅ | ✅ | ✅ | | [`pre-commit`][pre-commit] | - | ✅ | ✅ | ✅ |
| [`prettier-check`][prettier-check] | ✅ | - | - | ✅ | | [`prettier-check`][prettier-check] | ✅ | - | | ✅ |
| [`prettier-fix`][prettier-fix] | - | - | ✅ | ✅ | | [`prettier-fix`][prettier-fix] | - | - | ✅ | ✅ |
| [`python-lint-fix`][python-lint-fix] | ✅ | ✅ | ✅ | ✅ | | [`python-lint-fix`][python-lint-fix] | ✅ | ✅ | ✅ | ✅ |
| [`python-version-detect`][python-version-detect] | - | ✅ | - | ✅ | | [`python-version-detect`][python-version-detect] | - | ✅ | | ✅ |
| [`python-version-detect-v2`][python-version-detect-v2] | - | ✅ | - | ✅ | | [`python-version-detect-v2`][python-version-detect-v2] | - | ✅ | | ✅ |
| [`release-monthly`][release-monthly] | - | - | ✅ | ✅ | | [`release-monthly`][release-monthly] | - | - | ✅ | ✅ |
| [`set-git-config`][set-git-config] | - | - | ✅ | ✅ | | [`set-git-config`][set-git-config] | - | - | ✅ | ✅ |
| [`stale`][stale] | - | - | ✅ | ✅ | | [`stale`][stale] | - | - | ✅ | ✅ |
@@ -200,25 +210,34 @@ This repository contains **43 reusable GitHub Actions** for CI/CD automation.
### Language Support ### Language Support
| Language | Actions | | Language | Actions |
|:-----------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |:---------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| .NET | [`csharp-build`][csharp-build], [`csharp-lint-check`][csharp-lint-check], [`csharp-publish`][csharp-publish], [`dotnet-version-detect`][dotnet-version-detect] | | .NET | [`csharp-build`][csharp-build], [`csharp-lint-check`][csharp-lint-check], [`csharp-publish`][csharp-publish], [`dotnet-version-detect`][dotnet-version-detect] |
| Ansible | [`ansible-lint-fix`][ansible-lint-fix] | | Ansible | [`ansible-lint-fix`][ansible-lint-fix] |
| C# | [`csharp-build`][csharp-build], [`csharp-lint-check`][csharp-lint-check], [`csharp-publish`][csharp-publish], [`dotnet-version-detect`][dotnet-version-detect] | | C# | [`codeql-analysis`][codeql-analysis], [`csharp-build`][csharp-build], [`csharp-lint-check`][csharp-lint-check], [`csharp-publish`][csharp-publish], [`dotnet-version-detect`][dotnet-version-detect] |
| Docker | [`docker-build`][docker-build], [`docker-publish`][docker-publish], [`docker-publish-gh`][docker-publish-gh], [`docker-publish-hub`][docker-publish-hub] | | C++ | [`codeql-analysis`][codeql-analysis] |
| Go | [`go-build`][go-build], [`go-lint`][go-lint], [`go-version-detect`][go-version-detect] | | CalVer | [`version-validator`][version-validator] |
| HCL | [`terraform-lint-fix`][terraform-lint-fix] | | Conventional Commits | [`pr-lint`][pr-lint] |
| JSON | [`biome-check`][biome-check], [`biome-fix`][biome-fix], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] | | Docker | [`docker-build`][docker-build], [`docker-publish`][docker-publish], [`docker-publish-gh`][docker-publish-gh], [`docker-publish-hub`][docker-publish-hub] |
| JavaScript | [`biome-check`][biome-check], [`biome-fix`][biome-fix], [`eslint-check`][eslint-check], [`eslint-fix`][eslint-fix], [`node-setup`][node-setup], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] | | GitHub | [`sync-labels`][sync-labels] |
| Laravel | [`php-laravel-phpunit`][php-laravel-phpunit] | | GitHub Actions | [`validate-inputs`][validate-inputs] |
| Markdown | [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] | | Go | [`codeql-analysis`][codeql-analysis], [`go-build`][go-build], [`go-lint`][go-lint], [`go-version-detect`][go-version-detect] |
| Node.js | [`node-setup`][node-setup], [`npm-publish`][npm-publish] | | HCL | [`terraform-lint-fix`][terraform-lint-fix] |
| PHP | [`php-composer`][php-composer], [`php-laravel-phpunit`][php-laravel-phpunit], [`php-tests`][php-tests], [`php-version-detect`][php-version-detect] | | JSON | [`biome-check`][biome-check], [`biome-fix`][biome-fix], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] |
| Python | [`python-lint-fix`][python-lint-fix], [`python-version-detect`][python-version-detect], [`python-version-detect-v2`][python-version-detect-v2] | | Java | [`codeql-analysis`][codeql-analysis] |
| Terraform | [`terraform-lint-fix`][terraform-lint-fix] | | JavaScript | [`biome-check`][biome-check], [`biome-fix`][biome-fix], [`codeql-analysis`][codeql-analysis], [`eslint-check`][eslint-check], [`eslint-fix`][eslint-fix], [`node-setup`][node-setup], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] |
| TypeScript | [`biome-check`][biome-check], [`biome-fix`][biome-fix], [`eslint-check`][eslint-check], [`eslint-fix`][eslint-fix], [`node-setup`][node-setup], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] | | Laravel | [`php-laravel-phpunit`][php-laravel-phpunit] |
| YAML | [`ansible-lint-fix`][ansible-lint-fix], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] | | Markdown | [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] |
| npm | [`npm-publish`][npm-publish] | | Multiple Languages | [`pre-commit`][pre-commit], [`version-file-parser`][version-file-parser] |
| Node.js | [`node-setup`][node-setup], [`npm-publish`][npm-publish] |
| PHP | [`php-composer`][php-composer], [`php-laravel-phpunit`][php-laravel-phpunit], [`php-tests`][php-tests], [`php-version-detect`][php-version-detect] |
| Python | [`codeql-analysis`][codeql-analysis], [`pre-commit`][pre-commit], [`python-lint-fix`][python-lint-fix], [`python-version-detect`][python-version-detect], [`python-version-detect-v2`][python-version-detect-v2] |
| Ruby | [`codeql-analysis`][codeql-analysis] |
| Semantic Versioning | [`version-validator`][version-validator] |
| Terraform | [`terraform-lint-fix`][terraform-lint-fix] |
| TypeScript | [`biome-check`][biome-check], [`biome-fix`][biome-fix], [`codeql-analysis`][codeql-analysis], [`eslint-check`][eslint-check], [`eslint-fix`][eslint-fix], [`node-setup`][node-setup], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix] |
| YAML | [`ansible-lint-fix`][ansible-lint-fix], [`prettier-check`][prettier-check], [`prettier-fix`][prettier-fix], [`sync-labels`][sync-labels], [`validate-inputs`][validate-inputs] |
| npm | [`npm-publish`][npm-publish] |
### Action Usage ### Action Usage
@@ -226,7 +245,7 @@ All actions can be used independently in your workflows:
```yaml ```yaml
# Recommended: Use pinned refs for supply-chain security # Recommended: Use pinned refs for supply-chain security
- uses: ivuorinen/actions/action-name@2025-01-15 # Date-based tag - uses: ivuorinen/actions/action-name@vYYYY-MM-DD # Date-based tag (example)
with: with:
# action-specific inputs # action-specific inputs
@@ -240,6 +259,7 @@ All actions can be used independently in your workflows:
<!-- Reference Links --> <!-- Reference Links -->
[action-versioning]: action-versioning/README.md
[ansible-lint-fix]: ansible-lint-fix/README.md [ansible-lint-fix]: ansible-lint-fix/README.md
[biome-check]: biome-check/README.md [biome-check]: biome-check/README.md
[biome-fix]: biome-fix/README.md [biome-fix]: biome-fix/README.md

View File

@@ -203,7 +203,7 @@ install_shellspec() {
# Pinned SHA256 checksum for ShellSpec 0.28.1 # Pinned SHA256 checksum for ShellSpec 0.28.1
# Source: https://github.com/shellspec/shellspec/archive/refs/tags/0.28.1.tar.gz # Source: https://github.com/shellspec/shellspec/archive/refs/tags/0.28.1.tar.gz
local checksum="351e7a63b8df47c07b022c19d21a167b85693f5eb549fa96e64f64844b680024" local checksum="400d835466429a5fe6c77a62775a9173729d61dd43e05dfa893e8cf6cb511783"
# Ensure cleanup of the downloaded file # Ensure cleanup of the downloaded file
# Use ${tarball:-} to handle unbound variable when trap fires after function returns # Use ${tarball:-} to handle unbound variable when trap fires after function returns

152
_tools/release-undo.sh Executable file
View File

@@ -0,0 +1,152 @@
#!/bin/sh
# Undo the most recent release by deleting tags and optionally resetting HEAD
set -eu
# Source shared utilities
# shellcheck source=_tools/shared.sh
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# shellcheck disable=SC1091
. "$SCRIPT_DIR/shared.sh"
# Check git availability
require_git
msg_info "Finding most recent release tags..."
# Portable version sort function
# Sorts CalVer tags vYYYY.MM.DD numerically
version_sort_tags() {
# Try GNU sort first (Linux and some macOS with GNU coreutils)
if sort --version 2>/dev/null | grep -q GNU; then
sort -V
return
fi
# Try gsort (macOS with GNU coreutils via Homebrew)
if command -v gsort >/dev/null 2>&1; then
gsort -V
return
fi
# Fallback: awk-based numeric version sort with validation
awk -F. '{
# Validate CalVer format: vYYYY.MM.DD or YYYY.MM.DD
if ($0 !~ /^v?[0-9]+\.[0-9]+\.[0-9]+$/) {
printf "Warning: Skipping malformed tag: %s\n", $0 > "/dev/stderr"
next
}
# Check we have exactly 3 fields after splitting on dots
if (NF != 3) {
printf "Warning: Skipping invalid tag (wrong field count): %s\n", $0 > "/dev/stderr"
next
}
# Save original input before modification
original = $0
# Remove leading v and split into year, month, day
gsub(/^v/, "", $0)
# Verify each field is numeric after field recalculation
if ($1 !~ /^[0-9]+$/ || $2 !~ /^[0-9]+$/ || $3 !~ /^[0-9]+$/) {
printf "Warning: Skipping tag with non-numeric components: %s\n", original > "/dev/stderr"
next
}
printf "%04d.%02d.%02d %s\n", $1, $2, $3, original
}' | sort -n | cut -d' ' -f2
}
# Find all release tags matching vYYYY.MM.DD pattern
all_tags=$(git tag -l 'v[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9][0-9]' | version_sort_tags)
if [ -z "$all_tags" ]; then
msg_warn "No release tags found"
exit 0
fi
# Get most recent tag
latest_tag=$(echo "$all_tags" | tail -n 1)
# Extract version components
version_no_v="${latest_tag#v}"
year=$(echo "$version_no_v" | cut -d'.' -f1)
month=$(echo "$version_no_v" | cut -d'.' -f2)
day=$(echo "$version_no_v" | cut -d'.' -f3)
major="v$year"
minor="v$year.$month"
patch="v$year.$month.$day"
printf '\n'
msg_info "Most recent release:"
printf ' Patch: %s\n' "$patch"
printf ' Minor: %s\n' "$minor"
printf ' Major: %s\n' "$major"
printf '\n'
# Show which tags exist
msg_info "Tags that will be deleted:"
for tag in "$patch" "$minor" "$major"; do
if check_tag_exists "$tag"; then
tag_sha=$(git rev-list -n 1 "$tag")
tag_sha_short=$(echo "$tag_sha" | cut -c1-7)
printf ' %s (points to %s)\n' "$tag" "$tag_sha_short"
fi
done
printf '\n'
# Check if HEAD commit is a release commit
head_message=$(git log -1 --pretty=%s)
if echo "$head_message" | grep -q "^chore: update action references for release"; then
msg_warn "Last commit appears to be a release preparation commit:"
printf ' %s\n' "$head_message"
printf '\n'
reset_head=true
else
reset_head=false
fi
# Confirm deletion
msg_warn "This will:"
printf ' 1. Delete tags: %s, %s, %s\n' "$patch" "$minor" "$major"
if [ "$reset_head" = "true" ]; then
printf ' 2. Reset HEAD to previous commit (undo release prep)\n'
fi
printf '\n'
if ! prompt_confirmation "Proceed with rollback?"; then
msg_warn "Rollback cancelled"
exit 0
fi
printf '\n'
# Delete tags
msg_info "Deleting tags..."
for tag in "$patch" "$minor" "$major"; do
if check_tag_exists "$tag"; then
git tag -d "$tag"
msg_item "Deleted tag: $tag"
else
msg_notice "Tag not found: $tag (skipping)"
fi
done
# Reset HEAD if needed
if [ "$reset_head" = "true" ]; then
printf '\n'
msg_info "Resetting HEAD to previous commit..."
git reset --hard HEAD~1
msg_item "Reset complete"
new_head=$(git rev-parse HEAD)
new_head_short=$(echo "$new_head" | cut -c1-7)
printf 'New HEAD: %s%s%s\n' "$GREEN" "$new_head_short" "$NC"
fi
printf '\n'
msg_done "Rollback complete"
printf '\n'
msg_warn "Note:"
printf ' Tags were deleted locally only\n'
printf ' If you had pushed the tags, delete them from remote:\n'
printf ' git push origin --delete %s %s %s\n' "$patch" "$minor" "$major"

View File

@@ -2,7 +2,59 @@
# Release script for creating versioned tags and updating action references # Release script for creating versioned tags and updating action references
set -eu set -eu
VERSION="${1:-}" # Parse arguments
VERSION=""
DRY_RUN=false
SKIP_CONFIRM=false
PREP_ONLY=false
TAG_ONLY=false
while [ $# -gt 0 ]; do
case "$1" in
--dry-run)
DRY_RUN=true
shift
;;
--yes|--no-confirm)
SKIP_CONFIRM=true
shift
;;
--prep-only)
PREP_ONLY=true
shift
;;
--tag-only)
TAG_ONLY=true
shift
;;
--help|-h)
printf 'Usage: %s [OPTIONS] VERSION\n' "$0"
printf '\n'
printf 'Options:\n'
printf ' --dry-run Show what would happen without making changes\n'
printf ' --yes Skip confirmation prompt\n'
printf ' --no-confirm Alias for --yes\n'
printf ' --prep-only Only update refs and commit (no tags)\n'
printf ' --tag-only Only create tags (assumes prep done)\n'
printf ' --help, -h Show this help message\n'
printf '\n'
printf 'Examples:\n'
printf ' %s v2025.11.01\n' "$0"
printf ' %s --dry-run v2025.11.01\n' "$0"
printf ' %s --yes v2025.11.01\n' "$0"
exit 0
;;
-*)
printf 'Unknown option: %s\n' "$1" >&2
printf 'Use --help for usage information\n' >&2
exit 1
;;
*)
VERSION="$1"
shift
;;
esac
done
# Source shared utilities # Source shared utilities
# shellcheck source=_tools/shared.sh # shellcheck source=_tools/shared.sh
@@ -11,15 +63,17 @@ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
. "$SCRIPT_DIR/shared.sh" . "$SCRIPT_DIR/shared.sh"
if [ -z "$VERSION" ]; then if [ -z "$VERSION" ]; then
printf '%b' "${RED}Error: VERSION argument required${NC}\n" msg_error "VERSION argument required"
printf 'Usage: %s v2025.10.18\n' "$0" printf 'Usage: %s [OPTIONS] VERSION\n' "$0"
printf 'Use --help for more information\n'
exit 1 exit 1
fi fi
# Validate version format # Validate version format
if ! validate_version "$VERSION"; then if ! validate_version "$VERSION"; then
printf '%b' "${RED}Error: Invalid version format: $VERSION${NC}\n" msg_error "Invalid version format: $VERSION"
printf 'Expected: vYYYY.MM.DD (e.g., v2025.10.18)\n' printf 'Expected: vYYYY.MM.DD with zero-padded month/day (e.g., v2025.10.18, v2025.01.05)\n'
printf 'Invalid: v2025.1.5 (must be zero-padded)\n'
exit 1 exit 1
fi fi
@@ -35,68 +89,201 @@ major="v$year"
minor="v$year.$month" minor="v$year.$month"
patch="v$year.$month.$day" patch="v$year.$month.$day"
printf '%b' "${BLUE}Creating release $VERSION${NC}\n" # Show dry-run banner if applicable
if [ "$DRY_RUN" = "true" ]; then
msg_plain "$YELLOW" "=== DRY RUN MODE ==="
printf 'No changes will be made to git repository\n'
printf '\n'
fi
msg_info "Creating release $VERSION"
printf ' Major: %s\n' "$major" printf ' Major: %s\n' "$major"
printf ' Minor: %s\n' "$minor" printf ' Minor: %s\n' "$minor"
printf ' Patch: %s\n' "$patch" printf ' Patch: %s\n' "$patch"
printf '\n' printf '\n'
# Check if git is available (required for all modes)
if ! require_git 2>/dev/null; then
msg_error "git not available"
exit 1
fi
# Pre-flight checks (skip for --tag-only since prep should be done)
if [ "$TAG_ONLY" = "false" ]; then
msg_info "Running pre-flight checks..."
msg_item "git is available"
# Check if on main branch
if ! check_on_branch "main"; then
current_branch=$(git rev-parse --abbrev-ref HEAD)
msg_error "Not on main branch (currently on: $current_branch)"
if [ "$DRY_RUN" = "false" ]; then
exit 1
fi
else
msg_item "On main branch"
fi
# Check if working directory is clean
if ! check_git_clean; then
msg_error "Working directory has uncommitted changes"
if [ "$DRY_RUN" = "false" ]; then
printf 'Please commit or stash changes before creating a release\n'
exit 1
fi
else
msg_item "Working directory is clean"
fi
# Check if patch tag already exists
if check_tag_exists "$patch"; then
msg_error "Tag $patch already exists"
if [ "$DRY_RUN" = "false" ]; then
printf 'Use a different version or delete the existing tag first\n'
exit 1
fi
else
msg_item "Tag $patch does not exist"
fi
printf '\n'
fi
# Get current commit SHA # Get current commit SHA
current_sha=$(git rev-parse HEAD) current_sha=$(git rev-parse HEAD)
printf '%b' "Current HEAD: ${GREEN}$current_sha${NC}\n" printf 'Current HEAD: %s%s%s\n' "$GREEN" "$current_sha" "$NC"
printf '\n' printf '\n'
# Update all action references to current SHA # Confirmation prompt (skip if --yes or --dry-run)
printf '%b' "${BLUE}Updating action references to $current_sha...${NC}\n" if [ "$DRY_RUN" = "false" ] && [ "$SKIP_CONFIRM" = "false" ]; then
"$SCRIPT_DIR/update-action-refs.sh" "$current_sha" "direct" if ! prompt_confirmation "Proceed with release $VERSION?"; then
msg_warn "Release cancelled by user"
exit 0
fi
printf '\n'
fi
# Commit the changes # Skip prep if --tag-only
if ! git diff --quiet; then if [ "$TAG_ONLY" = "true" ]; then
git add -- */action.yml msg_info "Skipping preparation (--tag-only mode)"
git commit -m "chore: update action references for release $VERSION printf '\n'
else
# Update all action references to current SHA
msg_info "Updating action references to $current_sha..."
if [ "$DRY_RUN" = "true" ]; then
msg_warn "[DRY RUN] Would run: update-action-refs.sh $current_sha direct"
else
"$SCRIPT_DIR/update-action-refs.sh" "$current_sha" "direct"
fi
fi
# Commit the changes (skip if --tag-only)
if [ "$TAG_ONLY" = "false" ]; then
if ! git diff --quiet; then
if [ "$DRY_RUN" = "true" ]; then
msg_warn "[DRY RUN] Would add: */action.yml"
msg_warn "[DRY RUN] Would commit: update action references for release $VERSION"
else
git add -- */action.yml
git commit -m "chore: update action references for release $VERSION
This commit updates all internal action references to point to the current This commit updates all internal action references to point to the current
commit SHA in preparation for release $VERSION." commit SHA in preparation for release $VERSION."
# Update SHA since we just created a new commit # Update SHA since we just created a new commit
current_sha=$(git rev-parse HEAD) current_sha=$(git rev-parse HEAD)
printf '%b' "${GREEN}Committed updated action references${NC}\n" msg_done "Committed updated action references"
printf '%b' "New HEAD: ${GREEN}$current_sha${NC}\n" printf 'New HEAD: %s%s%s\n' "$GREEN" "$current_sha" "$NC"
else fi
printf '%b' "${BLUE}No changes to commit${NC}\n" else
msg_info "No changes to commit"
fi
fi
# Exit early if --prep-only
if [ "$PREP_ONLY" = "true" ]; then
printf '\n'
msg_done "Preparation complete (--prep-only mode)"
msg_warn "Run with --tag-only to create tags"
exit 0
fi fi
# Create/update tags # Create/update tags
printf '%b' "${BLUE}Creating tags...${NC}\n" printf '\n'
msg_info "Creating tags..."
# Create patch tag # Create patch tag
git tag -a "$patch" -m "Release $patch" if [ "$DRY_RUN" = "true" ]; then
printf '%b' " ${GREEN}${NC} Created tag: $patch\n" msg_warn "[DRY RUN] Would create tag: $patch"
else
git tag -a "$patch" -m "Release $patch"
msg_item "Created tag: $patch"
fi
# Move/create minor tag # Move/create minor tag
if git rev-parse "$minor" >/dev/null 2>&1; then if git rev-parse "$minor" >/dev/null 2>&1; then
git tag -f -a "$minor" -m "Latest $minor release: $patch" if [ "$DRY_RUN" = "true" ]; then
printf '%b' " ${GREEN}${NC} Updated tag: $minor (force)\n" msg_warn "[DRY RUN] Would force-update tag: $minor"
else
git tag -f -a "$minor" -m "Latest $minor release: $patch"
msg_item "Updated tag: $minor (force)"
fi
else else
git tag -a "$minor" -m "Latest $minor release: $patch" if [ "$DRY_RUN" = "true" ]; then
printf '%b' " ${GREEN}${NC} Created tag: $minor\n" msg_warn "[DRY RUN] Would create tag: $minor"
else
git tag -a "$minor" -m "Latest $minor release: $patch"
msg_item "Created tag: $minor"
fi
fi fi
# Move/create major tag # Move/create major tag
if git rev-parse "$major" >/dev/null 2>&1; then if git rev-parse "$major" >/dev/null 2>&1; then
git tag -f -a "$major" -m "Latest $major release: $patch" if [ "$DRY_RUN" = "true" ]; then
printf '%b' " ${GREEN}${NC} Updated tag: $major (force)\n" msg_warn "[DRY RUN] Would force-update tag: $major"
else
git tag -f -a "$major" -m "Latest $major release: $patch"
msg_item "Updated tag: $major (force)"
fi
else else
git tag -a "$major" -m "Latest $major release: $patch" if [ "$DRY_RUN" = "true" ]; then
printf '%b' " ${GREEN}${NC} Created tag: $major\n" msg_warn "[DRY RUN] Would create tag: $major"
else
git tag -a "$major" -m "Latest $major release: $patch"
msg_item "Created tag: $major"
fi
fi fi
printf '\n' printf '\n'
printf '%b' "${GREEN}✅ Release $VERSION created successfully${NC}\n" if [ "$DRY_RUN" = "true" ]; then
msg_done "Dry run complete - no changes made"
printf '\n'
msg_info "Would have created release $VERSION"
else
msg_done "Release $VERSION created successfully"
fi
printf '\n' printf '\n'
printf '%b' "${YELLOW}All tags point to: $current_sha${NC}\n" msg_plain "$YELLOW" "All tags point to: $current_sha"
printf '\n' printf '\n'
printf '%b' "${BLUE}Tags created:${NC}\n" msg_info "Tags created:"
printf ' %s\n' "$patch" printf ' %s\n' "$patch"
printf ' %s\n' "$minor" printf ' %s\n' "$minor"
printf ' %s\n' "$major" printf ' %s\n' "$major"
printf '\n'
# Enhanced next steps
if [ "$DRY_RUN" = "false" ]; then
msg_warn "Next steps:"
printf ' 1. Review changes: git show HEAD\n'
printf ' 2. Verify CI status: gh run list --limit 5\n'
printf ' 3. Push tags: git push origin main --tags --force-with-lease\n'
printf ' 4. Update workflow refs: make update-version-refs MAJOR=%s\n' "$major"
printf ' 5. Update README examples if needed\n'
printf ' 6. Create GitHub release: gh release create %s --generate-notes\n' "$VERSION"
printf '\n'
msg_info "If something went wrong:"
printf ' Rollback: make release-undo\n'
else
msg_warn "To execute this release:"
printf ' Run without --dry-run flag\n'
fi

View File

@@ -14,12 +14,12 @@ YELLOW='\033[1;33m'
# shellcheck disable=SC2034 # shellcheck disable=SC2034
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Validate CalVer version format: vYYYY.MM.DD # Validate CalVer version format: vYYYY.MM.DD (zero-padded)
validate_version() { validate_version() {
version="$1" version="$1"
# Check format: vYYYY.MM.DD using grep # Check format: vYYYY.MM.DD (require zero-padding) using grep
if ! echo "$version" | grep -qE '^v[0-9]{4}\.[0-9]{1,2}\.[0-9]{1,2}$'; then if ! echo "$version" | grep -qE '^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}$'; then
return 1 return 1
fi fi
@@ -34,12 +34,12 @@ validate_version() {
return 1 return 1
fi fi
# Validate month (1-12) # Validate month (01-12)
if [ "$month" -lt 1 ] || [ "$month" -gt 12 ]; then if [ "$month" -lt 1 ] || [ "$month" -gt 12 ]; then
return 1 return 1
fi fi
# Validate day (1-31) # Validate day (01-31)
if [ "$day" -lt 1 ] || [ "$day" -gt 31 ]; then if [ "$day" -lt 1 ] || [ "$day" -gt 31 ]; then
return 1 return 1
fi fi
@@ -67,12 +67,12 @@ validate_major_version() {
return 0 return 0
} }
# Validate minor version format: vYYYY.MM # Validate minor version format: vYYYY.MM (zero-padded)
validate_minor_version() { validate_minor_version() {
version="$1" version="$1"
# Check format: vYYYY.MM using grep # Check format: vYYYY.MM (require zero-padding) using grep
if ! echo "$version" | grep -qE '^v[0-9]{4}\.[0-9]{1,2}$'; then if ! echo "$version" | grep -qE '^v[0-9]{4}\.[0-9]{2}$'; then
return 1 return 1
fi fi
@@ -86,7 +86,7 @@ validate_minor_version() {
return 1 return 1
fi fi
# Validate month (1-12) # Validate month (01-12)
if [ "$month" -lt 1 ] || [ "$month" -gt 12 ]; then if [ "$month" -lt 1 ] || [ "$month" -gt 12 ]; then
return 1 return 1
fi fi
@@ -94,6 +94,139 @@ validate_minor_version() {
return 0 return 0
} }
# Check if working directory is clean (no uncommitted changes)
check_git_clean() {
if ! has_git; then
return 1
fi
if ! git diff --quiet || ! git diff --cached --quiet; then
return 1
fi
return 0
}
# Check if currently on specified branch (default: main)
check_on_branch() {
target_branch="${1:-main}"
if ! has_git; then
return 1
fi
current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || return 1
if [ "$current_branch" != "$target_branch" ]; then
return 1
fi
return 0
}
# Check if a git tag exists
check_tag_exists() {
tag="$1"
if ! has_git; then
return 1
fi
if git rev-parse "$tag" >/dev/null 2>&1; then
return 0
fi
return 1
}
# Prompt user for yes/no confirmation
# Usage: if prompt_confirmation "Continue?"; then ...; fi
prompt_confirmation() {
prompt_text="${1:-Continue?}"
timeout_seconds="${2:-30}"
# Check if stdin is a TTY (interactive terminal)
if [ ! -t 0 ]; then
msg_error "Non-interactive session detected - cannot prompt for confirmation"
return 1
fi
# Check if timeout command is available for optional timeout support
if command -v timeout >/dev/null 2>&1; then
printf '%s [y/N] (timeout in %ss) ' "$prompt_text" "$timeout_seconds"
# Create a temporary file to store the response
_temp_response=$(mktemp) || return 1
# Use timeout with --foreground to allow reading from TTY
# Write response to temp file instead of trying to capture in command substitution
if timeout --foreground "$timeout_seconds" sh -c "read -r r && printf '%s' \"\$r\" > '$_temp_response'" 2>/dev/null; then
response=$(cat "$_temp_response")
rm -f "$_temp_response"
else
rm -f "$_temp_response"
printf '\n'
msg_warn "Confirmation timeout - defaulting to No"
return 1
fi
else
# No timeout available - plain read
printf '%s [y/N] ' "$prompt_text"
read -r response || return 1
fi
case "$response" in
[yY]|[yY][eE][sS])
return 0
;;
*)
return 1
;;
esac
}
# Message output functions for consistent, colored output
# These functions provide a clean API for printing status messages
# msg_error "message" - Print error message in red with ✗ symbol to stderr
msg_error() {
printf '%s✗ %s%s\n' "$RED" "$1" "$NC" >&2
}
# msg_success "message" - Print success message in green with ✓ symbol
msg_success() {
printf '%s✓ %s%s\n' "$GREEN" "$1" "$NC"
}
# msg_done "message" - Print completion message in green with ✅ symbol
msg_done() {
printf '%s✅ %s%s\n' "$GREEN" "$1" "$NC"
}
# msg_info "message" - Print info/status message in blue (no symbol)
msg_info() {
printf '%s%s%s\n' "$BLUE" "$1" "$NC"
}
# msg_warn "message" - Print warning message in yellow (no symbol)
msg_warn() {
printf '%s%s%s\n' "$YELLOW" "$1" "$NC"
}
# msg_item "message" - Print indented item with ✓ in green
msg_item() {
printf ' %s✓%s %s\n' "$GREEN" "$NC" "$1"
}
# msg_notice "message" - Print indented notice with in blue
msg_notice() {
printf ' %s%s %s\n' "$BLUE" "$NC" "$1"
}
# msg_plain "color" "message" - Print plain colored message (no symbol)
# Usage: msg_plain "$YELLOW" "=== BANNER ==="
msg_plain() {
color="$1"
message="$2"
printf '%s%s%s\n' "$color" "$message" "$NC"
}
# Get the directory where the calling script is located # Get the directory where the calling script is located
get_script_dir() { get_script_dir() {
cd "$(dirname -- "$1")" && pwd cd "$(dirname -- "$1")" && pwd
@@ -107,7 +240,7 @@ has_git() {
# Require git to be available, exit with error if not # Require git to be available, exit with error if not
require_git() { require_git() {
if ! has_git; then if ! has_git; then
printf '%b' "${RED}Error: git is not installed or not in PATH${NC}\n" >&2 msg_error "git is not installed or not in PATH"
printf 'Please install git to use this script.\n' >&2 printf 'Please install git to use this script.\n' >&2
exit 1 exit 1
fi fi
@@ -117,7 +250,7 @@ require_git() {
safe_mktemp() { safe_mktemp() {
_temp_file="" _temp_file=""
if ! _temp_file=$(mktemp); then if ! _temp_file=$(mktemp); then
printf '%b' "${RED}Error: Failed to create temp file${NC}\n" >&2 msg_error "Failed to create temp file"
exit 1 exit 1
fi fi
printf '%s' "$_temp_file" printf '%s' "$_temp_file"

View File

@@ -112,7 +112,7 @@ runs:
- name: Cache Python Dependencies - name: Cache Python Dependencies
if: steps.check-files.outputs.files_found == 'true' if: steps.check-files.outputs.files_found == 'true'
id: cache-pip id: cache-pip
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'pip' type: 'pip'
paths: '~/.cache/pip' paths: '~/.cache/pip'
@@ -122,7 +122,7 @@ runs:
- name: Install ansible-lint - name: Install ansible-lint
id: install-ansible-lint id: install-ansible-lint
if: steps.check-files.outputs.files_found == 'true' if: steps.check-files.outputs.files_found == 'true'
uses: ivuorinen/actions/common-retry@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-retry@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
command: 'pip install ansible-lint==6.22.1' command: 'pip install ansible-lint==6.22.1'
max-retries: ${{ inputs.max-retries }} max-retries: ${{ inputs.max-retries }}
@@ -162,7 +162,7 @@ runs:
- name: Set Git Config for Fixes - name: Set Git Config for Fixes
id: set-git-config id: set-git-config
if: steps.check-files.outputs.files_found == 'true' if: steps.check-files.outputs.files_found == 'true'
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
@@ -184,6 +184,6 @@ runs:
- name: Upload SARIF Report - name: Upload SARIF Report
if: steps.check-files.outputs.files_found == 'true' if: steps.check-files.outputs.files_found == 'true'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: ansible-lint.sarif sarif_file: ansible-lint.sarif

View File

@@ -44,7 +44,7 @@ runs:
using: composite using: composite
steps: steps:
- name: Validate Inputs (Centralized) - name: Validate Inputs (Centralized)
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: biome-check action-type: biome-check
@@ -112,7 +112,7 @@ runs:
token: ${{ inputs.token }} token: ${{ inputs.token }}
- name: Set Git Config - name: Set Git Config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
@@ -120,11 +120,11 @@ runs:
- name: Node Setup - name: Node Setup
id: node-setup id: node-setup
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Cache Node Dependencies - name: Cache Node Dependencies
id: cache id: cache
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'npm' type: 'npm'
paths: 'node_modules' paths: 'node_modules'
@@ -233,6 +233,6 @@ runs:
- name: Upload Biome Results - name: Upload Biome Results
if: always() if: always()
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: biome-report.sarif sarif_file: biome-report.sarif

View File

@@ -95,7 +95,7 @@ runs:
token: ${{ inputs.token }} token: ${{ inputs.token }}
- name: Set Git Config - name: Set Git Config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
@@ -103,11 +103,11 @@ runs:
- name: Node Setup - name: Node Setup
id: node-setup id: node-setup
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Cache Node Dependencies - name: Cache Node Dependencies
id: cache id: cache
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'npm' type: 'npm'
paths: 'node_modules' paths: 'node_modules'

View File

@@ -112,7 +112,7 @@ runs:
using: composite using: composite
steps: steps:
- name: Validate inputs - name: Validate inputs
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: codeql-analysis action-type: codeql-analysis
language: ${{ inputs.language }} language: ${{ inputs.language }}
@@ -189,7 +189,7 @@ runs:
echo "Using build mode: $build_mode" echo "Using build mode: $build_mode"
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
languages: ${{ inputs.language }} languages: ${{ inputs.language }}
queries: ${{ inputs.queries }} queries: ${{ inputs.queries }}
@@ -202,12 +202,12 @@ runs:
threads: ${{ inputs.threads }} threads: ${{ inputs.threads }}
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/autobuild@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
if: ${{ steps.set-build-mode.outputs.build-mode == 'autobuild' }} if: ${{ steps.set-build-mode.outputs.build-mode == 'autobuild' }}
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
id: analysis id: analysis
uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
category: ${{ steps.set-category.outputs.category }} category: ${{ steps.set-category.outputs.category }}
upload: ${{ inputs.upload-results }} upload: ${{ inputs.upload-results }}

View File

@@ -143,7 +143,7 @@ runs:
fi fi
- name: Set Git Config - name: Set Git Config
id: set-git-config id: set-git-config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}

View File

@@ -50,7 +50,7 @@ runs:
- name: Detect .NET SDK Version - name: Detect .NET SDK Version
id: detect-dotnet-version id: detect-dotnet-version
uses: ivuorinen/actions/dotnet-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/dotnet-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
default-version: "${{ inputs.dotnet-version || '7.0' }}" default-version: "${{ inputs.dotnet-version || '7.0' }}"
@@ -61,7 +61,7 @@ runs:
- name: Cache NuGet packages - name: Cache NuGet packages
id: cache-nuget id: cache-nuget
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'nuget' type: 'nuget'
paths: '~/.nuget/packages' paths: '~/.nuget/packages'
@@ -70,7 +70,7 @@ runs:
- name: Restore Dependencies - name: Restore Dependencies
if: steps.cache-nuget.outputs.cache-hit != 'true' if: steps.cache-nuget.outputs.cache-hit != 'true'
uses: ivuorinen/actions/common-retry@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-retry@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
command: | command: |
echo "Restoring .NET dependencies..." echo "Restoring .NET dependencies..."
@@ -124,7 +124,7 @@ runs:
- name: Upload Test Results - name: Upload Test Results
if: always() if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with: with:
name: csharp-test-results name: csharp-test-results
path: | path: |

View File

@@ -66,7 +66,7 @@ runs:
- name: Detect .NET SDK Version - name: Detect .NET SDK Version
id: detect-dotnet-version id: detect-dotnet-version
uses: ivuorinen/actions/dotnet-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/dotnet-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
default-version: ${{ inputs.dotnet-version || '7.0' }} default-version: ${{ inputs.dotnet-version || '7.0' }}
@@ -111,6 +111,6 @@ runs:
fi fi
- name: Upload SARIF Report - name: Upload SARIF Report
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: dotnet-format.sarif sarif_file: dotnet-format.sarif

View File

@@ -51,7 +51,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: 'csharp-publish' action-type: 'csharp-publish'
token: ${{ inputs.token }} token: ${{ inputs.token }}
@@ -60,7 +60,7 @@ runs:
- name: Detect .NET SDK Version - name: Detect .NET SDK Version
id: detect-dotnet-version id: detect-dotnet-version
uses: ivuorinen/actions/dotnet-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/dotnet-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
default-version: '7.0' default-version: '7.0'
@@ -71,7 +71,7 @@ runs:
- name: Cache NuGet packages - name: Cache NuGet packages
id: cache-nuget id: cache-nuget
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'nuget' type: 'nuget'
paths: '~/.nuget/packages' paths: '~/.nuget/packages'

View File

@@ -147,7 +147,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: 'docker-build' action-type: 'docker-build'
image-name: ${{ inputs.image-name }} image-name: ${{ inputs.image-name }}

View File

@@ -170,7 +170,7 @@ runs:
- name: Build Multi-Arch Docker Image - name: Build Multi-Arch Docker Image
id: build id: build
uses: ivuorinen/actions/docker-build@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/docker-build@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
tag: ${{ steps.tags.outputs.all-tags }} tag: ${{ steps.tags.outputs.all-tags }}
architectures: ${{ inputs.platforms }} architectures: ${{ inputs.platforms }}
@@ -185,7 +185,7 @@ runs:
- name: Publish to Docker Hub - name: Publish to Docker Hub
id: publish-dockerhub id: publish-dockerhub
if: contains(steps.dest.outputs.reg, 'dockerhub') if: contains(steps.dest.outputs.reg, 'dockerhub')
uses: ivuorinen/actions/docker-publish-hub@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/docker-publish-hub@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
tags: ${{ steps.tags.outputs.all-tags }} tags: ${{ steps.tags.outputs.all-tags }}
platforms: ${{ inputs.platforms }} platforms: ${{ inputs.platforms }}
@@ -201,7 +201,7 @@ runs:
- name: Publish to GitHub Packages - name: Publish to GitHub Packages
id: publish-github id: publish-github
if: contains(steps.dest.outputs.reg, 'github') if: contains(steps.dest.outputs.reg, 'github')
uses: ivuorinen/actions/docker-publish-gh@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/docker-publish-gh@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
tags: ${{ steps.tags.outputs.all-tags }} tags: ${{ steps.tags.outputs.all-tags }}
platforms: ${{ inputs.platforms }} platforms: ${{ inputs.platforms }}

View File

@@ -58,7 +58,7 @@ runs:
- name: Parse .NET Version - name: Parse .NET Version
id: parse-version id: parse-version
uses: ivuorinen/actions/version-file-parser@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/version-file-parser@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
language: 'dotnet' language: 'dotnet'
tool-versions-key: 'dotnet' tool-versions-key: 'dotnet'

View File

@@ -176,11 +176,11 @@ runs:
- name: Setup Node.js - name: Setup Node.js
id: node-setup id: node-setup
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Cache Node Dependencies - name: Cache Node Dependencies
id: cache id: cache
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'npm' type: 'npm'
paths: 'node_modules' paths: 'node_modules'
@@ -414,7 +414,7 @@ runs:
- name: Upload ESLint Results - name: Upload ESLint Results
if: always() && inputs.report-format == 'sarif' if: always() && inputs.report-format == 'sarif'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: ${{ inputs.working-directory }}/reports/eslint.sarif sarif_file: ${{ inputs.working-directory }}/reports/eslint.sarif
category: eslint category: eslint

View File

@@ -44,7 +44,7 @@ runs:
steps: steps:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: 'eslint-fix' action-type: 'eslint-fix'
token: ${{ inputs.token }} token: ${{ inputs.token }}
@@ -58,7 +58,7 @@ runs:
token: ${{ inputs.token }} token: ${{ inputs.token }}
- name: Set Git Config - name: Set Git Config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
@@ -66,11 +66,11 @@ runs:
- name: Node Setup - name: Node Setup
id: node-setup id: node-setup
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Cache Node Dependencies - name: Cache Node Dependencies
id: cache id: cache
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'npm' type: 'npm'
paths: 'node_modules' paths: 'node_modules'

View File

@@ -17,6 +17,7 @@ const CATEGORIES = {
'dotnet-version-detect': 'Setup', 'dotnet-version-detect': 'Setup',
// Utilities // Utilities
'action-versioning': 'Utilities',
'version-file-parser': 'Utilities', 'version-file-parser': 'Utilities',
'version-validator': 'Utilities', 'version-validator': 'Utilities',
@@ -236,6 +237,14 @@ function generateQuickReference(actions) {
return markdownTable(rows, { align: ['c', 'l', 'l', 'l', 'l'] }); return markdownTable(rows, { align: ['c', 'l', 'l', 'l', 'l'] });
} }
/**
* Generate per-category Markdown sections containing tables of actions and their brief details.
*
* Sections appear in a fixed priority order: Setup, Utilities, Linting, Testing, Build, Publishing, Repository, Validation.
*
* @param {Array<Object>} actions - Array of action metadata objects. Each object should include at least: `name`, `description`, `category`, `icon`, `languages` (array), and `features` (array).
* @returns {string} A Markdown string with one section per category (when present), each containing a table of actions with columns: Action, Description, Languages, and Features.
*/
function generateCategoryTables(actions) { function generateCategoryTables(actions) {
const categories = {}; const categories = {};
@@ -257,8 +266,9 @@ function generateCategoryTables(actions) {
const categoryActions = categories[category]; const categoryActions = categories[category];
const icon = CATEGORY_ICONS[category] || '📦'; const icon = CATEGORY_ICONS[category] || '📦';
const actionWord = categoryActions.length === 1 ? 'action' : 'actions';
output += `\n#### ${icon} ${category} (${categoryActions.length} actions)\n\n`; output += `\n#### ${icon} ${category} (${categoryActions.length} ${actionWord})\n\n`;
const rows = [['Action', 'Description', 'Languages', 'Features']]; const rows = [['Action', 'Description', 'Languages', 'Features']];
@@ -319,6 +329,15 @@ function generateReferenceLinks(actions) {
return `\n<!-- Reference Links -->\n${links}\n`; return `\n<!-- Reference Links -->\n${links}\n`;
} }
/**
* Builds the complete Markdown catalog for all discovered actions in the repository.
*
* The generated content includes a quick reference, per-category tables, a feature matrix,
* language support matrix, usage examples with recommended pinned refs, action reference links,
* and a closing separator.
*
* @returns {string} The assembled catalog as a Markdown-formatted string.
*/
function generateCatalogContent() { function generateCatalogContent() {
const actions = getAllActions(); const actions = getAllActions();
const totalCount = actions.length; const totalCount = actions.length;
@@ -341,10 +360,17 @@ function generateCatalogContent() {
content += `\n\n### Action Usage\n\n`; content += `\n\n### Action Usage\n\n`;
content += 'All actions can be used independently in your workflows:\n\n'; content += 'All actions can be used independently in your workflows:\n\n';
content += '```yaml\n'; content += '```yaml\n';
content += '- uses: ivuorinen/actions/action-name@main\n'; content += '# Recommended: Use pinned refs for supply-chain security\n';
content += '- uses: ivuorinen/actions/action-name@vYYYY-MM-DD # Date-based tag (example)\n';
content += ' with:\n'; content += ' with:\n';
content += ' # action-specific inputs\n'; content += ' # action-specific inputs\n';
content += '```\n'; content += '\n';
content += '# Alternative: Use commit SHA for immutability\n';
content += '- uses: ivuorinen/actions/action-name@abc123def456 # Full commit SHA\n';
content += ' with:\n';
content += ' # action-specific inputs\n';
content += '```\n\n';
content += '> **Security Note**: Always pin to specific tags or commit SHAs instead of `@main` to ensure reproducible workflows and supply-chain integrity.\n';
// Add reference links before the timestamp // Add reference links before the timestamp
content += generateReferenceLinks(actions); content += generateReferenceLinks(actions);

View File

@@ -54,7 +54,7 @@ runs:
- name: Detect Go Version - name: Detect Go Version
id: detect-go-version id: detect-go-version
uses: ivuorinen/actions/go-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/go-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
default-version: "${{ inputs.go-version || '1.21' }}" default-version: "${{ inputs.go-version || '1.21' }}"
@@ -66,7 +66,7 @@ runs:
- name: Cache Go Dependencies - name: Cache Go Dependencies
id: cache-go id: cache-go
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'go' type: 'go'
paths: '~/go/pkg/mod' paths: '~/go/pkg/mod'
@@ -75,7 +75,7 @@ runs:
- name: Download Dependencies - name: Download Dependencies
if: steps.cache-go.outputs.cache-hit != 'true' if: steps.cache-go.outputs.cache-hit != 'true'
uses: ivuorinen/actions/common-retry@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-retry@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
command: | command: |
echo "Downloading Go dependencies..." echo "Downloading Go dependencies..."
@@ -163,7 +163,7 @@ runs:
- name: Upload Build Artifacts - name: Upload Build Artifacts
if: always() if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with: with:
name: go-build-artifacts name: go-build-artifacts
path: | path: |

View File

@@ -218,7 +218,7 @@ runs:
- name: Set up Cache - name: Set up Cache
id: cache id: cache
if: inputs.cache == 'true' if: inputs.cache == 'true'
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'go' type: 'go'
paths: '~/.cache/golangci-lint,~/.cache/go-build' paths: '~/.cache/golangci-lint,~/.cache/go-build'
@@ -413,7 +413,7 @@ runs:
- name: Upload Lint Results - name: Upload Lint Results
if: always() && inputs.report-format == 'sarif' if: always() && inputs.report-format == 'sarif'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: ${{ inputs.working-directory }}/reports/golangci-lint.sarif sarif_file: ${{ inputs.working-directory }}/reports/golangci-lint.sarif
category: golangci-lint category: golangci-lint

View File

@@ -65,7 +65,7 @@ runs:
- name: Parse Go Version - name: Parse Go Version
id: parse-version id: parse-version
uses: ivuorinen/actions/version-file-parser@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/version-file-parser@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
language: 'go' language: 'go'
tool-versions-key: 'golang' tool-versions-key: 'golang'

View File

@@ -176,7 +176,7 @@ runs:
- name: Parse Node.js Version - name: Parse Node.js Version
id: version id: version
uses: ivuorinen/actions/version-file-parser@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/version-file-parser@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
language: 'node' language: 'node'
tool-versions-key: 'nodejs' tool-versions-key: 'nodejs'
@@ -275,7 +275,8 @@ runs:
with: with:
node-version: ${{ steps.version.outputs.detected-version }} node-version: ${{ steps.version.outputs.detected-version }}
registry-url: ${{ inputs.registry-url }} registry-url: ${{ inputs.registry-url }}
cache: false # Note: cache parameter removed for actions/setup-node@v6 compatibility
# Caching is handled separately via common-cache action (step: Cache Dependencies)
- name: Enable Corepack - name: Enable Corepack
id: corepack id: corepack
@@ -299,7 +300,7 @@ runs:
- name: Cache Dependencies - name: Cache Dependencies
if: inputs.cache == 'true' if: inputs.cache == 'true'
id: deps-cache id: deps-cache
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'npm' type: 'npm'
paths: '~/.npm,~/.yarn/cache,~/.pnpm-store,~/.bun/install/cache,node_modules' paths: '~/.npm,~/.yarn/cache,~/.pnpm-store,~/.bun/install/cache,node_modules'
@@ -359,7 +360,7 @@ runs:
- name: Install Dependencies - name: Install Dependencies
if: inputs.install == 'true' && steps.deps-cache.outputs.cache-hit != 'true' if: inputs.install == 'true' && steps.deps-cache.outputs.cache-hit != 'true'
uses: ivuorinen/actions/common-retry@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-retry@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
command: | command: |
package_manager="$PACKAGE_MANAGER" package_manager="$PACKAGE_MANAGER"

View File

@@ -101,7 +101,7 @@ runs:
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
- name: Setup Node.js - name: Setup Node.js
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Authenticate NPM - name: Authenticate NPM
shell: sh shell: sh

1
package-lock.json generated
View File

@@ -1079,6 +1079,7 @@
"integrity": "sha512-/4Osri9QFGCZOCTkfA8qJF+XGjKYERSHkXzxSyS1hd3ZERJGjvsUao2h4wdnvpHp6Tu2Jh/bPHM0FE9JJza6ng==", "integrity": "sha512-/4Osri9QFGCZOCTkfA8qJF+XGjKYERSHkXzxSyS1hd3ZERJGjvsUao2h4wdnvpHp6Tu2Jh/bPHM0FE9JJza6ng==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"globby": "14.1.0", "globby": "14.1.0",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",

View File

@@ -79,7 +79,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: php-composer action-type: php-composer
@@ -176,7 +176,7 @@ runs:
- name: Cache Composer packages - name: Cache Composer packages
id: composer-cache id: composer-cache
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'composer' type: 'composer'
paths: vendor,~/.composer/cache${{ inputs.cache-directories != "" && format(",{0}", inputs.cache-directories) || "" }} paths: vendor,~/.composer/cache${{ inputs.cache-directories != "" && format(",{0}", inputs.cache-directories) || "" }}
@@ -196,7 +196,7 @@ runs:
composer clear-cache composer clear-cache
- name: Install Dependencies - name: Install Dependencies
uses: ivuorinen/actions/common-retry@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-retry@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
command: composer install ${{ inputs.args }} command: composer install ${{ inputs.args }}
max-retries: ${{ inputs.max-retries }} max-retries: ${{ inputs.max-retries }}

View File

@@ -60,7 +60,7 @@ runs:
- name: Detect PHP Version - name: Detect PHP Version
id: php-version id: php-version
uses: ivuorinen/actions/php-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/php-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
default-version: ${{ inputs.php-version }} default-version: ${{ inputs.php-version }}

View File

@@ -86,14 +86,14 @@ runs:
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
- name: Set Git Config - name: Set Git Config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token != '' && inputs.token || github.token }} token: ${{ inputs.token != '' && inputs.token || github.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
email: ${{ inputs.email }} email: ${{ inputs.email }}
- name: Composer Install - name: Composer Install
uses: ivuorinen/actions/php-composer@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/php-composer@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Run PHPUnit Tests - name: Run PHPUnit Tests
id: test id: test

View File

@@ -67,7 +67,7 @@ runs:
- name: Parse PHP Version - name: Parse PHP Version
id: parse-version id: parse-version
uses: ivuorinen/actions/version-file-parser@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/version-file-parser@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
language: 'php' language: 'php'
tool-versions-key: 'php' tool-versions-key: 'php'

View File

@@ -40,7 +40,7 @@ runs:
steps: steps:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: pr-lint action-type: pr-lint
token: ${{ inputs.token }} token: ${{ inputs.token }}
@@ -64,9 +64,9 @@ runs:
# ╰──────────────────────────────────────────────────────────╯ # ╰──────────────────────────────────────────────────────────╯
- name: Setup Git Config - name: Setup Git Config
id: git-config id: git-config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token || github.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
email: ${{ inputs.email }} email: ${{ inputs.email }}
@@ -87,7 +87,7 @@ runs:
- name: Setup Node.js environment - name: Setup Node.js environment
if: steps.detect-node.outputs.found == 'true' if: steps.detect-node.outputs.found == 'true'
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
install: true install: true
cache: true cache: true
@@ -106,7 +106,7 @@ runs:
- name: Detect PHP Version - name: Detect PHP Version
if: steps.detect-php.outputs.found == 'true' if: steps.detect-php.outputs.found == 'true'
id: php-version id: php-version
uses: ivuorinen/actions/php-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/php-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Setup PHP - name: Setup PHP
if: steps.detect-php.outputs.found == 'true' if: steps.detect-php.outputs.found == 'true'
@@ -150,7 +150,7 @@ runs:
- name: Detect Python Version - name: Detect Python Version
if: steps.detect-python.outputs.found == 'true' if: steps.detect-python.outputs.found == 'true'
id: python-version id: python-version
uses: ivuorinen/actions/python-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/python-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Setup Python - name: Setup Python
if: steps.detect-python.outputs.found == 'true' if: steps.detect-python.outputs.found == 'true'
@@ -181,7 +181,7 @@ runs:
- name: Detect Go Version - name: Detect Go Version
if: steps.detect-go.outputs.found == 'true' if: steps.detect-go.outputs.found == 'true'
id: go-version id: go-version
uses: ivuorinen/actions/go-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/go-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Setup Go - name: Setup Go
if: steps.detect-go.outputs.found == 'true' if: steps.detect-go.outputs.found == 'true'
@@ -252,7 +252,7 @@ runs:
# Upload MegaLinter artifacts # Upload MegaLinter artifacts
- name: Archive production artifacts - name: Archive production artifacts
if: success() || failure() if: success() || failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with: with:
name: MegaLinter reports name: MegaLinter reports
include-hidden-files: 'true' include-hidden-files: 'true'
@@ -264,7 +264,12 @@ runs:
- name: Set APPLY_FIXES_IF var - name: Set APPLY_FIXES_IF var
shell: bash shell: bash
env: env:
APPLY_FIXES_CONDITION: ${{ steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) }} APPLY_FIXES_CONDITION: >-
${{
steps.ml.outputs.has_updated_sources == 1 &&
(env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) &&
(github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
}}
run: | run: |
set -euo pipefail set -euo pipefail

View File

@@ -49,7 +49,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: 'pre-commit' action-type: 'pre-commit'
token: ${{ inputs.token }} token: ${{ inputs.token }}
@@ -58,7 +58,7 @@ runs:
email: ${{ inputs.commit_email }} email: ${{ inputs.commit_email }}
username: ${{ inputs.commit_user }} username: ${{ inputs.commit_user }}
- name: Set Git Config - name: Set Git Config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.commit_user }} username: ${{ inputs.commit_user }}

View File

@@ -202,11 +202,11 @@ runs:
- name: Setup Node.js - name: Setup Node.js
id: node-setup id: node-setup
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Set up Cache - name: Set up Cache
id: cache id: cache
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
if: inputs.cache == 'true' if: inputs.cache == 'true'
with: with:
type: 'npm' type: 'npm'
@@ -432,7 +432,7 @@ runs:
- name: Upload Prettier Results - name: Upload Prettier Results
if: always() && inputs.report-format == 'sarif' if: always() && inputs.report-format == 'sarif'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: ${{ inputs.working-directory }}/reports/prettier.sarif sarif_file: ${{ inputs.working-directory }}/reports/prettier.sarif
category: prettier category: prettier

View File

@@ -91,7 +91,7 @@ runs:
token: ${{ inputs.token }} token: ${{ inputs.token }}
- name: Set Git Config - name: Set Git Config
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
@@ -99,11 +99,11 @@ runs:
- name: Node Setup - name: Node Setup
id: node-setup id: node-setup
uses: ivuorinen/actions/node-setup@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/node-setup@0fa9a68f07a1260b321f814202658a6089a43d42
- name: Cache npm Dependencies - name: Cache npm Dependencies
id: cache-npm id: cache-npm
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'npm' type: 'npm'
paths: 'node_modules' paths: 'node_modules'

View File

@@ -155,7 +155,7 @@ runs:
- name: Detect Python Version - name: Detect Python Version
id: python-version id: python-version
uses: ivuorinen/actions/python-version-detect@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/python-version-detect@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
default-version: ${{ inputs.python-version }} default-version: ${{ inputs.python-version }}
@@ -189,7 +189,7 @@ runs:
- name: Cache Python Dependencies - name: Cache Python Dependencies
if: steps.check-files.outputs.result == 'found' if: steps.check-files.outputs.result == 'found'
id: cache-pip id: cache-pip
uses: ivuorinen/actions/common-cache@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/common-cache@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
type: 'pip' type: 'pip'
paths: '~/.cache/pip' paths: '~/.cache/pip'
@@ -325,7 +325,7 @@ runs:
- name: Set Git Config for Fixes - name: Set Git Config for Fixes
if: ${{ fromJSON(steps.fix.outputs.fixed_count) > 0 }} if: ${{ fromJSON(steps.fix.outputs.fixed_count) > 0 }}
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token }} token: ${{ inputs.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
@@ -370,7 +370,7 @@ runs:
- name: Upload SARIF Report - name: Upload SARIF Report
if: steps.check-files.outputs.result == 'found' if: steps.check-files.outputs.result == 'found'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: ${{ inputs.working-directory }}/reports/flake8.sarif sarif_file: ${{ inputs.working-directory }}/reports/flake8.sarif
category: 'python-lint' category: 'python-lint'

View File

@@ -72,7 +72,7 @@ runs:
- name: Parse Python Version - name: Parse Python Version
id: parse-version id: parse-version
uses: ivuorinen/actions/version-file-parser@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/version-file-parser@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
language: 'python' language: 'python'
tool-versions-key: 'python' tool-versions-key: 'python'

View File

@@ -65,7 +65,7 @@ runs:
- name: Parse Python Version - name: Parse Python Version
id: parse-version id: parse-version
uses: ivuorinen/actions/version-file-parser@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/version-file-parser@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
language: 'python' language: 'python'
tool-versions-key: 'python' tool-versions-key: 'python'

View File

@@ -88,16 +88,6 @@ runs:
GIT_USERNAME="$VALIDATED_GIT_USERNAME" GIT_USERNAME="$VALIDATED_GIT_USERNAME"
GIT_EMAIL="$VALIDATED_GIT_EMAIL" GIT_EMAIL="$VALIDATED_GIT_EMAIL"
# Function to clean up Git config
cleanup_git_config() {
git config --local --unset-all "url.https://x-access-token:${TOKEN}@github.com/.insteadof" || true
git config --local --unset-all "user.name" || true
git config --local --unset-all "user.email" || true
}
# Set up trap to ensure cleanup on exit
trap cleanup_git_config EXIT
# Store token in variable to avoid repeated exposure # Store token in variable to avoid repeated exposure
TOKEN="$GITHUB_TOKEN" TOKEN="$GITHUB_TOKEN"

View File

@@ -43,7 +43,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: 'stale' action-type: 'stale'
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}

View File

@@ -78,7 +78,7 @@ runs:
- name: Validate Inputs - name: Validate Inputs
id: validate id: validate
uses: ivuorinen/actions/validate-inputs@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/validate-inputs@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
action-type: 'terraform-lint-fix' action-type: 'terraform-lint-fix'
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
@@ -270,7 +270,7 @@ runs:
- name: Set Git Config for Fixes - name: Set Git Config for Fixes
if: ${{ fromJSON(steps.fix.outputs.fixed_count) > 0 }} if: ${{ fromJSON(steps.fix.outputs.fixed_count) > 0 }}
uses: ivuorinen/actions/set-git-config@7061aafd35a2f21b57653e34f2b634b2a19334a9 uses: ivuorinen/actions/set-git-config@0fa9a68f07a1260b321f814202658a6089a43d42
with: with:
token: ${{ inputs.token || github.token }} token: ${{ inputs.token || github.token }}
username: ${{ inputs.username }} username: ${{ inputs.username }}
@@ -302,7 +302,7 @@ runs:
- name: Upload SARIF Report - name: Upload SARIF Report
if: steps.check-files.outputs.found == 'true' && inputs.format == 'sarif' if: steps.check-files.outputs.found == 'true' && inputs.format == 'sarif'
uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # v4.30.9 uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
with: with:
sarif_file: ${{ env.VALIDATED_WORKING_DIR }}/reports/tflint.sarif sarif_file: ${{ env.VALIDATED_WORKING_DIR }}/reports/tflint.sarif
category: terraform-lint category: terraform-lint

View File

@@ -48,9 +48,47 @@ class TestConventionsValidator:
rules = validator._rules rules = validator._rules
assert rules["action_type"] == "nonexistent-action" assert rules["action_type"] == "nonexistent-action"
assert rules["required_inputs"] == [] assert rules["required_inputs"] == []
assert isinstance(rules["optional_inputs"], dict) assert isinstance(rules["optional_inputs"], list)
assert isinstance(rules["conventions"], dict) assert isinstance(rules["conventions"], dict)
def test_load_rules_with_dict_optional_inputs(self, tmp_path):
"""Test backward compatibility with dict format for optional_inputs."""
# Create a rules file with legacy dict format for optional_inputs
rules_file = tmp_path / "legacy_rules.yml"
rules_file.write_text("""
action_type: legacy-action
required_inputs: []
optional_inputs:
foo: int
bar: str
baz:
type: boolean
validator: boolean
conventions: {}
overrides: {}
""")
# Load rules and verify conventions are built from dict keys
validator = ConventionBasedValidator("legacy-action")
rules = validator.load_rules(rules_file)
# Verify optional_inputs is preserved as-is from YAML
assert "optional_inputs" in rules
assert isinstance(rules["optional_inputs"], dict)
# Verify conventions were auto-generated from optional_inputs dict keys
assert "conventions" in rules
assert isinstance(rules["conventions"], dict)
conventions_keys = set(rules["conventions"].keys())
optional_keys = set(rules["optional_inputs"].keys())
assert conventions_keys == optional_keys, (
f"Conventions keys {conventions_keys} should match optional_inputs keys {optional_keys}"
)
# Verify each key from the dict is in conventions
assert "foo" in rules["conventions"]
assert "bar" in rules["conventions"]
assert "baz" in rules["conventions"]
def test_load_rules_with_custom_path(self, tmp_path): def test_load_rules_with_custom_path(self, tmp_path):
"""Test loading rules from custom path.""" """Test loading rules from custom path."""
rules_file = tmp_path / "custom_rules.yml" rules_file = tmp_path / "custom_rules.yml"

View File

@@ -82,7 +82,7 @@ class ConventionBasedValidator(BaseValidator):
return { return {
"action_type": self.action_type, "action_type": self.action_type,
"required_inputs": [], "required_inputs": [],
"optional_inputs": {}, "optional_inputs": [],
"conventions": {}, "conventions": {},
"overrides": {}, "overrides": {},
} }
@@ -93,16 +93,27 @@ class ConventionBasedValidator(BaseValidator):
# Ensure all expected keys exist # Ensure all expected keys exist
rules.setdefault("required_inputs", []) rules.setdefault("required_inputs", [])
rules.setdefault("optional_inputs", {}) rules.setdefault("optional_inputs", [])
rules.setdefault("conventions", {}) rules.setdefault("conventions", {})
rules.setdefault("overrides", {}) rules.setdefault("overrides", {})
# Build conventions from optional_inputs if not explicitly set # Build conventions from optional_inputs if not explicitly set
if not rules["conventions"] and rules["optional_inputs"]: if not rules["conventions"] and rules["optional_inputs"]:
conventions = {} conventions = {}
for input_name, input_config in rules["optional_inputs"].items(): optional_inputs = rules["optional_inputs"]
# Try to infer validator type from the input name or pattern
conventions[input_name] = self._infer_validator_type(input_name, input_config) # Handle both list and dict formats for optional_inputs
if isinstance(optional_inputs, list):
# List format: just input names
for input_name in optional_inputs:
conventions[input_name] = self._infer_validator_type(input_name, {})
elif isinstance(optional_inputs, dict):
# Dict format: input names with config
for input_name, input_config in optional_inputs.items():
conventions[input_name] = self._infer_validator_type(
input_name, input_config
)
rules["conventions"] = conventions rules["conventions"] = conventions
return rules return rules
@@ -110,7 +121,7 @@ class ConventionBasedValidator(BaseValidator):
return { return {
"action_type": self.action_type, "action_type": self.action_type,
"required_inputs": [], "required_inputs": [],
"optional_inputs": {}, "optional_inputs": [],
"conventions": {}, "conventions": {},
"overrides": {}, "overrides": {},
} }
@@ -285,7 +296,7 @@ class ConventionBasedValidator(BaseValidator):
# Get conventions and overrides from rules # Get conventions and overrides from rules
conventions = self._rules.get("conventions", {}) conventions = self._rules.get("conventions", {})
overrides = self._rules.get("overrides", {}) overrides = self._rules.get("overrides", {})
optional_inputs = self._rules.get("optional_inputs", {}) optional_inputs = self._rules.get("optional_inputs", [])
required_inputs = self.get_required_inputs() required_inputs = self.get_required_inputs()
# Validate each input # Validate each input