Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
_commit: v1.2.0
_commit: v1.7.1
_src_path: git@github.com:aignostics/foundry-python.git
author_email: oliver.meyer@aignostics.com
author_github_username: olivermeyer
Expand All @@ -9,5 +9,6 @@ import_package_name: aignostics_foundry_core
project_description: Foundational infrastructure for Foundry components.
project_icon: 🏭
project_name: Foundry Python Core
project_type: library
slack_notifications_enabled: true
slack_release_channel: '#announce-foundry'
4 changes: 2 additions & 2 deletions .github/actions/run-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ runs:
shell: bash
run: |
set +e
mise run $MISE_TASK
mise run "${MISE_TASK}"
EXIT_CODE=$?
# Show test execution in GitHub Job summary
found_files=0
Expand All @@ -47,7 +47,7 @@ runs:
fi
done
if [ $found_files -eq 0 ]; then
echo "# $SUMMARY_TITLE" >> $GITHUB_STEP_SUMMARY
echo "# ${SUMMARY_TITLE}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
fi
# Show test coverage in GitHub Job summary
Expand Down
3 changes: 3 additions & 0 deletions .github/actions/setup-dev-env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ description: 'Checkout, GCP auth, mise, uv, and dev tools'
runs:
using: 'composite'
steps:

- name: Install mise
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1

- name: Initialize mise and install Python dependencies
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
run: mise run install
4 changes: 4 additions & 0 deletions .github/workflows/_audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Audit
run: mise run audit

- name: Generate attributions
run: mise run attributions

- name: Upload audit results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ always() && (env.GITHUB_WORKFLOW_RUNTIME != 'ACT') }}
Expand All @@ -34,4 +37,5 @@ jobs:
reports/licenses.json
reports/licenses_grouped.json
reports/vulnerabilities.json
reports/ATTRIBUTIONS.md
retention-days: 30
2 changes: 1 addition & 1 deletion .github/workflows/_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ jobs:
uses: ./.github/actions/setup-dev-env

- name: Lint
run: mise run lint
run: mise run pre_commit_run_all
17 changes: 10 additions & 7 deletions .github/workflows/_package-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ jobs:
- name: Setup Dev Environment
uses: ./.github/actions/setup-dev-env

- name: Build documentation
run: mise run docs

- name: Build distribution
run: uv build
Expand All @@ -45,10 +43,15 @@ jobs:

