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
92 changes: 92 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: prepare-release

# Reusable release-preparation workflow for Apius Splunk apps (ADR-0004:
# commit-back release-PR flow). It stamps the target version into the two
# source-of-truth files -- app.conf [launcher] version and the root
# pyproject.toml [project].version -- on a release/vX.Y.Z branch, then opens a
# "Release vX.Y.Z" PR against main. It never writes to main directly; opening
# the PR runs the normal PR gate (ci.yml). A human reviews and merges the PR so
# main always shows the released version.
#
# Human release flow (see also release.yml):
# 1. Dispatch the caller prepare-release workflow with the target version.
# 2. This workflow opens the "Release vX.Y.Z" PR; review and merge it.
# 3. Push the tag vX.Y.Z on the merged commit.
# 4. The release workflow (release.yml) packages, runs AppInspect and
# publishes the GitHub Release.
on:
workflow_call:
inputs:
version:
description: "Release version X.Y.Z (no leading v)."
required: true
type: string
app_id:
description: "Splunk app id; also the app directory containing default/app.conf."
required: true
type: string
python_version:
description: "Python version used for the stamping tooling."
required: false
type: string
default: "3.9"

permissions:
contents: write
pull-requests: write

jobs:
prepare-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python_version }}

- name: Fetch packaging tooling
uses: actions/checkout@v4
with:
repository: apius-tech/splunk-app-ci
ref: main
path: .splunk-app-ci

# Stamp both source-of-truth files in place so the repo always shows the
# released version once the PR merges (ADR-0004).
- name: Stamp version into app.conf + pyproject.toml
run: >
PYTHONPATH=.splunk-app-ci python -m splunk_app_ci stamp
--version "${{ inputs.version }}"
--app-conf "${{ inputs.app_id }}/default/app.conf"
--pyproject pyproject.toml

- name: Configure git identity
run: |
git config user.name "Patryk Bujna"
git config user.email "patryk.bujna@apius.pl"

# Commit only the two stamped files onto a release branch and open the PR.
# The .splunk-app-ci checkout is intentionally not staged.
- name: Commit and open release PR
env:
GH_TOKEN: ${{ github.token }}
run: |
branch="release/v${{ inputs.version }}"
git checkout -b "$branch"
git add "${{ inputs.app_id }}/default/app.conf" pyproject.toml
git commit -m "Release v${{ inputs.version }}: stamp app.conf + pyproject version"
git push -u origin "$branch"
gh pr create \
--base main \
--head "$branch" \
--title "Release v${{ inputs.version }}" \
--body "Automated release preparation for v${{ inputs.version }} (ADR-0004).

