Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2a821f6
Moving sfdx-project.json into packages/ directories
jasonsiders Aug 3, 2025
6ed0550
adding temporary sfdx-project.json file for deployment purposes
jasonsiders Aug 3, 2025
8ca55bf
experimenting with package structures
jasonsiders Aug 3, 2025
6201912
checkpoint
jasonsiders Aug 3, 2025
32bbde0
checkpoint
jasonsiders Aug 4, 2025
f2d57c6
contd.
jasonsiders Aug 4, 2025
42b6a04
first draft
jasonsiders Aug 4, 2025
27b6148
reworking package input
jasonsiders Aug 4, 2025
562b4a3
removing pwd
jasonsiders Aug 4, 2025
b069f37
fixing permissions
jasonsiders Aug 4, 2025
c81af33
Requested new package version v3.0.0.NEXT
jasonsiders Aug 4, 2025
808798b
adding prettier
jasonsiders Aug 4, 2025
3e52857
tweaking prettier action
jasonsiders Aug 4, 2025
4e3be69
contd.
jasonsiders Aug 4, 2025
3e46c36
contd.
jasonsiders Aug 4, 2025
073fefd
contd.
jasonsiders Aug 4, 2025
2398b41
running prettier
jasonsiders Aug 4, 2025
f989089
not testing actually creating package versions for right now
jasonsiders Aug 4, 2025
090e489
contd.
jasonsiders Aug 4, 2025
0726f21
troubleshooting node
jasonsiders Aug 4, 2025
c2c0343
fix package.json
jasonsiders Aug 4, 2025
680e74f
Packaged new unlocked version v3.0.0.NEXT
jasonsiders Aug 4, 2025
259b17f
alternate approach
jasonsiders Aug 4, 2025
a3d2c74
cleanup
jasonsiders Aug 4, 2025
ad0008e
renaming steps
jasonsiders Aug 4, 2025
4117dd7
use latest version of node
jasonsiders Aug 4, 2025
446e16f
fixing commit message and package version name
jasonsiders Aug 4, 2025
5addd99
resetting package versions
jasonsiders Aug 4, 2025
a59e09d
Packaged new unlocked version vv2.5.2
jasonsiders Aug 4, 2025
b29f2f0
fixing commit message
jasonsiders Aug 4, 2025
712dbec
Merge branch 'devops/packaging-action' of https://github.com/jasonsid…
jasonsiders Aug 4, 2025
5c7e990
removing temporary skip
jasonsiders Aug 4, 2025
49a9276
adding timeout-minutes
jasonsiders Aug 4, 2025
2115874
creating release action
jasonsiders Aug 4, 2025
7da4a69
solidifying release action
jasonsiders Aug 4, 2025
3cddc1e
cleanup
jasonsiders Aug 4, 2025
090eae5
cleaning up project files
jasonsiders Aug 4, 2025
ddfcb1f
adding input validation
jasonsiders Aug 4, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
id-token: write

steps:
- name: Checkout repository
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
Expand Down
136 changes: 109 additions & 27 deletions .github/workflows/packaging.yml
Original file line number Diff line number Diff line change
@@ -1,43 +1,77 @@
name: Packaging

