Skip to content

Commit 80d136e

Browse files
mwojtyczkaCopilot
andauthored
Added optional path to the codegen file for configuring the acceptance tests (#502)
Improved github action for acceptance tests to accept optionally path to the `.codegen.json` for configuring the tests. This makes it possible to run multiple type of tests separately within one code based. **Details:** The github action for acceptance tests `databrickslabs/sandbox/acceptance@acceptance/v0.4.3` uses the first `.codegen.json` file found in the project. For that reason it is currently not possible to run different type of tests separately using this action. With the proposed changes, a path to the codegen can be optionally provided, e.g. ``` - name: Run integration tests uses: databrickslabs/sandbox/acceptance@acceptance/v0.4.4 with: vault_uri: ${{ secrets.VAULT_URI }} timeout: 2h codegen_path: tests/integration/.codegen.json - name: Run e2e tests uses: databrickslabs/sandbox/acceptance@acceptance/v0.4.4 with: vault_uri: ${{ secrets.VAULT_URI }} timeout: 2h codegen_path: tests/e2e/.codegen.json ``` tests/integration/.codegen.json: ``` { "version": { "src/databricks/labs/dqx/__about__.py": "__version__ = \"$VERSION\"" }, "toolchain": { "required": ["python3", "hatch"], "pre_setup": ["hatch env create"], "prepend_path": ".venv/bin", "acceptance_path": "tests/integration" } } ``` tests/e2e/.codegen.json: ``` { "version": { "src/databricks/labs/dqx/__about__.py": "__version__ = \"$VERSION\"" }, "toolchain": { "required": ["python3", "hatch"], "pre_setup": ["hatch env create"], "prepend_path": ".venv/bin", "acceptance_path": "tests/e2e" } } ``` The change is backward compatible so the old behaviour is retained: ``` - name: Run integration tests uses: databrickslabs/sandbox/acceptance@acceptance/v0.4.4 with: vault_uri: ${{ secrets.VAULT_URI }} timeout: 2h ``` This will search for `.codegen.json` in the code and use the first codegen found. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 3d73acb commit 80d136e

File tree

7 files changed

+341
-11
lines changed

7 files changed

+341
-11
lines changed

acceptance/README.md

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,82 @@ sequenceDiagram
5858

5959
## Usage
6060

61-
Add to your `.github/workflows` folder:
61+
Add a file named `acceptance.yml` to the `.github/workflows` folder in your repository.
62+
This file defines a GitHub Actions workflow for running acceptance tests on pull requests.
63+
The workflow sets up the environment, installs dependencies, executes tests, and uploads artifacts for further analysis.
6264

65+
Example `acceptance.yml` for Python projects:
66+
67+
```yaml
68+
name: acceptance
69+
70+
on:
71+
pull_request:
72+
types: [ opened, synchronize, ready_for_review ]
73+
merge_group:
74+
types: [ checks_requested ]
75+
76+
permissions:
77+
id-token: write
78+
contents: read
79+
pull-requests: write
80+
81+
concurrency:
82+
group: ${{ github.workflow }}-${{ github.ref }}
83+
cancel-in-progress: true
84+
85+
jobs:
86+
acceptance:
87+
if: github.event_name == 'pull_request'
88+
runs-on: ubuntu-latest
89+
steps:
90+
- name: Checkout
91+
uses: actions/checkout@v4
92+
93+
- name: Install Python
94+
uses: actions/setup-python@v5
95+
with:
96+
cache: 'pip'
97+
cache-dependency-path: '**/pyproject.toml'
98+
python-version: '3.10'
99+
100+
- name: Install hatch
101+
run: pip install hatch==1.9.4
102+
103+
- name: Run integration tests
104+
uses: databrickslabs/sandbox/acceptance@acceptance/v0.4.4
105+
with:
106+
vault_uri: ${{ secrets.VAULT_URI }}
107+
timeout: 2h
108+
# optional path to codegen file containing configuration for the tests
109+
# by default first `codegen.json` file found in the repository is used
110+
# codegen_path: tests/integration/.codegen.json
111+
env:
112+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
113+
```
114+
115+
The project must include a `.codegen.json` file, which defines the toolchain configuration for the action.
116+
This configuration specifies details such as versioning, required tools, and the paths to acceptance tests.
117+
If a `codegen_path` field is not explicitly provided, the action will automatically search the project for the `.codegen.json` file and use the first one it locates.
118+
119+
Example `.codegen.json`:
120+
```json
121+
{
122+
"version": {
123+
"src/databricks/labs/project_name/__about__.py": "__version__ = \"$VERSION\""
124+
},
125+
"toolchain": {
126+
"required": ["python3", "hatch"],
127+
"pre_setup": ["hatch env create"],
128+
"prepend_path": ".venv/bin",
129+
"acceptance_path": "tests/integration"
130+
}
131+
}
132+
```
133+
134+
Note: if `acceptance_path` is not provided in the `codegen.json`, the action will execute all tests in the project by default.
135+
136+
Example for uploading artifacts to GitHub Actions:
63137
```yaml
64138
name: acceptance
65139

acceptance/action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ inputs:
2424
description: 'Create issues in the repository for failed tests'
2525
required: false
2626
default: false
27+
codegen_path:
28+
description: 'Relative path to the .codegen.json file to use for configuring the acceptance tests'
29+
required: false # by default the first .codegen.json found in the project is used
2730
outputs:
2831
sample:
2932
description: 'Sample output'

acceptance/ecosystem/python.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ func (py *pyContext) Start(script string, reply *localHookServer) chan error {
9191
}
9292

9393
func (r pyTestRunner) prepare(ctx context.Context, redact redaction.Redaction, logfile string) (*pyContext, error) {
94-
tc, err := toolchain.FromFileset(r.files)
94+
codegenPath := env.Get(ctx, "codegen_path")
95+
tc, err := toolchain.FromFileset(r.files, &codegenPath)
9596
if err != nil {
9697
return nil, fmt.Errorf("detect: %w", err)
9798
}

acceptance/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ func (a *acceptance) trigger(ctx context.Context) (*notify.Notification, error)
6868
defer stop()
6969
// make sure that test logs leave their artifacts somewhere we can pickup
7070
ctx = env.Set(ctx, ecosystem.LogDirEnv, artifactDir)
71+
// set codegen path file used for configuring the acceptance tests
72+
codegenPath := a.Action.GetInput("codegen_path")
73+
ctx = env.Set(ctx, "codegen_path", codegenPath)
7174
redact := loaded.Redaction()
7275
report, err := a.runWithTimeout(ctx, redact, directory)
7376
if err != nil {

go-libs/linkdev/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func (r Repo) Retest(ctx context.Context, upstreamFolder string) error {
5858
return fmt.Errorf("fileset: %w", err)
5959
}
6060
// defer cleanup()
61-
tc, err := toolchain.FromFileset(downstreamFiles)
61+
tc, err := toolchain.FromFileset(downstreamFiles, nil)
6262
if err != nil {
6363
return fmt.Errorf("toolchain: %w", err)
6464
}

go-libs/toolchain/toolchain.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,33 @@ import (
1515
"github.com/databrickslabs/sandbox/go-libs/process"
1616
)
1717

18-
var ErrNotExist = fmt.Errorf("no .codegen.json found. %w", fs.ErrNotExist)
18+
func FromFileset(files fileset.FileSet, codegenPath *string) (*Toolchain, error) {
19+
var raw []byte
20+
var err error
1921

20-
func FromFileset(files fileset.FileSet) (*Toolchain, error) {
21-
configs := files.Filter(".codegen.json")
22-
if len(configs) == 0 {
23-
return nil, ErrNotExist
22+
// Helper function to filter files and retrieve raw content
23+
getFileContent := func(filter string) ([]byte, error) {
24+
filteredFiles := files.Filter(filter)
25+
if len(filteredFiles) == 0 {
26+
return nil, fmt.Errorf("file not found in fileset: %s", filter)
27+
}
28+
return filteredFiles[0].Raw()
2429
}
25-
raw, err := configs[0].Raw()
26-
if err != nil {
27-
return nil, fmt.Errorf("read: %w", err)
30+
31+
// Check if codegenPath is provided and retrieve content
32+
if codegenPath != nil && *codegenPath != "" {
33+
raw, err = getFileContent(*codegenPath)
34+
if err != nil {
35+
return nil, fmt.Errorf("provided 'codegen_path' does not exist in the project: %w", fs.ErrNotExist)
36+
}
37+
} else {
38+
raw, err = getFileContent(".codegen.json")
39+
if err != nil {
40+
return nil, fmt.Errorf("no .codegen.json found. %w", fs.ErrNotExist)
41+
}
2842
}
43+
44+
// Unmarshal JSON content into dotCodegen struct
2945
var dc dotCodegen
3046
err = json.Unmarshal(raw, &dc)
3147
if err != nil {

0 commit comments

Comments
 (0)