Stamps to v${{ inputs.version }}:
- \`${{ inputs.app_id }}/default/app.conf\` \`[launcher] version\`
- root \`pyproject.toml\` \`[project].version\`

After merge, push the tag \`v${{ inputs.version }}\` on the merged commit to trigger the release workflow (package -> AppInspect API -> GitHub Release)."
132 changes: 132 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
name: release

# Reusable release/publish workflow for Apius Splunk apps (ADR-0004 / ADR-0005).
# Triggered by a caller on a pushed tag vX.Y.Z (on the merged release commit),
# it builds the Splunkbase package at the released version, runs Splunk
# AppInspect via the AppInspect API, and publishes a GitHub Release with the
# packaged .tar.gz and auto-generated notes.
#
# AppInspect (ADR-0005): base (non-cloud) errors/failures BLOCK the release;
# cloud findings are ADVISORY by default and only block when cloud_gate=true.
# The base and cloud vettings run as two steps so blocking can be controlled
# per-tag-set: the base step always blocks (the action's failOnError is
# hardcoded true), while the cloud step is made advisory via step-level
# continue-on-error unless cloud_gate is set.
#
# Splunkbase upload is deliberately out of scope here (that is slice #6); this
# workflow stops after the GitHub Release step.
#
# Human release flow (see also prepare-release.yml):
# 1. Dispatch prepare-release with the target version; merge the "Release
# vX.Y.Z" PR so main shows the released version.
# 2. Push the tag vX.Y.Z on the merged commit -> this workflow runs.
on:
workflow_call:
inputs:
app_id:
description: "Splunk app id; also the app directory to package/inspect."
required: true
type: string
version:
description: "Release version X.Y.Z (no leading v; caller strips it from the tag)."
required: true
type: string
cloud_gate:
description: "When true, AppInspect cloud findings block the release; otherwise advisory."
required: false
type: boolean
default: false
python_version:
description: "Python version used for the packaging tooling."
required: false
type: string
default: "3.9"
secrets:
SPLUNK_USER:
description: "splunk.com service-account user for the AppInspect API."
required: true
SPLUNK_PASS:
description: "splunk.com service-account password for the AppInspect API."
required: true

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python_version }}

- name: Fetch packaging tooling
uses: actions/checkout@v4
with:
repository: apius-tech/splunk-app-ci
ref: main
path: .splunk-app-ci

# Build the Splunkbase artifact at the released version into dist/. The
# AppInspect API action globs the directory, so dist/ holds only this
# single tarball.
- name: Build package
run: >
PYTHONPATH=.splunk-app-ci python -m splunk_app_ci package
--app-dir "${{ inputs.app_id }}"
--version "${{ inputs.version }}"
--dest dist

# Base (non-cloud) vetting. failOnError is hardcoded true in the action,
# so any error/failure here BLOCKS the release.
- name: AppInspect API (base checks, blocking)
uses: splunk/appinspect-api-action@v3.0.5
with:
username: ${{ secrets.SPLUNK_USER }}
password: ${{ secrets.SPLUNK_PASS }}
app_path: dist
excluded_tags: "manual,cloud"

- name: Upload base AppInspect report
if: always()
uses: actions/upload-artifact@v4
with:
name: appinspect-base-report
path: AppInspect_response.html
if-no-files-found: warn

# Cloud vetting. included_tags: cloud runs only the cloud checks. The
# step is advisory (continue-on-error) unless cloud_gate is true, in
# which case cloud findings block the release.
- name: AppInspect API (cloud vetting, advisory unless cloud_gate)
continue-on-error: ${{ !inputs.cloud_gate }}
uses: splunk/appinspect-api-action@v3.0.5
with:
username: ${{ secrets.SPLUNK_USER }}
password: ${{ secrets.SPLUNK_PASS }}
app_path: dist
included_tags: cloud

- name: Upload cloud AppInspect report
if: always()
uses: actions/upload-artifact@v4
with:
name: appinspect-cloud-report
path: AppInspect_response.html
if-no-files-found: warn

# Publish the GitHub Release for the pushed tag with the packaged
# artifact and auto-generated notes. Reached only when the base checks
# (and, under cloud_gate, cloud checks) passed.
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: >
gh release create "v${{ inputs.version }}"
dist/*.tar.gz
--title "v${{ inputs.version }}"
--generate-notes
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,76 @@ python -m splunk_app_ci stamp --version X.Y.Z \
directory is the app id, with `app.conf` version stamped, vendored `lib/`
retained, and tooling/VCS artifacts excluded.

## Release workflows

Two reusable workflows implement the commit-back release-PR flow (ADR-0004),
each with a thin caller in the app repo:

- `.github/workflows/prepare-release.yml` (`workflow_call`; inputs `version`,
`app_id`) — stamps `app.conf [launcher] version` and root `pyproject.toml
[project].version` to `version` on a `release/vX.Y.Z` branch and opens a
"Release vX.Y.Z" PR. It never writes to main directly; opening the PR runs
the normal PR gate.
- `.github/workflows/release.yml` (`workflow_call`; inputs `app_id`, `version`,
`cloud_gate` default `false`; secrets `SPLUNK_USER`/`SPLUNK_PASS`) — packages
the app at `version`, runs Splunk AppInspect via the **AppInspect API**
(`splunk/appinspect-api-action`), and publishes a GitHub Release with the
`.tar.gz` and auto-generated notes. Base (non-cloud) errors/failures block;
cloud findings are advisory unless `cloud_gate=true` (ADR-0005). Splunkbase
upload is a separate slice and is not done here.

### Human release flow

1. Dispatch the app's `prepare-release` caller with the target version
(`X.Y.Z`). This opens the "Release vX.Y.Z" PR.
2. Review and merge the Release PR — main now shows the released version.
3. Push the tag `vX.Y.Z` on the merged commit
(`git tag vX.Y.Z && git push origin vX.Y.Z`).
4. The `release` workflow runs: package -> AppInspect API -> GitHub Release.

Caller examples (in an app repo):

```yaml
# .github/workflows/prepare-release.yml
name: prepare-release
on:
workflow_dispatch:
inputs:
version: { description: "X.Y.Z", required: true, type: string }
jobs:
prepare-release:
uses: apius-tech/splunk-app-ci/.github/workflows/prepare-release.yml@main
with:
version: ${{ inputs.version }}
app_id: <app_id>
```

```yaml
# .github/workflows/release.yml
name: release
on:
push:
tags: ["v*"]
jobs:
version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.strip.outputs.version }}
steps:
- id: strip
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
release:
needs: version
uses: apius-tech/splunk-app-ci/.github/workflows/release.yml@main
with:
app_id: <app_id>
version: ${{ needs.version.outputs.version }}
secrets: inherit
```

The `prepare-release` job needs the repo setting "Allow GitHub Actions to
create and approve pull requests" enabled so it can open the Release PR.

## Development

```
Expand Down
Loading