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
103 changes: 78 additions & 25 deletions .github/workflows/functions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Functions
# To run this workflow's tests locally, see ./hack/test-full.sh

permissions:
id-token: write # Required for signing
id-token: write # Required for signing
contents: read
packages: write
attestations: write
Expand All @@ -18,10 +18,10 @@ on:

# Global version definitions
env:
PYTHON_VERSION: '3.10'
NODE_VERSION: '20'
JAVA_VERSION: '21'
JAVA_DISTRIBUTION: 'temurin'
PYTHON_VERSION: "3.10"
NODE_VERSION: "20"
JAVA_VERSION: "21"
JAVA_DISTRIBUTION: "temurin"

jobs:
# --------
Expand Down Expand Up @@ -53,10 +53,10 @@ jobs:
fail-fast: false
matrix:
os:
- "ubuntu-latest" # x86_64
- "ubuntu-24.04-arm" # ARM64
- "macos-latest" # Intel
- "macos-14" # ARM
- "ubuntu-latest" # x86_64
- "ubuntu-24.04-arm" # ARM64
- "macos-latest" # Intel
- "macos-14" # ARM
- "windows-latest"
runs-on: ${{ matrix.os }}
steps:
Expand Down Expand Up @@ -88,14 +88,14 @@ jobs:
fail-fast: false
matrix:
os:
- "ubuntu-latest" # x86_64
- "ubuntu-24.04-arm" # ARM64
- "macos-latest" # Intel
- "macos-14" # ARM
- "ubuntu-latest" # x86_64
- "ubuntu-24.04-arm" # ARM64
- "macos-latest" # Intel
- "macos-14" # ARM
- "windows-latest"
runs-on: ${{ matrix.os }}
steps:
# Setup
# Setup
- name: Disable CRLF conversion (Windows)
if: runner.os == 'Windows'
run: git config --global core.autocrlf false
Expand Down Expand Up @@ -124,7 +124,6 @@ jobs:
- name: Templates Tests
run: make test-templates


# -----------------
# INTEGRATION TESTS
# -----------------
Expand Down Expand Up @@ -175,7 +174,7 @@ jobs:
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}

# Preserve Cluser Logs
# Preserve Cluster Logs
- name: Dump Cluster Logs
if: always()
run: ./hack/dump-logs.sh cluster_log.txt
Expand Down Expand Up @@ -230,7 +229,7 @@ jobs:
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}

# Preserve Cluser Logs
# Preserve Cluster Logs
- name: Dump Cluster Logs
if: always()
run: ./hack/dump-logs.sh cluster_log.txt
Expand All @@ -252,8 +251,8 @@ jobs:
strategy:
matrix:
os:
- "ubuntu-latest" # x86_64
- "ubuntu-24.04-arm" # ARM64
- "ubuntu-latest" # x86_64
- "ubuntu-24.04-arm" # ARM64
env:
FUNC_CLUSTER_RETRIES: 5
FUNC_E2E_PODMAN: true
Expand Down Expand Up @@ -284,7 +283,7 @@ jobs:
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}

# Preserve Cluser Logs
# Preserve Cluster Logs
- name: Dump Cluster Logs
if: always()
run: ./hack/dump-logs.sh cluster_log.txt
Expand All @@ -296,7 +295,6 @@ jobs:
path: ./cluster_log.txt
retention-days: 7


# -----------------
# E2E RUNTIME TESTS
# -----------------
Expand All @@ -315,9 +313,9 @@ jobs:
- "springboot"
runs-on: ubuntu-latest
env:
FUNC_CLUSTER_RETRIES: 5 # Cluster allocation retries
FUNC_E2E_CLEAN: false # Skip deletes (cluster not reused)
FUNC_E2E_MATRIX: true # Enables the language runtim matrix tests
FUNC_CLUSTER_RETRIES: 5 # Cluster allocation retries
FUNC_E2E_CLEAN: false # Skip deletes (cluster not reused)
FUNC_E2E_MATRIX: true # Enables the language runtime matrix tests
FUNC_E2E_VERBOSE: true
FUNC_E2E_MATRIX_RUNTIMES: ${{ matrix.runtime }}
steps:
Expand Down Expand Up @@ -374,7 +372,7 @@ jobs:
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}

# Preserve Cluser Logs
# Preserve Cluster Logs
- name: Dump Cluster Logs
if: always()
run: ./hack/dump-logs.sh cluster_log.txt
Expand All @@ -386,6 +384,60 @@ jobs:
path: ./cluster_log.txt
retention-days: 7

