Skip to content

Verify and Release #212

Verify and Release

Verify and Release #212

Workflow file for this run

name: Verify and Release
on:
workflow_dispatch:
inputs:
release:
description: 'Version to release'
required: true
permissions: read-all
env:
javaVersion: java26
jobs:
release:
name: Release
runs-on: ubuntu-24.04
timeout-minutes: 60
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: write # Needed for checkout, git-auto-commit-action, and creating releases
packages: write # Needed for publishing packages
id-token: write # Required for SLSA provenance and SBOM attestation
actions: read # Basic read access to actions
security-events: write # Needed for SBOM attestation
statuses: write # Required for commit statuses updated by actions
issues: write # Updated to write for release-drafter
pull-requests: write # Updated to write for release-drafter
pages: read
deployments: write
attestations: write # Required to create and persist attestations
strategy:
fail-fast: false
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: block
allowed-endpoints: >
api.adoptopenjdk.net:443
api.adoptium.net:443
api.github.com:443
apt.postgresql.org:443
archive.apache.org:443
azure.archive.ubuntu.com:80
azure.archive.ubuntu.com:443
security.ubuntu.com:80
security.ubuntu.com:443
github.com:443
maven.java.net:443
maven.vaadin.com:443
objects.githubusercontent.com:443
oss.sonatype.org:443
raw.githubusercontent.com:443
repo.maven.apache.org:443
maven.mirrors.opennms.org:443
repo1.maven.org:443
repository.mulesoft.org:443
tools.google.com:80
tools.vaadin.com:443
uploads.github.com:443
spdx.org:443
sonarcloud.io:443
repository.jboss.org:443
repository.sonatype.org:443
files.pythonhosted.org:443
pypi.org:443
www.bridgecrew.cloud:443
www.postgresql.org:443
docs.github.com:443
dlcdn.apache.org:443
archive.apache.org:443
esm.ubuntu.com:443
fulcio.sigstore.dev:443
packages.microsoft.com:443
rekor.sigstore.dev:443
release-drafter.github.io:443
release-assets.githubusercontent.com:443
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 2
- name: Set up JDK 26
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'temurin'
java-version: '26'
java-package: 'jdk' # Explicitly specify JDK package
check-latest: true # Always get latest patch version
# Disable built-in cache - we use optimized manual caching below
cache: ''
server-id: 'github' # Optional: For GitHub Packages authentication
architecture: 'x64' # Explicitly specify architecture
# Optimized Maven caching with multiple fallback levels for better resilience
- name: Cache Maven dependencies
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
~/.m2/repository
~/.m2/wrapper
~/.sonar/cache
# Include Maven version in key for isolation
key: ${{ runner.os }}-maven-3.9.15-${{ hashFiles('**/pom.xml', '.mvn/**') }}
restore-keys: |
${{ runner.os }}-maven-3.9.15-${{ hashFiles('**/pom.xml') }}
${{ runner.os }}-maven-3.9.15-
${{ runner.os }}-maven-
- name: Add PostgreSQL PGDG repository
run: |
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
- name: APT update
run: sudo apt-get update
- name: Install buildtools
run: sudo apt-get install -y graphviz build-essential fakeroot devscripts debhelper dh-make wget
- name: Install PostgreSQL
run: sudo apt-get install -y postgresql-18 postgresql-contrib-18 postgresql-18-pgaudit postgresql-18-pgvector
- name: Create PostgreSQL 18 cluster
run: |
# Drop pre-installed PostgreSQL clusters that block port 5432
sudo pg_dropcluster --stop 14 main || true
sudo pg_dropcluster --stop 16 main || true
# Create and start PostgreSQL 18 cluster (idempotent)
if sudo pg_lsclusters 18 main >/dev/null 2>&1; then
sudo pg_ctlcluster 18 main start
else
sudo pg_createcluster 18 main --start
fi
- name: Configure PostgreSQL
run: |
# Enable prepared transactions and required extensions
sudo sed -i "s/#max_prepared_transactions = 0/max_prepared_transactions = 100/" /etc/postgresql/18/main/postgresql.conf
sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = 'pg_stat_statements, pgaudit, pgcrypto'/" /etc/postgresql/18/main/postgresql.conf
echo "pgaudit.log = ddl" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "pg_stat_statements.track = all" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "pg_stat_statements.max = 10000" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Performance optimization settings per README-SCHEMA-MAINTENANCE.md
# Memory settings (adjusted for GitHub Actions ~7GB RAM, lower than production recommendations)
echo "shared_buffers = '1GB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "effective_cache_size = '4GB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "work_mem = '32MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "maintenance_work_mem = '256MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Checkpoint settings for write performance
echo "checkpoint_completion_target = 0.9" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "wal_buffers = '16MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "max_wal_size = '2GB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "min_wal_size = '512MB'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Query planning optimizations (SSD storage on GitHub Actions)
echo "random_page_cost = 1.1" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "effective_io_concurrency = 200" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Connection settings (reduced for CI environment)
echo "max_connections = 100" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Add IPv6 loopback access
echo "host all all ::1/128 md5" | sudo tee -a /etc/postgresql/18/main/pg_hba.conf
- name: Generate SSL certificates for PostgreSQL
run: |
# Generate secure random passphrase
openssl rand -base64 48 > passphrase.txt
# Create passphrase-protected private key
openssl genrsa -des3 -passout file:passphrase.txt -out server.pass.key 2048
# Remove passphrase protection from private key
openssl rsa -passin file:passphrase.txt -in server.pass.key -out server.key
rm server.pass.key
# Create Certificate Signing Request
openssl req -new -key server.key -out server.csr \
-subj "/C=UK/ST=PostgreSQL/L=Docker/O=Hack23/OU=demo/CN=127.0.0.1"
# Self-sign the certificate (valid for 10 years)
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
# Clean up temporary files
rm passphrase.txt server.csr
- name: Deploy SSL certificate and key for PostgreSQL
run: |
# Copy certificate and key to PostgreSQL data directory
sudo cp server.crt /var/lib/postgresql/18/main/server.crt
sudo cp server.key /var/lib/postgresql/18/main/server.key
# Secure the certificate and key
sudo chmod 600 /var/lib/postgresql/18/main/server.key
sudo chmod 644 /var/lib/postgresql/18/main/server.crt
sudo chown postgres:postgres /var/lib/postgresql/18/main/server.key
sudo chown postgres:postgres /var/lib/postgresql/18/main/server.crt
# Enable SSL in PostgreSQL
echo "ssl = on" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "ssl_cert_file = '/var/lib/postgresql/18/main/server.crt'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
echo "ssl_key_file = '/var/lib/postgresql/18/main/server.key'" | sudo tee -a /etc/postgresql/18/main/postgresql.conf
# Provide SSL certificate to the runner user
mkdir -p $HOME/.postgresql
cp server.crt $HOME/.postgresql/root.crt
chmod 600 $HOME/.postgresql/root.crt
# Clean up
rm server.key server.crt
# Restart PostgreSQL to apply all changes
sudo systemctl restart postgresql
- name: Create CIA database and user
run: |
sudo -u postgres psql -c "CREATE USER eris WITH PASSWORD 'discord';"
sudo -u postgres psql -c "CREATE DATABASE cia_dev;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE cia_dev TO eris;"
sudo -u postgres psql -d cia_dev -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"
sudo -u postgres psql -d cia_dev -c "CREATE EXTENSION IF NOT EXISTS pgaudit;"
sudo -u postgres psql -d cia_dev -c "CREATE EXTENSION IF NOT EXISTS pgcrypto;"
sudo -u postgres psql -d cia_dev -c "GRANT ALL ON SCHEMA public TO eris;"
- name: Load database schema
run: |
# Load the full schema into the database
sudo -u postgres psql -d cia_dev -f service.data.impl/src/main/resources/full_schema.sql || echo "Schema load completed with warnings (expected for first-time setup)"
- name: Remove localtime
run: sudo rm /etc/localtime
- name: Set Swedish localtime
run: sudo ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime
- name: Update tzdata
run: sudo dpkg-reconfigure -f noninteractive tzdata
- name: Set up Maven
uses: stCarolas/setup-maven@d6af6abeda15e98926a57b5aa970a96bb37f97d1 # v5
with:
maven-version: 3.9.15
- name: Set Version for release
run: mvn -B --file parent-pom/pom.xml versions:set -DnewVersion="${{ github.event.inputs.release }}" -Pall-modules versions:commit -Dmaven.wagon.http.retryHandler.count=3 -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.pool=true
- uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
with:
commit_message: Automated Release ${{ github.event.inputs.release }}
branch: release-${{ github.event.inputs.release }}
tagging_message: '${{ github.event.inputs.release }}'
create_branch: true
- name: Build with Maven
run: mvn -B --file pom.xml clean install -Prelease-site,all-modules -DforkMode=once '-Dtest=!**ITest*,!**DocumentationTest*' -Dmaven.test.skip=true -DfailIfNoTests=false -Dmaven.wagon.http.retryHandler.count=3 -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.pool=true
# Rename SPDX files to align with artifact naming convention
- name: Rename SPDX files to match artifact names
run: |
cp -v cia-dist-deb/target/site/com.hack23.cia_cia-dist-deb-${{ github.event.inputs.release }}.spdx.json cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb.spdx.json
cp -v citizen-intelligence-agency/target/site/com.hack23.cia_citizen-intelligence-agency-${{ github.event.inputs.release }}.spdx.json citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war.spdx.json
# Generate artifact attestation for DEB package
- name: Generate artifact attestation for deb package
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
id: attest_deb
with:
subject-path: 'cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb'
- name: Copy artifact attestation for deb package
run: cp ${{ steps.attest_deb.outputs.bundle-path }} cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb.intoto.jsonl
# Generate SBOM attestation for DEB package (actions/attest with sbom-path replaces deprecated actions/attest-sbom)
- name: Generate SBOM attestation for deb package
id: attestsbom_deb
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
with:
subject-path: 'cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb'
sbom-path: 'cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb.spdx.json'
- name: Copy SBOM attestation for deb package
run: cp ${{ steps.attestsbom_deb.outputs.bundle-path }} cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb.spdx.json.intoto.jsonl
# Generate artifact attestation for WAR
- name: Generate artifact attestation for WAR
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
id: attest_war
with:
subject-path: 'citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war'
- name: Copy artifact attestation for WAR
run: cp ${{ steps.attest_war.outputs.bundle-path }} citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war.intoto.jsonl
# Generate SBOM attestation for WAR (actions/attest with sbom-path replaces deprecated actions/attest-sbom)
- name: Generate SBOM attestation for WAR
id: attestsbom_war
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
with:
subject-path: 'citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war'
sbom-path: 'citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war.spdx.json'
- name: Copy SBOM attestation for WAR
run: cp ${{ steps.attestsbom_war.outputs.bundle-path }} citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war.spdx.json.intoto.jsonl
- name: Draft Release Notes
id: release-notes
uses: release-drafter/release-drafter@c2e2804cc59f45f57076a99af580d0fedb697927 # v7.3.0
with:
config-name: release-drafter.yml
version: ${{ github.event.inputs.release }}
tag: ${{ github.event.inputs.release }}
name: Release ${{ github.event.inputs.release }}
publish: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create a GitHub release
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0
with:
tag: '${{ github.event.inputs.release }}'
generateReleaseNotes: false
immutableCreate: true
name: Release ${{ github.event.inputs.release }}
body: ${{ steps.release-notes.outputs.body }}
artifacts: |
cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb
cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb.intoto.jsonl
cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb.spdx.json
cia-dist-deb/target/cia-dist-deb-${{ github.event.inputs.release }}.all.deb.spdx.json.intoto.jsonl
citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war
citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war.intoto.jsonl
citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war.spdx.json
citizen-intelligence-agency/target/citizen-intelligence-agency-${{ github.event.inputs.release }}.war.spdx.json.intoto.jsonl
cia-dist-cloudformation/src/main/resources/cia-dist-cloudformation.json
- name: Submit Dependency Release
uses: advanced-security/maven-dependency-submission-action@b275d12641ac2d2108b2cbb7598b154ad2f2cee8 # v5.0.0