Skip to content

Commit 9318ed2

Browse files
committed
test(actions): add tests for deployment environments
1 parent 7164c50 commit 9318ed2

3 files changed

Lines changed: 544 additions & 0 deletions

File tree

models/actions/environment_test.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
// Copyright 2026 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package actions
5+
6+
import (
7+
"testing"
8+
9+
"gitea.dev/models/db"
10+
"gitea.dev/models/unittest"
11+
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
func TestEnvironmentMatchesBranch(t *testing.T) {
17+
tests := []struct {
18+
name string
19+
protectedBranches string
20+
ref string
21+
want bool
22+
}{
23+
{
24+
name: "empty policy allows everything",
25+
protectedBranches: "",
26+
ref: "refs/heads/feature",
27+
want: true,
28+
},
29+
{
30+
name: "exact match",
31+
protectedBranches: "main",
32+
ref: "refs/heads/main",
33+
want: true,
34+
},
35+
{
36+
name: "no match",
37+
protectedBranches: "main",
38+
ref: "refs/heads/develop",
39+
want: false,
40+
},
41+
{
42+
name: "glob wildcard matches",
43+
protectedBranches: "release/*",
44+
ref: "refs/heads/release/1.0",
45+
want: true,
46+
},
47+
{
48+
name: "glob wildcard no match",
49+
protectedBranches: "release/*",
50+
ref: "refs/heads/main",
51+
want: false,
52+
},
53+
{
54+
name: "multiple patterns comma-separated, first matches",
55+
protectedBranches: "main, staging",
56+
ref: "refs/heads/main",
57+
want: true,
58+
},
59+
{
60+
name: "multiple patterns comma-separated, second matches",
61+
protectedBranches: "main, staging",
62+
ref: "refs/heads/staging",
63+
want: true,
64+
},
65+
{
66+
name: "multiple patterns, none match",
67+
protectedBranches: "main, staging",
68+
ref: "refs/heads/feature/x",
69+
want: false,
70+
},
71+
{
72+
name: "glob and exact combo",
73+
protectedBranches: "main, release/*",
74+
ref: "refs/heads/release/2.0",
75+
want: true,
76+
},
77+
{
78+
name: "ref without refs/heads/ prefix",
79+
protectedBranches: "main",
80+
ref: "main",
81+
want: true,
82+
},
83+
}
84+
85+
for _, tt := range tests {
86+
t.Run(tt.name, func(t *testing.T) {
87+
env := &ActionEnvironment{ProtectedBranches: tt.protectedBranches}
88+
assert.Equal(t, tt.want, env.MatchesBranch(tt.ref))
89+
})
90+
}
91+
}
92+
93+
func TestEnvironmentCRUD(t *testing.T) {
94+
require.NoError(t, unittest.PrepareTestDatabase())
95+
ctx := t.Context()
96+
97+
const repoID int64 = 4
98+
99+
t.Run("Insert and Get", func(t *testing.T) {
100+
env, err := InsertEnvironment(ctx, repoID, "production", "main")
101+
require.NoError(t, err)
102+
assert.Positive(t, env.ID)
103+
assert.Equal(t, "production", env.Name)
104+
assert.Equal(t, "main", env.ProtectedBranches)
105+
106+
got, err := GetEnvironmentByRepoAndName(ctx, repoID, "production")
107+
require.NoError(t, err)
108+
assert.Equal(t, env.ID, got.ID)
109+
110+
gotByID, err := GetEnvironmentByID(ctx, env.ID)
111+
require.NoError(t, err)
112+
assert.Equal(t, "production", gotByID.Name)
113+
})
114+
115+
t.Run("Update", func(t *testing.T) {
116+
env, err := InsertEnvironment(ctx, repoID, "staging", "develop")
117+
require.NoError(t, err)
118+
119+
env.ProtectedBranches = "staging,develop"
120+
require.NoError(t, UpdateEnvironment(ctx, env))
121+
122+
got, err := GetEnvironmentByID(ctx, env.ID)
123+
require.NoError(t, err)
124+
assert.Equal(t, "staging,develop", got.ProtectedBranches)
125+
})
126+
127+
t.Run("Delete cascades secrets and variables", func(t *testing.T) {
128+
env, err := InsertEnvironment(ctx, repoID, "preview", "")
129+
require.NoError(t, err)
130+
131+
// insert a secret and a variable scoped to the env
132+
secret := &ActionEnvironmentSecret{
133+
RepoID: repoID,
134+
EnvironmentID: env.ID,
135+
Name: "TOKEN",
136+
Data: "encrypted",
137+
}
138+
require.NoError(t, db.Insert(ctx, secret))
139+
variable := &ActionEnvironmentVariable{
140+
RepoID: repoID,
141+
EnvironmentID: env.ID,
142+
Name: "APP_URL",
143+
Data: "https://preview.example.com",
144+
}
145+
require.NoError(t, db.Insert(ctx, variable))
146+
147+
require.NoError(t, DeleteEnvironment(ctx, repoID, env.ID))
148+
149+
// environment should be gone
150+
_, err = GetEnvironmentByID(ctx, env.ID)
151+
require.ErrorIs(t, err, ErrEnvironmentNotFound{})
152+
153+
// secrets and variables should be cascaded
154+
secrets, err := db.Find[ActionEnvironmentSecret](ctx, FindEnvSecretsOptions{
155+
RepoID: repoID,
156+
EnvironmentID: env.ID,
157+
})
158+
require.NoError(t, err)
159+
assert.Empty(t, secrets)
160+
161+
vars, err := db.Find[ActionEnvironmentVariable](ctx, FindEnvVariablesOptions{
162+
RepoID: repoID,
163+
EnvironmentID: env.ID,
164+
})
165+
require.NoError(t, err)
166+
assert.Empty(t, vars)
167+
})
168+
169+
t.Run("NotFound error for unknown env", func(t *testing.T) {
170+
_, err := GetEnvironmentByRepoAndName(ctx, repoID, "nonexistent")
171+
require.ErrorIs(t, err, ErrEnvironmentNotFound{Name: "nonexistent"})
172+
})
173+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2026 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package jobparser
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestDeploymentEnvironmentName(t *testing.T) {
14+
tests := []struct {
15+
name string
16+
yaml string
17+
wantEnv string
18+
}{
19+
{
20+
name: "no environment key",
21+
yaml: "on: push\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo hi\n",
22+
wantEnv: "",
23+
},
24+
{
25+
name: "scalar string environment",
26+
yaml: "on: push\njobs:\n deploy:\n runs-on: ubuntu-latest\n environment: production\n steps:\n - run: echo hi\n",
27+
wantEnv: "production",
28+
},
29+
{
30+
name: "object environment with name",
31+
yaml: "on: push\njobs:\n deploy:\n runs-on: ubuntu-latest\n environment:\n name: staging\n url: https://staging.example.com\n steps:\n - run: echo hi\n",
32+
wantEnv: "staging",
33+
},
34+
{
35+
name: "object environment name only",
36+
yaml: "on: push\njobs:\n deploy:\n runs-on: ubuntu-latest\n environment:\n name: preview\n steps:\n - run: echo hi\n",
37+
wantEnv: "preview",
38+
},
39+
}
40+
41+
for _, tt := range tests {
42+
t.Run(tt.name, func(t *testing.T) {
43+
workflows, err := Parse([]byte(tt.yaml))
44+
require.NoError(t, err)
45+
require.Len(t, workflows, 1)
46+
_, job := workflows[0].Job()
47+
require.NotNil(t, job)
48+
assert.Equal(t, tt.wantEnv, job.DeploymentEnvironmentName())
49+
})
50+
}
51+
}

0 commit comments

Comments
 (0)