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
267 changes: 267 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@

name: CI

on:
push:
branches:
- main
- release-*
pull_request: {}
workflow_dispatch:
inputs:
version:
description: Package version (e.g. v0.1.0)
required: false

env:
NODE_VERSION: "24"

# These environment variables are important to the Crossplane CLI install.sh
# script. They determine what version it installs.
XP_CHANNEL: stable
XP_VERSION: current

# This CI job will automatically push new builds to xpkg.upbound.io if the
# XPKG_ACCESS_ID and XPKG_TOKEN secrets are set in the GitHub repository (or
# organization) settings. Create a token at https://accounts.upbound.io.
XPKG_ACCESS_ID: ${{ secrets.XPKG_ACCESS_ID }}

# The OCI/Docker Repository to push our images to.
# By Default this points to Github Package Registry.
XPKG_REPO: ghcr.io/${{ github.repository_owner }}

# Names for the Configuration and corresponding Function Packages
XPKG_NAME: ${{ github.event.repository.name }}
# The function package
XPKG_FN_NAME: ${{ github.event.repository.name }}-function

jobs:
# Compute the package version once and share it with all jobs that need it
version:
runs-on: &default-runner ubuntu-24.04
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
fetch-depth: 0

- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{env.NODE_VERSION}}

# If a version wasn't explicitly passed as a workflow_dispatch input we
# default to version $(npm pkg get version)-<git-commit-date>-<git-short-sha>, for example
# v0.1.1-20231101115142-1091066df799. This is a simple implementation of
# Go's pseudo-versions: https://go.dev/ref/mod#pseudo-versions.
- name: Compute Package Version
id: version
run: |
if [ -n "${{ inputs.version }}" ]; then
VERSION="${{ inputs.version }}"
else
VERSION="v$(npm pkg get version | tr -d '"')-$(date -d@$(git show -s --format=%ct) +%Y%m%d%H%M%S)-$(git rev-parse --short=12 HEAD)"
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "Computed version: ${VERSION}"

lint:
runs-on: *default-runner

steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Install
uses: actions/setup-node@v6
with:
node-version: ${{env.NODE_VERSION}}
- run: npm ci

- name: Lint
run: npm run lint

test:
runs-on: *default-runner

steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Install
uses: actions/setup-node@v6
with:
node-version: ${{env.NODE_VERSION}}
- run: npm ci

- name: test
run: npm test

check-types:
runs-on: *default-runner

steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{env.NODE_VERSION}}
- run: npm ci

- name: Check Types
run: npm run check-types

# Build the OCI image for the configuration.
build-configuration-package:
runs-on: *default-runner
needs:
- version
- check-types

outputs:
configuration_xpkg: ${{ steps.save-configuration-package-name.outputs.configuration_xpkg }}

steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Setup the Crossplane CLI
uses: crossplane-contrib/setup-crossplane-action@cb8aac3f1246b19f101e7f85fd0a38623b4d5ad3 #v0.1.1
with:
version: ${{env.XP_VERSION}}

- name: Build the Configuration Package
run: crossplane xpkg build --package-root="package" --examples-root="examples" -o ${{env.XPKG_NAME}}-${{needs.version.outputs.version}}.xpkg

- name: Save the Configuration package name
id: save-configuration-package-name

run: |
CONFIGURATION_XPKG=${{env.XPKG_NAME}}-${{needs.version.outputs.version}}.xpkg
echo "configuration_xpkg=${CONFIGURATION_XPKG}" >> $GITHUB_OUTPUT
echo "Configuration Package: ${CONFIGURATION_XPKG}"

- name: Upload Single-Platform Package
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: configuration-xpkg
path: ${{env.XPKG_NAME}}-${{needs.version.outputs.version}}.xpkg
if-no-files-found: error
retention-days: 1

# Build OCI images for the function
build-function-packages:
needs:
- version
- check-types
runs-on: *default-runner
strategy:
fail-fast: true
matrix:
arch:
- amd64
- arm64

steps:
- name: Setup QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
with:
platforms: all

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

# We ask Docker to use GitHub Action's native caching support to speed up
# the build, per https://docs.docker.com/build/cache/backends/gha/.
- name: Build Runtime
id: image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
with:
context: .
platforms: linux/${{ matrix.arch }}
cache-from: type=gha
cache-to: type=gha,mode=max
target: image
outputs: type=docker,dest=${{env.XPKG_FN_NAME}}-runtime-${{ matrix.arch }}-${{needs.version.outputs.version}}.tar

- name: Setup the Crossplane CLI
uses: crossplane-contrib/setup-crossplane-action@cb8aac3f1246b19f101e7f85fd0a38623b4d5ad3 #v0.1.1
with:
version: ${{env.XP_VERSION}}

