Add CI workflows for testing and version checks, enhance README and T… #3
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test SSH Key Sync | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| paths: | |
| - 'sync-ssh-keys.sh' | |
| - 'users.conf' | |
| - '.github/workflows/test.yml' | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'sync-ssh-keys.sh' | |
| - 'users.conf' | |
| - '.github/workflows/test.yml' | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Make script executable | |
| run: chmod +x sync-ssh-keys.sh | |
| - name: Create test users | |
| run: | | |
| sudo useradd -m testuser1 || true | |
| sudo useradd -m testuser2 || true | |
| sudo useradd -m testuser3 || true | |
| - name: Setup test environment | |
| run: | | |
| # Create a temporary test configuration | |
| cat > test-users.conf << 'EOF' | |
| #!/bin/bash | |
| # Test configuration for GitHub Actions | |
| # No GitHub token needed for public key tests | |
| CONF_GITHUB_TOKEN="" | |
| # Test user key mapping with public GitHub users | |
| declare -A USER_KEYS=( | |
| # Test with a known GitHub user that has public keys | |
| ["testuser1"]="ghuser:octocat" | |
| # Test with raw public key (using GitHub's public key endpoint) | |
| ["testuser2"]="raw:https://github.com/octocat.keys" | |
| ) | |
| EOF | |
| - name: Test configuration validation | |
| run: | | |
| # Test with missing config file | |
| mv users.conf users.conf.backup | |
| ! ./sync-ssh-keys.sh 2>&1 | grep -q "Configuration file 'users.conf' not found" | |
| mv users.conf.backup users.conf | |
| echo "✓ Configuration file validation works" | |
| - name: Test configuration loading | |
| run: | | |
| # Use test configuration | |
| cp test-users.conf users.conf | |
| # Test basic functionality (dry run equivalent) | |
| timeout 30s ./sync-ssh-keys.sh || { | |
| echo "Script execution completed or timed out as expected" | |
| } | |
| echo "✓ Configuration loading test completed" | |
| - name: Test invalid method handling | |
| run: | | |
| # Create config with invalid method | |
| cat > test-invalid.conf << 'EOF' | |
| #!/bin/bash | |
| declare -A USER_KEYS=( | |
| ["testuser1"]="invalid:test" | |
| ) | |
| EOF | |
| cp test-invalid.conf users.conf | |
| # Should fail with unsupported method error | |
| ! ./sync-ssh-keys.sh 2>&1 | grep -q "Unsupported method 'invalid'" | |
| echo "✓ Invalid method handling works" | |
| - name: Test script syntax and functions | |
| run: | | |
| # Source the script to test function definitions | |
| bash -n sync-ssh-keys.sh | |
| echo "✓ Script syntax is valid" | |
| # Test individual functions by sourcing (without execution) | |
| ( | |
| source sync-ssh-keys.sh 2>/dev/null || true | |
| echo "✓ Script can be sourced" | |
| ) | |
| - name: Test with empty user array | |
| run: | | |
| # Create config with empty user array | |
| cat > test-empty.conf << 'EOF' | |
| #!/bin/bash | |
| declare -A USER_KEYS=() | |
| EOF | |
| cp test-empty.conf users.conf | |
| # Should exit cleanly with warning | |
| ./sync-ssh-keys.sh 2>&1 | grep -q "No users defined in USER_KEYS array" | |
| echo "✓ Empty user array handling works" | |
| - name: Test GitHub user key fetching (mock) | |
| run: | | |
| # Test the curl command format for GitHub user keys | |
| curl -fsSL "https://github.com/octocat.keys" | head -5 | |
| echo "✓ GitHub user key endpoint is accessible" | |
| - name: Test script version extraction | |
| run: | | |
| # Verify version can be extracted | |
| VERSION=$(awk -F'"' '/SCRIPT_VERSION/ {print $2; exit}' sync-ssh-keys.sh) | |
| if [[ -n "$VERSION" ]]; then | |
| echo "✓ Script version found: $VERSION" | |
| else | |
| echo "✗ Script version not found" | |
| exit 1 | |
| fi | |
| - name: Test self-update function (dry run) | |
| run: | | |
| # Test that self-update function exists and can be parsed | |
| grep -q "self_update()" sync-ssh-keys.sh | |
| grep -q "get_latest_release_url" sync-ssh-keys.sh | |
| grep -q "download_latest_script" sync-ssh-keys.sh | |
| echo "✓ Self-update functions are present" | |
| - name: Test error handling | |
| run: | | |
| # Create config that will trigger various error conditions | |
| cat > test-errors.conf << 'EOF' | |
| #!/bin/bash | |
| declare -A USER_KEYS=( | |
| ["nonexistentuser"]="ghuser:nonexistentuser12345" | |
| ["testuser1"]="raw:https://invalid-url-that-does-not-exist.example.com/keys" | |
| ) | |
| EOF | |
| cp test-errors.conf users.conf | |
| # Should handle errors gracefully | |
| ! ./sync-ssh-keys.sh | |
| echo "✓ Error handling test completed" | |
| - name: Test log message formatting | |
| run: | | |
| # Verify log messages are properly formatted with timestamps | |
| cp test-users.conf users.conf | |
| timeout 10s ./sync-ssh-keys.sh 2>&1 | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}:' || true | |
| echo "✓ Log message format test completed" | |
| - name: Cleanup test environment | |
| run: | | |
| # Restore original configuration | |
| git checkout users.conf 2>/dev/null || true | |
| # Remove test files | |
| rm -f test-*.conf | |
| # Remove test users (if they exist) | |
| sudo userdel -f testuser1 2>/dev/null || true | |
| sudo userdel -f testuser2 2>/dev/null || true | |
| sudo userdel -f testuser3 2>/dev/null || true | |
| echo "✓ Cleanup completed" | |
| integration-test: | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Make script executable | |
| run: chmod +x sync-ssh-keys.sh | |
| - name: Create integration test user | |
| run: | | |
| sudo useradd -m integrationuser | |
| - name: Setup integration test configuration | |
| run: | | |
| cat > users.conf << 'EOF' | |
| #!/bin/bash | |
| # Integration test configuration | |
| declare -A USER_KEYS=( | |
| # Use a real GitHub user with known public keys for integration testing | |
| ["integrationuser"]="ghuser:octocat" | |
| ) | |
| EOF | |
| - name: Run integration test | |
| run: | | |
| # Run the script and verify it completes successfully | |
| ./sync-ssh-keys.sh | |
| # Verify the authorized_keys file was created | |
| if [[ -f /home/integrationuser/.ssh/authorized_keys ]]; then | |
| echo "✓ authorized_keys file created successfully" | |
| echo "File contents:" | |
| head -2 /home/integrationuser/.ssh/authorized_keys | |
| echo "File permissions:" | |
| ls -la /home/integrationuser/.ssh/authorized_keys | |
| else | |
| echo "✗ authorized_keys file was not created" | |
| exit 1 | |
| fi | |
| - name: Verify file permissions | |
| run: | | |
| # Check SSH directory permissions | |
| PERMS=$(stat -c "%a" /home/integrationuser/.ssh) | |
| if [[ "$PERMS" == "700" ]]; then | |
| echo "✓ SSH directory permissions are correct (700)" | |
| else | |
| echo "✗ SSH directory permissions are incorrect: $PERMS" | |
| exit 1 | |
| fi | |
| # Check authorized_keys file permissions | |
| PERMS=$(stat -c "%a" /home/integrationuser/.ssh/authorized_keys) | |
| if [[ "$PERMS" == "600" ]]; then | |
| echo "✓ authorized_keys file permissions are correct (600)" | |
| else | |
| echo "✗ authorized_keys file permissions are incorrect: $PERMS" | |
| exit 1 | |
| fi | |
| - name: Cleanup integration test | |
| run: | | |
| sudo userdel -rf integrationuser 2>/dev/null || true | |
| git checkout users.conf |