Skip to content
Draft
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
23 changes: 18 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,29 @@ permissions:

jobs:
package:
name: Build plugin packages
name: Build and verify plugin packages
runs-on: ubuntu-latest
steps:
# The local Kandev SDK replacement expects this sibling layout.
- name: Checkout plugin
- name: Check out plugin
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
path: plugin

- name: Checkout Kandev SDK
- name: Read pinned Kandev source revision
id: sdk
working-directory: plugin
run: |
set -euo pipefail
sdk_ref="$(cat .kandev-sdk-ref)"
[[ "$sdk_ref" =~ ^[0-9a-f]{40}$ ]]
echo "ref=$sdk_ref" >> "$GITHUB_OUTPUT"

- name: Check out Kandev SDK contract
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
repository: kdlbs/kandev
path: kandev
ref: ${{ steps.sdk.outputs.ref }}
sparse-checkout: apps/backend

- name: Set up Go
Expand All @@ -39,6 +48,10 @@ jobs:
working-directory: plugin
run: make build

- name: Package all supported platforms
- name: Build and verify host-only package
working-directory: plugin
run: make package-host

- name: Build and verify every declared platform
working-directory: plugin
run: make package
31 changes: 23 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,56 @@ jobs:
name: Format, vet, and test
runs-on: ubuntu-latest
steps:
# Keep the checkouts side by side so go.mod's local Kandev SDK
# replacement (../kandev/apps/backend) resolves on a fresh runner.
- name: Checkout plugin
- name: Check out plugin
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
path: plugin

- name: Checkout Kandev SDK
- name: Read pinned Kandev source revision
id: sdk
working-directory: plugin
run: |
set -euo pipefail
sdk_ref="$(cat .kandev-sdk-ref)"
[[ "$sdk_ref" =~ ^[0-9a-f]{40}$ ]]
echo "ref=$sdk_ref" >> "$GITHUB_OUTPUT"

- name: Check out Kandev SDK contract
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
repository: kdlbs/kandev
path: kandev
sparse-checkout: apps/backend
ref: ${{ steps.sdk.outputs.ref }}
sparse-checkout: |
apps/backend
apps/packages/plugin-sdk

- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: plugin/go.mod
cache-dependency-path: plugin/go.sum

- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24

- name: Check module files are tidy
working-directory: plugin
run: |
set -euo pipefail
go mod tidy
git diff --exit-code -- go.mod go.sum

- name: Check formatting
working-directory: plugin
run: |
test -z "$(gofmt -l ./server)" || { echo "gofmt needed:"; gofmt -l ./server; exit 1; }
run: make check-format

- name: Vet
working-directory: plugin
run: make vet

- name: Test
- name: Test backend, UI, and package verifiers
working-directory: plugin
run: make test
168 changes: 130 additions & 38 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
name: release

# Run manually from GitHub Actions on master to calculate a version, commit the
# release metadata and changelog, tag that commit, then build and publish it.
# Existing v* tag pushes skip preparation and only build and publish.
# Dispatch builds and validates the complete candidate before pushing release
# metadata or a tag. Pushed tags pass through the same checks before publish.
on:
push:
tags:
Expand All @@ -19,19 +18,25 @@ on:
- minor
- major
dry_run:
description: "Calculate the release version without committing, tagging, or publishing"
description: "Build and validate the candidate without committing, tagging, or publishing"
required: true
type: boolean
default: false

concurrency:
group: kandy-release
cancel-in-progress: false

permissions:
contents: write
contents: read