# Export release notes for Slack notification
# Convert markdown links [text](url) to Slack format <url|text>
# Truncate to 2900 chars for Slack's ~3000 char limit
# If notes exceed Slack's ~3000 char limit, truncate and add link to full release notes
# Escape for JSON (backslashes, quotes, newlines)
NOTES=$(sed -E 's/\[([^]]+)\]\(([^)]+)\)/<\2|\1>/g' RELEASE_NOTES.md | head -c 2900 | \
sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
NOTES_CONVERTED=$(sed -E 's/\[([^]]+)\]\(([^)]+)\)/<\2|\1>/g' RELEASE_NOTES.md)
RELEASE_URL="${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}"
if [ "$(printf '%s' "$NOTES_CONVERTED" | wc -c)" -gt 2700 ]; then
NOTES_TRUNCATED=$(printf '%s' "$NOTES_CONVERTED" | head -c 2700)
NOTES_CONVERTED="${NOTES_TRUNCATED}"$'\n'"...<${RELEASE_URL}|Read full release notes>"
fi
NOTES=$(printf '%s' "$NOTES_CONVERTED" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
echo "RELEASE_NOTES_CONTENT=$NOTES" >> $GITHUB_ENV


Expand All @@ -69,8 +72,8 @@ jobs:

- name: Send Slack release notification
if: success()
uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
with:
method: chat.postMessage
token: ${{ secrets.SLACK_RELEASE_BOT_TOKEN }}
payload: '{"channel":"#announce-foundry","text":"🚀 aignostics-foundry-core ${{ github.ref_name }} released","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"🚀 *aignostics-foundry-core* <${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> released"}},{"type":"section","text":{"type":"mrkdwn","text":"${{ env.RELEASE_NOTES_CONTENT }}"}}]}'
payload: '{"channel":"#announce-foundry","text":"🚀 Foundry Python Core ${{ github.ref_name }} released","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"🚀 *Foundry Python Core* <${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}> released"}},{"type":"section","text":{"type":"mrkdwn","text":"${{ env.RELEASE_NOTES_CONTENT }}"}}]}'
15 changes: 4 additions & 11 deletions .github/workflows/_scheduled-test-daily.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,21 @@ jobs:
- name: Setup Dev Environment
uses: ./.github/actions/setup-dev-env

- name: Print development version info
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
shell: bash
run: |
TOML_VERSION=$(grep -m 1 '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
echo "Development build - Current version in pyproject.toml: $TOML_VERSION"

- name: Validate and set environment suffix
id: env_suffix
env:
DEPLOY_ENV: ${{ inputs.deploy_env }}
shell: bash
run: |
# Validate deploy_env is one of the allowed values
case "$DEPLOY_ENV" in
case "${DEPLOY_ENV}" in
dev|test|staging|production)
# Convert to uppercase
SUFFIX=$(echo "$DEPLOY_ENV" | tr '[:lower:]' '[:upper:]')
SUFFIX=$(echo "${DEPLOY_ENV}" | tr '[:lower:]' '[:upper:]')
echo "suffix=${SUFFIX}" >> $GITHUB_OUTPUT
;;
*)
echo "Error: Invalid deploy_env value '$DEPLOY_ENV'. Must be one of: dev, test, staging, production"
echo "Error: Invalid deploy_env value '${DEPLOY_ENV}'. Must be one of: dev, test, staging, production"
exit 1
;;
esac
Expand Down Expand Up @@ -220,7 +213,7 @@ jobs:

- name: SonarQube Scan
if: ${{ !cancelled() && (env.GITHUB_WORKFLOW_RUNTIME != 'ACT') }}
uses: SonarSource/sonarqube-scan-action@59db25f34e16620e48ab4bb9e4a5dce155cb5432 # v8
uses: SonarSource/sonarqube-scan-action@59db25f34e16620e48ab4bb9e4a5dce155cb5432 # v8.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/_scheduled-test-hourly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ jobs:
shell: bash
run: |
# Validate deploy_env is one of the allowed values
case "$DEPLOY_ENV" in
case "${DEPLOY_ENV}" in
dev|test|staging|production)
# Convert to uppercase
SUFFIX=$(echo "$DEPLOY_ENV" | tr '[:lower:]' '[:upper:]')
SUFFIX=$(echo "${DEPLOY_ENV}" | tr '[:lower:]' '[:upper:]')
echo "suffix=${SUFFIX}" >> $GITHUB_OUTPUT
;;
*)
echo "Error: Invalid deploy_env value '$DEPLOY_ENV'. Must be one of: dev, test, staging, production"
echo "Error: Invalid deploy_env value '${DEPLOY_ENV}'. Must be one of: dev, test, staging, production"
exit 1
;;
esac
Expand Down
28 changes: 20 additions & 8 deletions .github/workflows/_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ name: "> Test"

on:
workflow_call:
secrets:
CODECOV_TOKEN:
required: true
SONAR_TOKEN:
required: true
AIGNOSTICS_FOUNDRY_CORE_LOGFIRE_TOKEN:
required: false
AIGNOSTICS_FOUNDRY_CORE_SENTRY_DSN:
required: false

concurrency:
group: test-${{ github.ref }}
Expand All @@ -15,6 +24,7 @@ jobs:
contents: read
id-token: write
packages: write

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -40,13 +50,6 @@ jobs:
TOML_VERSION=$(grep -m 1 '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
echo "Development build - Current version in pyproject.toml: $TOML_VERSION"

- name: Create .env file
uses: SpicyPizza/create-envfile@ace6d4f5d7802b600276c23ca417e669f1a06f6f # v2.0.3
with:
envkey_AIGNOSTICS_FOUNDRY_CORE_LOGFIRE_TOKEN: "${{ secrets.AIGNOSTICS_FOUNDRY_CORE_LOGFIRE_TOKEN }}"
envkey_AIGNOSTICS_FOUNDRY_CORE_SENTRY_DSN: "${{ secrets.AIGNOSTICS_FOUNDRY_CORE_SENTRY_DSN }}"
fail_on_empty: false

- name: Test / Unit
uses: ./.github/actions/run-tests
with:
Expand Down Expand Up @@ -74,6 +77,15 @@ jobs:
summary-title: All e2e tests passed
commit-message: ${{ github.event.head_commit.message }}

- name: Test / Unit (lowest-direct)
uses: ./.github/actions/run-tests
with:
test-type: unit
mise-task: test_lowest_direct
skip-marker: skip:test:lowest-direct
summary-title: All unit tests passed with lowest-direct dependencies
commit-message: ${{ github.event.head_commit.message }}

- name: Upload test results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ always() && (env.GITHUB_WORKFLOW_RUNTIME != 'ACT') }}
Expand Down Expand Up @@ -102,7 +114,7 @@ jobs:

