Skip to content

Publish pfSense ISO #32

Publish pfSense ISO

Publish pfSense ISO #32

Workflow file for this run

name: Publish pfSense ISO
on:
workflow_dispatch:
schedule:
- cron: '0 2 * * 1'
env:
PFSENSE_BASE_URL: https://atxfiles.netgate.com/mirror/downloads
jobs:
download-and-release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Discover latest pfSense version
id: discover
run: |
set -euo pipefail
echo "πŸ” Discovering latest pfSense version..."
# Fetch and parse latest version
LATEST_FILE=$(curl -fsSL "$PFSENSE_BASE_URL/" | \
grep -oP 'pfSense-CE-\d+\.\d+\.\d+-RELEASE-amd64\.iso\.gz' | \
sort -V | tail -n1)
if [[ -z "$LATEST_FILE" ]]; then
echo "❌ Failed to find pfSense ISO file"
exit 1
fi
VERSION=$(echo "$LATEST_FILE" | sed 's/pfSense-CE-\(.*\)-RELEASE-amd64\.iso\.gz/\1/')
ISO_FILE="${LATEST_FILE%.gz}"
SHA_FILE="${ISO_FILE}.sha256"
echo "πŸ“¦ Found version: $VERSION"
echo "πŸ“ ISO file: $ISO_FILE"
# Export variables
{
echo "latest_file=$LATEST_FILE"
echo "version=$VERSION"
echo "iso_file=$ISO_FILE"
echo "sha_file=$SHA_FILE"
echo "download_url=$PFSENSE_BASE_URL/$LATEST_FILE"
echo "checksum_url=$PFSENSE_BASE_URL/$LATEST_FILE.sha256"
} >> "$GITHUB_OUTPUT"
- name: Check if release already exists
id: check_release
run: |
set +e # Don't exit on error for this check
echo "πŸ” Checking if release ${{ steps.discover.outputs.version }} already exists..."
gh release view "${{ steps.discover.outputs.version }}" >/dev/null 2>&1
EXISTS=$?
if [[ $EXISTS -eq 0 ]]; then
echo "βœ… Release already exists, skipping..."
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "πŸ†• New release detected, proceeding..."
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download pfSense files
if: steps.check_release.outputs.skip == 'false'
run: |
set -euo pipefail
echo "⬇️ Downloading pfSense ${{ steps.discover.outputs.version }}..."
# Download with progress and retry logic
download_with_retry() {
local url="$1"
local max_attempts=3
local attempt=1
while [[ $attempt -le $max_attempts ]]; do
echo "πŸ“₯ Attempt $attempt/$max_attempts: $(basename "$url")"
if curl -fsSL --progress-bar --retry 3 --retry-delay 5 -o "$(basename "$url")" "$url"; then
return 0
fi
((attempt++))
sleep 10
done
echo "❌ Failed to download $url after $max_attempts attempts"
return 1
}
download_with_retry "${{ steps.discover.outputs.download_url }}"
download_with_retry "${{ steps.discover.outputs.checksum_url }}"
- name: Verify integrity
if: steps.check_release.outputs.skip == 'false'
run: |
set -euo pipefail
echo "πŸ” Verifying file integrity..."
# Verify the compressed file first
if sha256sum -c "${{ steps.discover.outputs.latest_file }}.sha256"; then
echo "βœ… Compressed file integrity verified"
else
echo "❌ Compressed file integrity check failed"
exit 1
fi
- name: Extract ISO
if: steps.check_release.outputs.skip == 'false'
run: |
set -euo pipefail
echo "πŸ“¦ Extracting ISO file..."
# Extract with progress
gunzip -v "${{ steps.discover.outputs.latest_file }}"
# Verify extraction
if [[ -f "${{ steps.discover.outputs.iso_file }}" ]]; then
ISO_SIZE=$(du -h "${{ steps.discover.outputs.iso_file }}" | cut -f1)
echo "βœ… Extraction complete - ISO size: $ISO_SIZE"
else
echo "❌ ISO extraction failed"
exit 1
fi
- name: Generate checksums
if: steps.check_release.outputs.skip == 'false'
run: |
set -euo pipefail
echo "πŸ”’ Generating checksums for extracted ISO..."
# Generate multiple checksums for verification
sha256sum "${{ steps.discover.outputs.iso_file }}" > "${{ steps.discover.outputs.sha_file }}"
md5sum "${{ steps.discover.outputs.iso_file }}" > "${{ steps.discover.outputs.iso_file }}.md5"
# Display checksums
echo "πŸ“‹ Generated checksums:"
echo "SHA256: $(cat "${{ steps.discover.outputs.sha_file }}")"
echo "MD5: $(cat "${{ steps.discover.outputs.iso_file }}.md5")"
- name: Create GitHub Release
if: steps.check_release.outputs.skip == 'false'
run: |
set -euo pipefail
echo "πŸš€ Creating GitHub release..."
# Create release with detailed body
RELEASE_BODY="## pfSense Community Edition ${{ steps.discover.outputs.version }}
This is an automated release of pfSense CE ${{ steps.discover.outputs.version }}.
### Files included:
- 🎯 **${{ steps.discover.outputs.iso_file }}** - Main ISO image
- πŸ”’ **${{ steps.discover.outputs.sha_file }}** - SHA256 checksum
- πŸ”’ **${{ steps.discover.outputs.iso_file }}.md5** - MD5 checksum
### Verification:
\`\`\`bash
# Verify SHA256
sha256sum -c ${{ steps.discover.outputs.sha_file }}
# Verify MD5
md5sum -c ${{ steps.discover.outputs.iso_file }}.md5
\`\`\`
### Source:
Downloaded from: [Netgate Official Mirror](${{ env.PFSENSE_BASE_URL }})
---
*Automated release created on $(date -u '+%Y-%m-%d %H:%M:%S UTC')*"
gh release create "${{ steps.discover.outputs.version }}" \
--title "pfSense CE ${{ steps.discover.outputs.version }}" \
--notes "$RELEASE_BODY" \
"${{ steps.discover.outputs.iso_file }}" \
"${{ steps.discover.outputs.sha_file }}" \
"${{ steps.discover.outputs.iso_file }}.md5"
echo "βœ… Release created successfully!"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Clean up artifacts
if: always()
run: |
echo "🧹 Cleaning up downloaded files..."
rm -f *.iso *.gz *.sha256 *.md5 || true
echo "βœ… Cleanup complete"
- name: Release summary
if: steps.check_release.outputs.skip == 'false'
run: |
echo "## πŸŽ‰ pfSense Release Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version:** ${{ steps.discover.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**ISO File:** ${{ steps.discover.outputs.iso_file }}" >> $GITHUB_STEP_SUMMARY
echo "**Release URL:** ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ steps.discover.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "βœ… Release created successfully!" >> $GITHUB_STEP_SUMMARY