# -------------------
# E2E CONFIG CI TESTS
# -------------------
test-e2e-config-ci:
name: E2E - Config CI GitHub Workflows
needs: precheck
runs-on: ubuntu-latest
env:
FUNC_CLUSTER_RETRIES: 5
FUNC_E2E_CLEAN: false
FUNC_E2E_VERBOSE: true
steps:
- uses: actions/checkout@v4
- uses: knative/actions/setup-go@main
- uses: endersonmenezes/free-disk-space@v3
with:
remove_android: true
remove_dotnet: true
remove_haskell: true
remove_swap: true
rm_cmd: "rmz"

- name: Install Binaries
run: ./hack/binaries.sh
- name: Allocate Cluster
run: ./hack/cluster.sh
- name: Start Local Registry
run: ./hack/registry.sh
- name: Prepare Images
run: ./hack/images.sh

- name: Run Config CI E2E Tests
run: make test-e2e-config-ci

- uses: codecov/codecov-action@v5
with:
files: ./coverage.txt
flags: e2e-config-ci
fail_ci_if_error: true
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}

# Preserve Cluster Logs
- name: Dump Cluster Logs
if: always()
run: ./hack/dump-logs.sh cluster_log.txt
- name: Archive Cluster Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: cluster-logs-e2e-config-ci
path: ./cluster_log.txt
retention-days: 7

