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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/actions/bash-script/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: 'File Processor'
description: 'Bash action with separate script file to process files'
author: 'Suspect Software'

inputs:
path:
description: 'Path to search for files'
required: false
default: './'
pattern:
description: 'File pattern to match (e.g., *.md, *.js)'
required: false
default: '*.md'
operation:
description: 'Operation to perform (count/list/size)'
required: false
default: 'count'

outputs:
count:
description: 'Number of files found (for count operation)'
files:
description: 'List of files found (for list operation)'
total-size:
description: 'Total size in bytes (for size operation)'

runs:
using: 'composite'
steps:
- name: Execute file processor script
shell: bash
env:
INPUT_PATH: ${{ inputs.path }}
INPUT_PATTERN: ${{ inputs.pattern }}
INPUT_OPERATION: ${{ inputs.operation }}
run: |
chmod +x "${{ github.action_path }}/script.sh"
"${{ github.action_path }}/script.sh"
82 changes: 82 additions & 0 deletions .github/actions/bash-script/script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash
set -e

# Script-based bash action
# This script demonstrates a more complex bash action with a separate script file

echo "=== File Processor Action ==="

# Read inputs from environment variables
INPUT_PATH="${INPUT_PATH:-./}"
INPUT_PATTERN="${INPUT_PATTERN:-*.md}"
INPUT_OPERATION="${INPUT_OPERATION:-count}"

echo "Configuration:"
echo " Path: $INPUT_PATH"
echo " Pattern: $INPUT_PATTERN"
echo " Operation: $INPUT_OPERATION"
echo ""

# Validate inputs
if [ ! -d "$INPUT_PATH" ] && [ ! -f "$INPUT_PATH" ]; then
echo "Error: Path does not exist: $INPUT_PATH"
exit 1
fi

# Perform operation
case "$INPUT_OPERATION" in
count)
echo "Counting files matching pattern..."
COUNT=$(find "$INPUT_PATH" -name "$INPUT_PATTERN" -type f 2>/dev/null | wc -l)
echo "Found $COUNT files"
echo "count=$COUNT" >> $GITHUB_OUTPUT
;;

list)
echo "Listing files matching pattern..."
FILES=$(find "$INPUT_PATH" -name "$INPUT_PATTERN" -type f 2>/dev/null)
if [ -n "$FILES" ]; then
echo "$FILES"
# Save to multiline output
{
echo 'files<<EOF'
echo "$FILES"
echo 'EOF'
} >> $GITHUB_OUTPUT
else
echo "No files found"
echo "files=" >> $GITHUB_OUTPUT
fi
;;

size)
echo "Calculating total size of files matching pattern..."
TOTAL_SIZE=0
while IFS= read -r file; do
if [ -f "$file" ]; then
SIZE=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
TOTAL_SIZE=$((TOTAL_SIZE + SIZE))
fi
done < <(find "$INPUT_PATH" -name "$INPUT_PATTERN" -type f 2>/dev/null)

echo "Total size: $TOTAL_SIZE bytes"
echo "total-size=$TOTAL_SIZE" >> $GITHUB_OUTPUT
;;

*)
echo "Error: Unknown operation: $INPUT_OPERATION"
echo "Supported operations: count, list, size"
exit 1
;;
esac

echo ""
echo "Operation completed successfully!"

# Create step summary
{
echo "### File Processor Results"
echo "- Operation: $INPUT_OPERATION"
echo "- Pattern: $INPUT_PATTERN"
echo "- Path: $INPUT_PATH"
} >> $GITHUB_STEP_SUMMARY
52 changes: 52 additions & 0 deletions .github/actions/bash-simple/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: 'Simple Bash Action'
description: 'A simple bash-based action that processes input and produces output'
author: 'Suspect Software'

inputs:
name:
description: 'Name to greet'
required: true
greeting:
description: 'Greeting to use'
required: false
default: 'Hello'
format:
description: 'Output format (text/json)'
required: false
default: 'text'

outputs:
message:
description: 'The greeting message'
time:
description: 'Time when the greeting was generated'

runs:
using: 'composite'
steps:
- name: Generate greeting
shell: bash
run: |
# Get current time
CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Generate message
MESSAGE="${{ inputs.greeting }}, ${{ inputs.name }}!"

# Format output based on input
if [ "${{ inputs.format }}" == "json" ]; then
echo "Output in JSON format:"
echo "{\"message\": \"$MESSAGE\", \"time\": \"$CURRENT_TIME\"}"
else
echo "Output in text format:"
echo "$MESSAGE"
fi

# Set outputs
echo "message=$MESSAGE" >> $GITHUB_OUTPUT
echo "time=$CURRENT_TIME" >> $GITHUB_OUTPUT

# Add to step summary
echo "### Greeting Generated" >> $GITHUB_STEP_SUMMARY
echo "- Message: $MESSAGE" >> $GITHUB_STEP_SUMMARY
echo "- Time: $CURRENT_TIME" >> $GITHUB_STEP_SUMMARY
72 changes: 72 additions & 0 deletions .github/actions/composite-build-test/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: 'Build and Test'
description: 'Composite action to build and test a project'
author: 'Suspect Software'