- name: SonarQube Scan
if: ${{ !cancelled() && (env.GITHUB_WORKFLOW_RUNTIME != 'ACT') }}
uses: SonarSource/sonarqube-scan-action@59db25f34e16620e48ab4bb9e4a5dce155cb5432 # v8
uses: SonarSource/sonarqube-scan-action@59db25f34e16620e48ab4bb9e4a5dce155cb5432 # v8.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
11 changes: 5 additions & 6 deletions .github/workflows/bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ on:
required: false
type: string
default: ""
workflow_call:

jobs:
bump:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
client-id: ${{ secrets.RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}

- name: Checkout
Expand All @@ -28,11 +30,8 @@ jobs:
token: ${{ steps.app-token.outputs.token }}
fetch-depth: 0

- name: Install mise
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1

- name: Install Python, venv and dependencies
run: uv sync --all-extras --frozen --no-build --link-mode=copy
- name: Setup Dev Environment
uses: ./.github/actions/setup-dev-env

- name: Configure git identity
run: |
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/check-action-pins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: check-action-pins

on:
pull_request:
paths:
- '.github/workflows/**'
- '.github/actions/**'

jobs:
check-action-pins:
name: Check action SHA pins have version comments
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Check action pins
uses: suzuki-shunsuke/pinact-action@cf51507d80d4d6522a07348e3d58790290eaf0b6 # v2.0.0
with:
review: "true"
skip_push: "true"
github_token_for_review: ${{ github.token }}
reviewdog_filter_mode: added
31 changes: 19 additions & 12 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
name: "+ CI/CD"

on:
# Pull requests to main trigger feature deployment
pull_request:
branches: [main]
types: [opened, synchronize, reopened, closed]

# Pushes/merges to main and version tags trigger deployment
push:
branches: ["main"]
tags:
- "v*"

# Manual trigger for any branch
workflow_dispatch:
Expand All @@ -22,32 +17,43 @@ concurrency:
jobs:

lint:
if: (!contains(github.event.head_commit.message, '[skip ci]'))
# Skip on pull_request:closed as merge commits also triggeres this and they share the same concurrency group
if: |
!contains(github.event.head_commit.message, '[skip ci]') &&
!(github.event_name == 'pull_request' && github.event.action == 'closed')
uses: ./.github/workflows/_lint.yml
permissions:
contents: read
id-token: write
packages: read
secrets: inherit

audit:
if: (!contains(github.event.head_commit.message, '[skip ci]'))
# Skip on pull_request:closed as merge commits also triggeres this and they share the same concurrency group
if: |
!contains(github.event.head_commit.message, '[skip ci]') &&
!(github.event_name == 'pull_request' && github.event.action == 'closed')
uses: ./.github/workflows/_audit.yml
permissions:
contents: read
id-token: write
packages: read
secrets: inherit

test:
if: (!contains(github.event.head_commit.message, '[skip ci]'))
# Skip on pull_request:closed as merge commits also triggeres this and they share the same concurrency group
if: |
!contains(github.event.head_commit.message, '[skip ci]') &&
!(github.event_name == 'pull_request' && github.event.action == 'closed')
uses: ./.github/workflows/_test.yml
permissions:
attestations: write
contents: read
id-token: write
packages: write
secrets: inherit
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
AIGNOSTICS_FOUNDRY_CORE_LOGFIRE_TOKEN: ${{ secrets.AIGNOSTICS_FOUNDRY_CORE_LOGFIRE_TOKEN }}
AIGNOSTICS_FOUNDRY_CORE_SENTRY_DSN: ${{ secrets.AIGNOSTICS_FOUNDRY_CORE_SENTRY_DSN }}

publish_package:
if: startsWith(github.ref, 'refs/tags/v')
Expand All @@ -57,4 +63,5 @@ jobs:
contents: write
id-token: write
packages: read
secrets: inherit
secrets:
SLACK_RELEASE_BOT_TOKEN: ${{ secrets.SLACK_RELEASE_BOT_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/claude-code-automation-pr-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
claude_args: |
--max-turns 100
--model claude-sonnet-4-5-20250929
--allowedTools "mcp__github_inline_comment__create_inline_comment,Read,Write,Edit,MultiEdit,Glob,Grep,LS,WebFetch,WebSearch,Bash(git:*),Bash(bun:*),Bash(npm:*),Bash(npx:*),Bash(gh:*),Bash(uv:*),Bash(make:*),Bash(export:*)"
--allowedTools "Bash(git diff *)" "Bash(git log *)" "Bash(gh pr view *)"
allowed_bots: "dependabot[bot],renovate[bot]"
prompt: |
# PR REVIEW
Expand Down
Loading
Loading