- name: Build Package
run: |
crossplane xpkg build --embed-runtime-image-tarball=${{env.XPKG_FN_NAME}}-runtime-${{ matrix.arch }}-${{needs.version.outputs.version}}.tar \
--package-root="package-function" \
-o ${{env.XPKG_FN_NAME}}-${{ matrix.arch }}-${{needs.version.outputs.version}}.xpkg

- name: Upload Single-Platform Package
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: function-package-${{ matrix.arch }}
path: ${{env.XPKG_FN_NAME}}-${{ matrix.arch }}-${{needs.version.outputs.version}}.xpkg
if-no-files-found: error
retention-days: 1

# This job downloads the single-platform packages built by the build job, and
# pushes them as a multi-platform package. We only push the package it the
# XPKG_ACCESS_ID and XPKG_TOKEN secrets were provided.
push:
runs-on: *default-runner
needs:
- version
- lint
- test
- build-function-packages
- build-configuration-package
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6

- name: Download Single-Platform Packages
uses: actions/download-artifact@v6
with:
path: .
merge-multiple: true
pattern: "!*.dockerbuild" # This gets uploaded by docker/build-push-action but must be skipped: https://github.com/actions/toolkit/pull/1874

- name: Setup the Crossplane CLI
uses: crossplane-contrib/setup-crossplane-action@cb8aac3f1246b19f101e7f85fd0a38623b4d5ad3 #v0.1.1
with:
version: ${{env.XP_VERSION}}

- name: Login to Upbound
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef #v3.6.0
if: env.XPKG_ACCESS_ID != ''
with:
registry: xpkg.upbound.io
username: ${{ secrets.XPKG_ACCESS_ID }}
password: ${{ secrets.XPKG_TOKEN }}

- name: Push Multi-Platform Function Packages to Upbound
if: env.XPKG_ACCESS_ID != ''
run: |
FN_XPKG_FILES=$(echo "${{env.XPKG_FN_NAME}}"-*-${{needs.version.outputs.version}}.xpkg | tr ' ' ',')
if [ -z "${FN_XPKG_FILES}" ] || [ "${FN_XPKG_FILES}" = "${{env.XPKG_FN_NAME}}-*-${{needs.version.outputs.version}}.xpkg" ]; then
echo "Error: No xpkg files found matching pattern"
exit 1
fi
crossplane --verbose xpkg push --package-files ${FN_XPKG_FILES} ${{env.XPKG_REPO}}/${{env.XPKG_FN_NAME}}:${{needs.version.outputs.version}}

- name: Push Configuration Package to Upbound
if: env.XPKG_ACCESS_ID != ''
run: |
CONF_XPKG_FILE="${{env.XPKG_NAME}}-${{needs.version.outputs.version}}.xpkg"
if [ ! -f "${CONF_XPKG_FILE}" ]; then
echo "Error: Configuration package ${CONF_XPKG_FILE} not found"
exit 1
fi
crossplane --verbose xpkg push --package-files ${CONF_XPKG_FILE} ${{env.XPKG_REPO}}/${{env.XPKG_NAME}}:${{needs.version.outputs.version}}

26 changes: 26 additions & 0 deletions .github/workflows/tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Tag

on:
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g. v0.1.0)'
required: true
message:
description: 'Tag message'
required: true

jobs:
create-tag:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Create Tag
uses: negz/create-tag@39bae1e0932567a58c20dea5a1a0d18358503320 # v1
with:
version: ${{ github.event.inputs.version }}
message: ${{ github.event.inputs.message }}
token: ${{ secrets.GITHUB_TOKEN }}
14 changes: 14 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Build output
dist/
build/

# Dependencies
node_modules/

# Test coverage
coverage/

# Package files
package-lock.json
pnpm-lock.yaml
yarn.lock
11 changes: 11 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always",
"bracketSpacing": true,
"endOfLine": "lf"
}
7 changes: 2 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
FROM node:25 AS build-env
COPY . /function
COPY function-sdk-typescript-0.1.0.tgz /function/function-sdk-typescript-0.1.0.tgz
WORKDIR /function

# This is temporary until the SDK is public
RUN npm install function-sdk-typescript-0.1.0.tgz
RUN npm ci --no-fund --only=production && npm cache clean --force
RUN npm run tsc

FROM gcr.io/distroless/nodejs24-debian12 AS image
COPY --from=build-env /function /function
EXPOSE 9443
#USER nonroot:nonroot
WORKDIR /function
CMD ["dist/main.js"]
ENTRYPOINT ["/nodejs/bin/node", "dist/main.js"]
CMD []
Loading