inputs:
build-command:
description: 'Command to build the project'
required: false
default: 'npm run build'
test-command:
description: 'Command to run tests'
required: false
default: 'npm test'
skip-tests:
description: 'Skip running tests'
required: false
default: 'false'
upload-coverage:
description: 'Upload test coverage report'
required: false
default: 'false'

outputs:
build-status:
description: 'Status of the build step'
value: ${{ steps.build.outcome }}
test-status:
description: 'Status of the test step'
value: ${{ steps.test.outcome }}

runs:
using: 'composite'
steps:
- name: Run linter
shell: bash
run: |
echo "Running linter..."
if [ -f "package.json" ] && grep -q '"lint"' package.json; then
npm run lint || echo "Linting completed with warnings"
else
echo "No linter configured, skipping..."
fi

- name: Build project
id: build
shell: bash
run: |
echo "Building project with command: ${{ inputs.build-command }}"
${{ inputs.build-command }}

- name: Run tests
id: test
if: inputs.skip-tests != 'true'
shell: bash
run: |
echo "Running tests with command: ${{ inputs.test-command }}"
${{ inputs.test-command }}

- name: Upload coverage
if: inputs.upload-coverage == 'true' && steps.test.outcome == 'success'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 30

- name: Build summary
shell: bash
run: |
echo "### Build and Test Summary" >> $GITHUB_STEP_SUMMARY
echo "- Build Status: ${{ steps.build.outcome }}" >> $GITHUB_STEP_SUMMARY
echo "- Test Status: ${{ steps.test.outcome }}" >> $GITHUB_STEP_SUMMARY
54 changes: 54 additions & 0 deletions .github/actions/composite-setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: 'Setup Environment'
description: 'Composite action to setup development environment with Node.js and dependencies'
author: 'Suspect Software'

inputs:
node-version:
description: 'Node.js version to install'
required: false
default: '18'
cache-dependency-path:
description: 'Path to package-lock.json or yarn.lock for caching'
required: false
default: 'package-lock.json'
install-dependencies:
description: 'Whether to install dependencies'
required: false
default: 'true'

outputs:
node-version:
description: 'The Node.js version that was installed'
value: ${{ steps.setup-node.outputs.node-version }}
cache-hit:
description: 'Whether dependencies were restored from cache'
value: ${{ steps.setup-node.outputs.cache-hit }}

runs:
using: 'composite'
steps:
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
cache-dependency-path: ${{ inputs.cache-dependency-path }}

- name: Install dependencies
if: inputs.install-dependencies == 'true'
shell: bash
run: |
if [ -f "package.json" ]; then
echo "Installing dependencies..."
npm ci
else
echo "No package.json found, skipping dependency installation"
fi

- name: Print environment info
shell: bash
run: |
echo "Node.js version: $(node --version)"
echo "NPM version: $(npm --version)"
echo "Working directory: $(pwd)"
92 changes: 92 additions & 0 deletions .github/workflows/demo-bash-actions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Demo - Using Bash Actions

on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday

permissions:
contents: read

jobs:
simple-bash-action:
runs-on: ubuntu-latest
name: Simple Bash Action Demo

steps:
- name: Checkout code
uses: actions/checkout@v4

# Use simple bash action with default greeting
- name: Greet with default
id: greet1
uses: ./.github/actions/bash-simple
with:
name: 'World'

- name: Display greeting output
run: |
echo "Message: ${{ steps.greet1.outputs.message }}"
echo "Time: ${{ steps.greet1.outputs.time }}"

# Use simple bash action with custom greeting
- name: Greet with custom message
id: greet2
uses: ./.github/actions/bash-simple
with:
name: 'GitHub Actions'
greeting: 'Welcome'
format: 'json'

- name: Display custom greeting
run: |
echo "Message: ${{ steps.greet2.outputs.message }}"
echo "Time: ${{ steps.greet2.outputs.time }}"

script-bash-action:
runs-on: ubuntu-latest
name: Script-based Bash Action Demo

steps:
- name: Checkout code
uses: actions/checkout@v4

# Count markdown files
- name: Count markdown files
id: count
uses: ./.github/actions/bash-script
with:
path: './'
pattern: '*.md'
operation: 'count'

- name: Display count
run: |
echo "Found ${{ steps.count.outputs.count }} markdown files"

# List YAML files
- name: List workflow files
id: list
uses: ./.github/actions/bash-script
with:
path: '.github/workflows'
pattern: '*.yml'
operation: 'list'

- name: Display files
run: |
echo "Workflow files found:"
echo "${{ steps.list.outputs.files }}"

# Calculate size of action files
- name: Calculate action files size
id: size
uses: ./.github/actions/bash-script
with:
path: '.github/actions'
pattern: '*.yml'
operation: 'size'

- name: Display size
run: |
echo "Total size: ${{ steps.size.outputs.total-size }} bytes"
Loading
Loading