# Build and Publish
build:
name: Build Release
Expand All @@ -396,6 +448,7 @@ jobs:
- test-e2e
- test-e2e-podman
- test-e2e-runtimes
- test-e2e-config-ci
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ __pycache__
AGENTS.override.md
.claude/*.local.*
.claude/pr/*
.claude/plans/*
.roo/*
.mcp*

Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -300,23 +300,29 @@ test-e2e: func-instrumented-bin ## Basic E2E tests (includes core, metadata and
go test -tags e2e -timeout 60m ./e2e -v -run "TestCore_|TestMetadata_|TestRemote_"
go tool covdata textfmt -i=$${FUNC_E2E_GOCOVERDIR:-.coverage} -o coverage.txt


.PHONY: test-e2e-podman
test-e2e-podman: func-instrumented-bin ## Run E2E Podman-specific tests
# see e2e_test.go for available options
FUNC_E2E_PODMAN=true go test -tags e2e -timeout 60m ./e2e -v -run TestPodman_
go tool covdata textfmt -i=$${FUNC_E2E_GOCOVERDIR:-.coverage} -o coverage.txt

.PHONY: test-e2e-matrix
test-e2e-matrix: func-instrumented-bin ## Basic E2E tests (includes core, metadata and remote tests)
# Runtime and other options can be configured using the FUNC_E2E_* environment variables. see e2e_test.go
FUNC_E2E_MATRIX=true go test -tags e2e -timeout 120m ./e2e -v -run TestMatrix_
go tool covdata textfmt -i=$${FUNC_E2E_GOCOVERDIR:-.coverage} -o coverage.txt

.PHONY: test-e2e-config-ci
test-e2e-config-ci: func-instrumented-bin ## CI tests for generated GitHub Workflows
# Runtime and other options can be configured using the FUNC_E2E_* environment variables. see e2e_test.go
FUNC_E2E_CONFIG_CI=true go test -tags e2e -timeout 120m ./e2e -v -run TestConfigCI_
go tool covdata textfmt -i=$${FUNC_E2E_GOCOVERDIR:-.coverage} -o coverage.txt

.PHONY: test-full
test-full: func-instrumented-bin ## Run full test suite with all checks enabled
./hack/test-full.sh

.PHONY: test-full-logged
test-full-logged: func-instrumented-bin ## Run full test and log with timestamps (requires python)
./hack/test-full.sh 2>&1 | python -u -c "import sys; from datetime import datetime; [print(f'[{datetime.now().strftime(\"%H:%M:%S\")}] {line}', end='', flush=True) for line in sys.stdin]" | tee ./test-full.log
@echo 'πŸŽ‰ Full Test Complete. Log stored in test-full.log'
Expand Down
4 changes: 2 additions & 2 deletions cmd/ci/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package ci

import "fmt"

func runner(conf CIConfig) string {
if conf.SelfHostedRunner() {
func determineRunner(selfHosted bool) string {
if selfHosted {
return "self-hosted"
}
return "ubuntu-latest"
Expand Down
66 changes: 54 additions & 12 deletions cmd/ci/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ const (
type CIConfig struct {
githubWorkflowDir,
githubWorkflowFilename,
path,
branch,
workflowName,
kubeconfigSecret,
Expand All @@ -83,9 +82,13 @@ type CIConfig struct {
testStep,
force,
verbose bool
fnRuntime,
fnRoot,
fnBuilder string
}

func NewCIConfig(
fnLoader common.FunctionLoader,
currentBranch common.CurrentBranchFunc,
workingDir common.WorkDirFunc,
workflowNameExplicit bool,
Expand All @@ -106,10 +109,20 @@ func NewCIConfig(

workflowName := resolveWorkflowName(workflowNameExplicit)

f, err := fnLoader.Load(path)
if err != nil {
return CIConfig{}, err
}

remoteBuild := viper.GetBool(RemoteBuildFlag)
fnBuilder, err := resolveBuilder(f.Runtime, remoteBuild)
if err != nil {
return CIConfig{}, err
}

return CIConfig{
githubWorkflowDir: DefaultGitHubWorkflowDir,
githubWorkflowFilename: DefaultGitHubWorkflowFilename,
path: path,
branch: branch,
workflowName: workflowName,
kubeconfigSecret: viper.GetString(KubeconfigSecretNameFlag),
Expand All @@ -119,18 +132,24 @@ func NewCIConfig(
registryUrlVar: viper.GetString(RegistryUrlVariableNameFlag),
registryLogin: viper.GetBool(RegistryLoginFlag),
selfHostedRunner: viper.GetBool(SelfHostedRunnerFlag),
remoteBuild: viper.GetBool(RemoteBuildFlag),
remoteBuild: remoteBuild,
workflowDispatch: viper.GetBool(WorkflowDispatchFlag),
testStep: viper.GetBool(TestStepFlag),
force: viper.GetBool(ForceFlag),
verbose: viper.GetBool(VerboseFlag),
fnRuntime: f.Runtime,
fnRoot: f.Root,
fnBuilder: fnBuilder,
}, nil
}

func resolvePlatform() error {
platform := viper.GetString(PlatformFlag)
if platform == "" {
return fmt.Errorf("platform must not be empty, supported: %s", DefaultPlatform)
}
if strings.ToLower(platform) != DefaultPlatform {
return fmt.Errorf("%s support is not implemented", platform)
return fmt.Errorf("%s support is not implemented, supported: %s", platform, DefaultPlatform)
}

return nil
Expand Down Expand Up @@ -177,22 +196,37 @@ func resolveWorkflowName(explicit bool) string {
return DefaultWorkflowName
}

func (cc CIConfig) fnGitHubWorkflowDir(fnRoot string) string {
return filepath.Join(fnRoot, cc.githubWorkflowDir)
func resolveBuilder(runtime string, remote bool) (string, error) {
switch runtime {
case "go":
if remote {
return "pack", nil
}
return "host", nil

case "node", "typescript", "rust", "quarkus", "springboot":
return "pack", nil

case "python":
if remote {
return "s2i", nil
}
return "host", nil

default:
return "", fmt.Errorf("no builder support for runtime: %s", runtime)
}
}

func (cc CIConfig) FnGitHubWorkflowFilepath(fnRoot string) string {
return filepath.Join(cc.fnGitHubWorkflowDir(fnRoot), cc.githubWorkflowFilename)
func (cc CIConfig) FnGitHubWorkflowFilepath() string {
fnGitHubWorkflowDir := filepath.Join(cc.fnRoot, cc.githubWorkflowDir)
return filepath.Join(fnGitHubWorkflowDir, cc.githubWorkflowFilename)
}

func (cc CIConfig) OutputPath() string {
return filepath.Join(cc.githubWorkflowDir, cc.githubWorkflowFilename)
}

func (cc CIConfig) Path() string {
return cc.path
}

func (cc CIConfig) Branch() string {
return cc.branch
}
Expand Down Expand Up @@ -248,3 +282,11 @@ func (cc CIConfig) Force() bool {
func (cc CIConfig) Verbose() bool {
return cc.verbose
}

func (cc CIConfig) FnRuntime() string {
return cc.fnRuntime
}

func (cc CIConfig) FnBuilder() string {
return cc.fnBuilder
}
Loading
Loading