jobs:
prepare:
name: Prepare release commit
name: Validate and prepare release candidate
if: ${{ github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
tag: ${{ steps.version.outputs.tag }}
steps:
Expand All @@ -48,17 +53,52 @@ jobs:
- name: Check out master and release tags
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
path: plugin
ref: master
fetch-depth: 0

- name: Read pinned Kandev source revision
id: sdk
working-directory: plugin
run: |
set -euo pipefail
sdk_ref="$(cat .kandev-sdk-ref)"
[[ "$sdk_ref" =~ ^[0-9a-f]{40}$ ]]
echo "ref=$sdk_ref" >> "$GITHUB_OUTPUT"

- name: Check out Kandev SDK contract
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
repository: kdlbs/kandev
path: kandev
ref: ${{ steps.sdk.outputs.ref }}
sparse-checkout: |
apps/backend
apps/packages/plugin-sdk

- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: plugin/go.mod
cache-dependency-path: plugin/go.sum

- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24

- name: Compute next release version
id: version
working-directory: plugin
env:
BUMP: ${{ inputs.bump }}
run: |
set -euo pipefail
CURRENT_VERSION="$(sed -nE 's/^version: "([0-9]+\.[0-9]+\.[0-9]+)(-[0-9A-Za-z.-]+)?"$/\1\2/p' manifest.yaml)"
MAKE_VERSION="$(sed -nE 's/^VERSION := ([0-9]+\.[0-9]+\.[0-9]+)(-[0-9A-Za-z.-]+)?$/\1\2/p' Makefile)"
test -n "$CURRENT_VERSION" || { echo "manifest.yaml has no SemVer version." >&2; exit 1; }
VERSION_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'
CURRENT_VERSION="$(sed -nE 's/^version: "([^"]+)"$/\1/p' manifest.yaml)"
MAKE_VERSION="$(sed -nE 's/^VERSION := ([^[:space:]]+)$/\1/p' Makefile)"
printf '%s\n' "$CURRENT_VERSION" | grep -Eq "$VERSION_PATTERN" || { echo "manifest.yaml has an invalid version." >&2; exit 1; }
printf '%s\n' "$MAKE_VERSION" | grep -Eq "$VERSION_PATTERN" || { echo "Makefile has an invalid version." >&2; exit 1; }
test "$CURRENT_VERSION" = "$MAKE_VERSION" || {
echo "manifest.yaml ($CURRENT_VERSION) and Makefile ($MAKE_VERSION) disagree." >&2
exit 1
Expand All @@ -83,14 +123,12 @@ jobs:
esac
TAG="v$NEXT"

! git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null || {
if git rev-parse --verify --quiet "refs/tags/$TAG" >/dev/null; then
echo "Tag already exists locally: $TAG" >&2
exit 1
}
! git ls-remote --exit-code --tags origin "refs/tags/$TAG" >/dev/null || {
echo "Tag already exists on origin: $TAG" >&2
exit 1
}
fi
REMOTE_TAG="$(git ls-remote --tags origin "refs/tags/$TAG")"
test -z "$REMOTE_TAG" || { echo "Tag already exists on origin: $TAG" >&2; exit 1; }

echo "Current version: $CURRENT_VERSION"
echo "Latest release tag: ${LATEST_TAG:-none}"
Expand All @@ -99,12 +137,8 @@ jobs:
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "previous_tag=$LATEST_TAG" >> "$GITHUB_OUTPUT"

- name: Report dry run
if: ${{ inputs.dry_run }}
run: echo "Would commit, tag, and publish ${{ steps.version.outputs.tag }}."

- name: Update release metadata and changelog
if: ${{ !inputs.dry_run }}
- name: Update candidate metadata and changelog
working-directory: plugin
env:
VERSION: ${{ steps.version.outputs.version }}
PREVIOUS_TAG: ${{ steps.version.outputs.previous_tag }}
Expand All @@ -114,7 +148,7 @@ jobs:
sed -i -E "s/^VERSION := [0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$/VERSION := $VERSION/" Makefile
sed -i -E "s/kandev-plugin-kandy-[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?\.tar\.gz/kandev-plugin-kandy-$VERSION.tar.gz/" README.md

RANGE="${PREVIOUS_TAG:+$PREVIOUS_TAG..}HEAD"
if [ -n "$PREVIOUS_TAG" ]; then RANGE="$PREVIOUS_TAG..HEAD"; else RANGE=HEAD; fi
CHANGES="$(git log --no-merges --format='- %s (%h)' "$RANGE")"
test -n "$CHANGES" || CHANGES="- Initial release"
{
Expand All @@ -129,8 +163,33 @@ jobs:
} > CHANGELOG.md.next
mv CHANGELOG.md.next CHANGELOG.md

- name: Commit and tag release metadata
- name: Verify candidate identity and checks
working-directory: plugin
env:
TAG: ${{ steps.version.outputs.tag }}
run: |
set -euo pipefail
sh scripts/verify-release-version.sh "$TAG"
go mod tidy
git diff --exit-code -- go.mod go.sum
make check-format
make vet
make test
make package-host
make package
PACKAGE_FILE="$(make -s package-file)"
sh scripts/verify-package.sh "$PACKAGE_FILE" full
sh scripts/verify-release-version.sh "$TAG" "$PACKAGE_FILE"

- name: Report dry run
if: ${{ inputs.dry_run }}
env:
TAG: ${{ steps.version.outputs.tag }}
run: echo "Candidate $TAG passed checks; no commit, tag, or release was created."

- name: Commit and tag validated release candidate
if: ${{ !inputs.dry_run }}
working-directory: plugin
env:
VERSION: ${{ steps.version.outputs.version }}
TAG: ${{ steps.version.outputs.tag }}
Expand All @@ -145,7 +204,7 @@ jobs:
git push origin "$TAG"

publish:
name: Build and publish release
name: Verify package and publish release
needs: prepare
if: >-
${{
Expand All @@ -154,48 +213,81 @@ jobs:
(github.event_name == 'workflow_dispatch' && !inputs.dry_run && needs.prepare.result == 'success'))
}}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout plugin
- name: Check out release commit
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
path: plugin
ref: ${{ github.event_name == 'push' && github.ref || needs.prepare.outputs.tag }}
fetch-depth: 0

- name: Checkout kandev SDK
- name: Read pinned Kandev source revision
id: sdk
working-directory: plugin
run: |
set -euo pipefail
sdk_ref="$(cat .kandev-sdk-ref)"
[[ "$sdk_ref" =~ ^[0-9a-f]{40}$ ]]
echo "ref=$sdk_ref" >> "$GITHUB_OUTPUT"

- name: Check out Kandev SDK contract
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
repository: kdlbs/kandev
path: kandev
sparse-checkout: apps/backend
ref: ${{ steps.sdk.outputs.ref }}
sparse-checkout: |
apps/backend
apps/packages/plugin-sdk

- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: plugin/go.mod
cache-dependency-path: plugin/go.sum

- name: Verify
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 24

- name: Verify release identity, checks, and package
id: verify
working-directory: plugin
env:
TAG: ${{ github.event_name == 'push' && github.ref_name || needs.prepare.outputs.tag }}
run: |
test -z "$(gofmt -l ./server)" || { echo "gofmt needed:"; gofmt -l ./server; exit 1; }
go vet ./server/...
set -euo pipefail
sh scripts/verify-release-version.sh "$TAG"
go mod tidy
git diff --exit-code -- go.mod go.sum
make check-format
make vet
make test

- name: Package all platforms
working-directory: plugin
run: make package
make package-host
make package
PACKAGE_FILE="$(make -s package-file)"
sh scripts/verify-package.sh "$PACKAGE_FILE" full
sh scripts/verify-release-version.sh "$TAG" "$PACKAGE_FILE"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "package=$PACKAGE_FILE" >> "$GITHUB_OUTPUT"

- name: Generate release checksums
working-directory: plugin
env:
PACKAGE_FILE: ${{ steps.verify.outputs.package }}
run: |
tar -xzf kandev-plugin-kandy-*.tar.gz checksums.txt
sha256sum kandev-plugin-kandy-*.tar.gz >> checksums.txt
set -euo pipefail
tar -xOzf "$PACKAGE_FILE" checksums.txt > checksums.txt
sha256sum "$PACKAGE_FILE" >> checksums.txt

- name: Create GitHub release
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
with:
tag_name: ${{ github.event_name == 'push' && github.ref_name || needs.prepare.outputs.tag }}
tag_name: ${{ steps.verify.outputs.tag }}
files: |
plugin/kandev-plugin-kandy-*.tar.gz
plugin/${{ steps.verify.outputs.package }}
plugin/checksums.txt
generate_release_notes: true
1 change: 1 addition & 0 deletions .kandev-sdk-ref
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
570600439036e81f8e9e1c63f15c4abce8a6c846
Loading
Loading