on:
push:
branches:
- main
paths:
- "force-app/**"
workflow_call:
inputs:
package:
description: Package Directory ("managed" or "unlocked")
default: unlocked
required: false
type: string
version:
description: Version Number (#.#.#)
required: false
type: string
outputs:
version-id:
description: "Package Version ID"
value: ${{ jobs.create-package-version.outputs.version-id }}
workflow_dispatch:
inputs:
version-number:
description: "Version Number (#.#.#): Do not include the 'v'"
package:
description: Package Directory ("managed" or "unlocked")
default: unlocked
required: false

concurrency:
group: packaging-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
PACKAGE_ALIAS: "apex-database-layer"
type: string
version:
description: Version Number (#.#.#)
required: false
type: string

jobs:
create-unlocked-package:
name: Create Unlocked Package Version
create-package-version:
name: Create Package Version
outputs:
version-id: ${{ steps.create-package.outputs.version-id }}
permissions:
contents: write
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
fetch-depth: 0
token: ${{ github.token }}
node-version: lts/*
cache: "npm"

- name: Setup NPM
shell: bash
run: npm ci

- name: Setup SF CLI
uses: ./.github/actions/setup-sf-cli

- name: Switch Package Context
shell: bash
run: |
# Validate package directory and sfdx-project.json file exist
if [[ ! -f "packages/${{ inputs.package }}/sfdx-project.json" ]]; then
echo "ERROR: 'packages/${{ inputs.package }}/sfdx-project.json' not found"
exit 1
fi
# Swap the sfdx-project.json file for the one listed in the package directory
mkdir -p tmp
mv sfdx-project.json tmp/
cp "packages/${{ inputs.package }}/sfdx-project.json" .

- name: Get Version Number
id: get-version
env:
INPUT_VERSION: ${{ inputs.version-number }}
INPUT_VERSION: ${{ inputs.version }}
shell: bash
run: |
# If an input version number isn't set, use the current version defined in sfdx-project.json:
if [[ -z "$INPUT_VERSION" ]]; then
Expand All @@ -47,16 +81,33 @@ jobs:
VERSION_NUMBER="${INPUT_VERSION}.NEXT"
echo "Using specified version number: $VERSION_NUMBER"
fi
# Create version name by removing .NEXT suffix
VERSION_NAME="v${VERSION_NUMBER%.NEXT}"
echo "version-number=$VERSION_NUMBER" >> "$GITHUB_OUTPUT"
echo "version-name=$VERSION_NAME" >> "$GITHUB_OUTPUT"

- name: Setup SF CLI
uses: ./.github/actions/setup-sf-cli
- name: Update Package Version
shell: bash
env:
VERSION_NUMBER: ${{ steps.get-version.outputs.version-number }}
VERSION_NAME: ${{ steps.get-version.outputs.version-name }}
run: |
# Update the version number/name in both project files:
# Update the package file
jq --arg vn "$VERSION_NUMBER" --arg vnm "$VERSION_NAME" \
'.packageDirectories[0].versionNumber = $vn | .packageDirectories[0].versionName = $vnm' \
sfdx-project.json > sfdx-project.json.tmp && mv sfdx-project.json.tmp sfdx-project.json
# Update version in the original root file
jq --arg vn "$VERSION_NUMBER" --arg vnm "$VERSION_NAME" \
'.packageDirectories[0].versionNumber = $vn | .packageDirectories[0].versionName = $vnm' \
tmp/sfdx-project.json > tmp/sfdx-project.json.tmp && mv tmp/sfdx-project.json.tmp tmp/sfdx-project.json

- name: Authenticate Devhub
env:
CLIENT_ID: ${{ secrets.SALESFORCE_CONSUMER_KEY }}
JWT_KEY: ${{ secrets.SALESFORCE_JWT_KEY }}
USERNAME: ${{ secrets.SALESFORCE_DEVHUB_USERNAME }}
shell: bash
run: |
set -euo pipefail
echo "${JWT_KEY}" > server.key
Expand All @@ -68,18 +119,49 @@ jobs:
trap 'rm -f server.key' EXIT

- name: Create New Package Version
id: create-package
env:
VERSION_NUMBER: ${{ steps.get-version.outputs.version-number }}
WIKI_URL: "https://github.com/jasonsiders/apex-database-layer/wiki"
shell: bash
run: |
sf package version create \
# Get package alias from sfdx-project.json
PACKAGE_ALIAS=$(jq -r '.packageDirectories[] | select(.default == true) | .package' sfdx-project.json)
echo "Creating package version for: $PACKAGE_ALIAS"
# Create package version and capture JSON output
RESULT=$(sf package version create \
--code-coverage \
--installation-key-bypass \
--json \
--package "$PACKAGE_ALIAS" \
--version-number "$VERSION_NUMBER" \
--wait 29
--post-install-url "$WIKI_URL" \
--wait 29)
echo "$RESULT"
# Extract SubscriberPackageVersionId from JSON response
VERSION_ID=$(echo "$RESULT" | jq -r '.result.SubscriberPackageVersionId')
echo "Package Version ID: $VERSION_ID"
echo "version-id=$VERSION_ID" >> "$GITHUB_OUTPUT"
if [[ -z "$VERSION_ID" || "$VERSION_ID" == "null" ]]; then
echo "ERROR: Missing Package Version ID"
exit 1
fi

- name: Run Prettier
shell: bash
run: |
# Run Prettier on sfdx-project.json files, since packaging overwrites spacing:
npx prettier -w sfdx-project.json
npx prettier -w tmp/sfdx-project.json

- name: Cleanup
shell: bash
run: |
# Relocate root & package's project files back to their original location
cp sfdx-project.json "packages/${{ inputs.package }}/"
mv tmp/sfdx-project.json .
rm -rf tmp/

- name: Tag & Commit Changes
uses: "stefanzweifel/git-auto-commit-action@v6"
with:
commit_message: "Requested new package version v${{ steps.get-version.outputs.version-number }}"
tagging_message: "v${{ steps.get-version.outputs.version-number }}"
commit_message: "Packaged new ${{ inputs.package }} version ${{ steps.get-version.outputs.version-name }}"
148 changes: 148 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: Release New Version

on:
push:
branches:
- main
paths:
- force-app
workflow_dispatch:
inputs:
version:
description: Version Number (#.#.#)
required: false
type: string

concurrency:
# Queue releases to prevent version collisions - don't cancel, let them run sequentially
group: release-${{ github.repository }}
cancel-in-progress: false

jobs:
versioning:
name: Versioning
outputs:
version-number: ${{ steps.determine-version.outputs.version-number }}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 2

- name: Did sfdx-project.json Change?
if: ${{ github.event_name == 'push' }}
id: check-changes
run: |
# Check if sfdx-project.json was modified in the latest commit
if git diff --name-only HEAD~1 HEAD | grep -q "^sfdx-project.json$"; then
echo "sfdx-project.json was modified"
echo "changed=true" >> "$GITHUB_OUTPUT"
else
echo "sfdx-project.json was not modified"
echo "changed=false" >> "$GITHUB_OUTPUT"
fi

- name: Determine Version
id: determine-version
run: |
# Get current version from sfdx-project.json:
CURRENT_VERSION=$(jq -r '.packageDirectories[] | select(.default == true) | .versionNumber' sfdx-project.json | sed 's/\.NEXT$//')
echo "Current version: $CURRENT_VERSION"
if [[ "${{ github.event_name }}" == "push" && "${{ steps.check-changes.outputs.changed }}" == "false" ]]; then
# 1. On push AND sfdx-project.json was NOT updated - increment the version
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR=${VERSION_PARTS[0]}
MINOR=${VERSION_PARTS[1]}
PATCH=${VERSION_PARTS[2]}
NEW_PATCH=$((PATCH + 1))
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"
echo "Auto-incremented version to: $NEW_VERSION"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ inputs.version }}" ]]; then
# 2. On workflow dispatch & a version input is provided - use the version input
NEW_VERSION="${{ inputs.version }}"
echo "Using input version: $NEW_VERSION"
else
# 3. Else - use the existing version number
NEW_VERSION="$CURRENT_VERSION"
echo "Using current version: $NEW_VERSION"
fi
echo "version-number=$NEW_VERSION" >> "$GITHUB_OUTPUT"

- name: Validate Package Version
env:
VERSION: ${{ steps.determine-version.outputs.version-number }}
run: |
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "ERROR: Version '$VERSION' is not valid semver format. Expected 'MAJOR.MINOR.PATCH'"
exit 1
fi

create-managed-package-version:
name: Create Managed Package Version
needs: versioning
uses: ./.github/workflows/packaging.yml
secrets: inherit
with:
package: managed
version: ${{ needs.versioning.outputs.version-number }}

create-unlocked-package-version:
name: Create Unlocked Package Version
needs: [versioning, create-managed-package-version]
uses: ./.github/workflows/packaging.yml
secrets: inherit
with:
package: unlocked
version: ${{ needs.versioning.outputs.version-number }}

create-release:
name: Create Release
needs: [versioning, create-managed-package-version, create-unlocked-package-version]
if: ${{ success() && needs.create-managed-package-version.outputs.version-id != '' && needs.create-unlocked-package-version.outputs.version-id != '' }}
permissions:
contents: write
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Draft Release Body
id: release-body
run: |
VERSION="${{ needs.versioning.outputs.version-number }}"
MANAGED_ID="${{ needs.create-managed-package-version.outputs.version-id }}"
UNLOCKED_ID="${{ needs.create-unlocked-package-version.outputs.version-id }}"
# Start building release body
{
echo "## Installation"
echo ""
echo "### Managed Package"
echo "**Package Version**: \`$MANAGED_ID\`"
echo "\`\`\`bash"
echo "sf package install --package $MANAGED_ID --wait 20"
echo "\`\`\`"
echo ""
echo "### Unlocked Package"
echo "**Package Version**: \`$UNLOCKED_ID\`"
echo "\`\`\`bash"
echo "sf package install --package $UNLOCKED_ID --wait 20"
echo "\`\`\`"
echo ""
} > release_body.md

# Set as output for next step
{
echo 'body<<EOF'
cat release_body.md
echo 'EOF'
} >> "$GITHUB_OUTPUT"

- name: Create Release
id: create_release
uses: softprops/action-gh-release@v2.3.2
with:
body: ${{ steps.release-body.outputs.body }}
generate_release_notes: true
make_latest: true
tag_name: v${{ needs.versioning.outputs.version-number }}
token: ${{ secrets.GITHUB_TOKEN }}
5 changes: 1 addition & 4 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run precommit
npm test
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"lint": "eslint **/{aura,lwc}/**/*.js",
"test": "npm run test:unit",
"test:unit": "sfdx-lwc-jest --passWithNoTests",
"test:unit": "sfdx-lwc-jest -- --passWithNoTests",
"test:unit:watch": "sfdx-lwc-jest --watch",
"test:unit:debug": "sfdx-lwc-jest --debug",
"test:unit:coverage": "sfdx-lwc-jest --coverage",
Expand Down
19 changes: 19 additions & 0 deletions packages/managed/sfdx-project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"packageDirectories": [
{
"path": "force-app",
"default": true,
"package": "apex-database-layer-managed",
"versionName": "v3.0.0",
"versionNumber": "3.0.0.NEXT",
"versionDescription": "Introducing managed package"
}
],
"name": "Apex Database Layer (Managed)",
"namespace": "apxsp",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "64.0",
"packageAliases": {
"apex-database-layer-managed": "0HoDn0000010wCnKAI"
}
}
Loading