mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-02-07 23:22:21 +00:00
1:n relationship for build-config
This commit is contained in:
parent
3f9356c6a7
commit
3fe710bbe4
11 changed files with 147 additions and 66 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,4 +8,5 @@ release/
|
||||||
cli/release/
|
cli/release/
|
||||||
|
|
||||||
server/swagger/files/*.json
|
server/swagger/files/*.json
|
||||||
|
server/swagger/swagger_gen.go
|
||||||
.idea/
|
.idea/
|
||||||
|
|
|
@ -16,7 +16,7 @@ package model
|
||||||
|
|
||||||
// ConfigStore persists pipeline configuration to storage.
|
// ConfigStore persists pipeline configuration to storage.
|
||||||
type ConfigStore interface {
|
type ConfigStore interface {
|
||||||
ConfigLoad(ID int64) (*Config, error)
|
ConfigLoad(buildID int64) ([]*Config, error)
|
||||||
ConfigFind(repo *Repo, sha string) (*Config, error)
|
ConfigFind(repo *Repo, sha string) (*Config, error)
|
||||||
ConfigFindApproved(*Config) (bool, error)
|
ConfigFindApproved(*Config) (bool, error)
|
||||||
ConfigCreate(*Config) error
|
ConfigCreate(*Config) error
|
||||||
|
@ -26,6 +26,8 @@ type ConfigStore interface {
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ID int64 `json:"-" meddler:"config_id,pk"`
|
ID int64 `json:"-" meddler:"config_id,pk"`
|
||||||
RepoID int64 `json:"-" meddler:"config_repo_id"`
|
RepoID int64 `json:"-" meddler:"config_repo_id"`
|
||||||
|
BuildID int64 `json:"-" meddler:"config_build_id"`
|
||||||
Data string `json:"data" meddler:"config_data"`
|
Data string `json:"data" meddler:"config_data"`
|
||||||
Hash string `json:"hash" meddler:"config_hash"`
|
Hash string `json:"hash" meddler:"config_hash"`
|
||||||
|
Name string `json:"name" meddler:"config_name"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,7 +268,7 @@ func PostApproval(c *gin.Context) {
|
||||||
build.Reviewer = user.Login
|
build.Reviewer = user.Login
|
||||||
|
|
||||||
// fetch the build file from the database
|
// fetch the build file from the database
|
||||||
conf, err := Config.Storage.Config.ConfigLoad(build.ConfigID)
|
configs, err := Config.Storage.Config.ConfigLoad(build.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("failure to get build config for %s. %s", repo.FullName, err)
|
logrus.Errorf("failure to get build config for %s. %s", repo.FullName, err)
|
||||||
c.AbortWithError(404, err)
|
c.AbortWithError(404, err)
|
||||||
|
@ -315,6 +315,11 @@ func PostApproval(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var yamls []string
|
||||||
|
for _, y := range configs {
|
||||||
|
yamls = append(yamls, string(y.Data))
|
||||||
|
}
|
||||||
|
|
||||||
b := procBuilder{
|
b := procBuilder{
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
Curr: build,
|
Curr: build,
|
||||||
|
@ -323,7 +328,7 @@ func PostApproval(c *gin.Context) {
|
||||||
Secs: secs,
|
Secs: secs,
|
||||||
Regs: regs,
|
Regs: regs,
|
||||||
Link: httputil.GetURL(c.Request),
|
Link: httputil.GetURL(c.Request),
|
||||||
Yamls: []string{conf.Data},
|
Yamls: yamls,
|
||||||
Envs: envs,
|
Envs: envs,
|
||||||
}
|
}
|
||||||
buildItems, err := b.Build()
|
buildItems, err := b.Build()
|
||||||
|
@ -435,7 +440,7 @@ func PostBuild(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch the .drone.yml file from the database
|
// fetch the .drone.yml file from the database
|
||||||
conf, err := Config.Storage.Config.ConfigLoad(build.ConfigID)
|
configs, err := Config.Storage.Config.ConfigLoad(build.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("failure to get build config for %s. %s", repo.FullName, err)
|
logrus.Errorf("failure to get build config for %s. %s", repo.FullName, err)
|
||||||
c.AbortWithError(404, err)
|
c.AbortWithError(404, err)
|
||||||
|
@ -503,6 +508,11 @@ func PostBuild(c *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var yamls []string
|
||||||
|
for _, y := range configs {
|
||||||
|
yamls = append(yamls, string(y.Data))
|
||||||
|
}
|
||||||
|
|
||||||
b := procBuilder{
|
b := procBuilder{
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
Curr: build,
|
Curr: build,
|
||||||
|
@ -511,7 +521,7 @@ func PostBuild(c *gin.Context) {
|
||||||
Secs: secs,
|
Secs: secs,
|
||||||
Regs: regs,
|
Regs: regs,
|
||||||
Link: httputil.GetURL(c.Request),
|
Link: httputil.GetURL(c.Request),
|
||||||
Yamls: []string{conf.Data},
|
Yamls: yamls,
|
||||||
Envs: buildParams,
|
Envs: buildParams,
|
||||||
}
|
}
|
||||||
buildItems, err := b.Build()
|
buildItems, err := b.Build()
|
||||||
|
|
|
@ -22,11 +22,11 @@ import (
|
||||||
"github.com/russross/meddler"
|
"github.com/russross/meddler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db *datastore) ConfigLoad(id int64) (*model.Config, error) {
|
func (db *datastore) ConfigLoad(buildID int64) ([]*model.Config, error) {
|
||||||
stmt := sql.Lookup(db.driver, "config-find-id")
|
stmt := sql.Lookup(db.driver, "config-find-id")
|
||||||
conf := new(model.Config)
|
var configs = []*model.Config{}
|
||||||
err := meddler.QueryRow(db, conf, stmt, id)
|
err := meddler.QueryAll(db, &configs, stmt, buildID)
|
||||||
return conf, err
|
return configs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *datastore) ConfigFind(repo *model.Repo, hash string) (*model.Config, error) {
|
func (db *datastore) ConfigFind(repo *model.Repo, hash string) (*model.Config, error) {
|
||||||
|
|
|
@ -30,13 +30,16 @@ func TestConfig(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
||||||
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
||||||
|
buildID = int64(1)
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := s.ConfigCreate(
|
if err := s.ConfigCreate(
|
||||||
&model.Config{
|
&model.Config{
|
||||||
RepoID: 2,
|
RepoID: 2,
|
||||||
|
BuildID: 1,
|
||||||
Data: data,
|
Data: data,
|
||||||
Hash: hash,
|
Hash: hash,
|
||||||
|
Name: "default",
|
||||||
},
|
},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
t.Errorf("Unexpected error: insert config: %s", err)
|
t.Errorf("Unexpected error: insert config: %s", err)
|
||||||
|
@ -54,19 +57,25 @@ func TestConfig(t *testing.T) {
|
||||||
if got, want := config.RepoID, int64(2); got != want {
|
if got, want := config.RepoID, int64(2); got != want {
|
||||||
t.Errorf("Want config repo id %d, got %d", want, got)
|
t.Errorf("Want config repo id %d, got %d", want, got)
|
||||||
}
|
}
|
||||||
|
if got, want := config.BuildID, buildID; got != want {
|
||||||
|
t.Errorf("Want config build id %d, got %d", want, got)
|
||||||
|
}
|
||||||
if got, want := config.Data, data; got != want {
|
if got, want := config.Data, data; got != want {
|
||||||
t.Errorf("Want config data %s, got %s", want, got)
|
t.Errorf("Want config data %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
if got, want := config.Hash, hash; got != want {
|
if got, want := config.Hash, hash; got != want {
|
||||||
t.Errorf("Want config hash %s, got %s", want, got)
|
t.Errorf("Want config hash %s, got %s", want, got)
|
||||||
}
|
}
|
||||||
|
if got, want := config.Name, "default"; got != want {
|
||||||
|
t.Errorf("Want config name %s, got %s", want, got)
|
||||||
|
}
|
||||||
|
|
||||||
loaded, err := s.ConfigLoad(config.ID)
|
loaded, err := s.ConfigLoad(buildID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Want config by id, got error %q", err)
|
t.Errorf("Want config by id, got error %q", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if got, want := loaded.ID, config.ID; got != want {
|
if got, want := loaded[0].ID, config.ID; got != want {
|
||||||
t.Errorf("Want config by id %d, got %d", want, got)
|
t.Errorf("Want config by id %d, got %d", want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,44 +100,55 @@ func TestConfigApproved(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
||||||
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
||||||
conf = &model.Config{
|
buildBlocked = &model.Build{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Data: data,
|
Status: model.StatusBlocked,
|
||||||
Hash: hash,
|
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||||
|
}
|
||||||
|
buildPending = &model.Build{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Status: model.StatusPending,
|
||||||
|
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||||
|
}
|
||||||
|
buildRunning = &model.Build{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Status: model.StatusRunning,
|
||||||
|
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
s.CreateBuild(buildBlocked)
|
||||||
|
s.CreateBuild(buildPending)
|
||||||
|
conf := &model.Config{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
BuildID: buildBlocked.ID,
|
||||||
|
Data: data,
|
||||||
|
Hash: hash,
|
||||||
|
}
|
||||||
if err := s.ConfigCreate(conf); err != nil {
|
if err := s.ConfigCreate(conf); err != nil {
|
||||||
t.Errorf("Unexpected error: insert config: %s", err)
|
t.Errorf("Unexpected error: insert config: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.CreateBuild(&model.Build{
|
|
||||||
RepoID: repo.ID,
|
|
||||||
ConfigID: conf.ID,
|
|
||||||
Status: model.StatusBlocked,
|
|
||||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
|
||||||
})
|
|
||||||
s.CreateBuild(&model.Build{
|
|
||||||
RepoID: repo.ID,
|
|
||||||
ConfigID: conf.ID,
|
|
||||||
Status: model.StatusPending,
|
|
||||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
|
||||||
})
|
|
||||||
|
|
||||||
if ok, _ := s.ConfigFindApproved(conf); ok == true {
|
if approved, err := s.ConfigFindApproved(conf); approved != false || err != nil {
|
||||||
t.Errorf("Want config not approved, when blocked or pending")
|
t.Errorf("Want config not approved, when blocked or pending. %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.CreateBuild(&model.Build{
|
s.CreateBuild(buildRunning)
|
||||||
|
conf2 := &model.Config{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
ConfigID: conf.ID,
|
BuildID: buildRunning.ID,
|
||||||
Status: model.StatusRunning,
|
Data: data,
|
||||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
Hash: "xxx",
|
||||||
})
|
}
|
||||||
|
if err := s.ConfigCreate(conf2); err != nil {
|
||||||
|
t.Errorf("Unexpected error: insert config: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ok, _ := s.ConfigFindApproved(conf); ok == false {
|
if approved, err := s.ConfigFindApproved(conf2); approved != true || err != nil {
|
||||||
t.Errorf("Want config approved, when running.")
|
t.Errorf("Want config approved, when running. %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
// Copyright 2018 Drone.IO Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package sqlite
|
package sqlite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -174,6 +160,22 @@ var migrations = []struct {
|
||||||
name: "alter-table-update-file-meta",
|
name: "alter-table-update-file-meta",
|
||||||
stmt: alterTableUpdateFileMeta,
|
stmt: alterTableUpdateFileMeta,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-config-build-id",
|
||||||
|
stmt: alterTableAddConfigBuildId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-config-config-id",
|
||||||
|
stmt: updateTableSetConfigConfigId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "alter-table-add-config-name",
|
||||||
|
stmt: alterTableAddConfigName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "update-table-set-config-name",
|
||||||
|
stmt: updateTableSetConfigName,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate performs the database migration. If the migration fails
|
// Migrate performs the database migration. If the migration fails
|
||||||
|
@ -637,3 +639,27 @@ UPDATE files SET
|
||||||
,file_meta_failed=0
|
,file_meta_failed=0
|
||||||
,file_meta_skipped=0
|
,file_meta_skipped=0
|
||||||
`
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 019_add_column_config_build_id.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddConfigBuildId = `
|
||||||
|
ALTER TABLE config ADD COLUMN config_build_id INTEGER
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetConfigConfigId = `
|
||||||
|
UPDATE config SET config_build_id = (SELECT builds.build_id FROM builds WHERE builds.build_config_id = config.config_id)
|
||||||
|
`
|
||||||
|
|
||||||
|
//
|
||||||
|
// 020_add_column_config_name.sql
|
||||||
|
//
|
||||||
|
|
||||||
|
var alterTableAddConfigName = `
|
||||||
|
ALTER TABLE config ADD COLUMN config_name TEXT
|
||||||
|
`
|
||||||
|
|
||||||
|
var updateTableSetConfigName = `
|
||||||
|
UPDATE config SET config_name = "default"
|
||||||
|
`
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-config-build-id
|
||||||
|
|
||||||
|
ALTER TABLE config ADD COLUMN config_build_id INTEGER
|
||||||
|
|
||||||
|
-- name: update-table-set-config-config-id
|
||||||
|
|
||||||
|
UPDATE config SET config_build_id = (SELECT builds.build_id FROM builds WHERE builds.build_config_id = config.config_id)
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- name: alter-table-add-config-name
|
||||||
|
|
||||||
|
ALTER TABLE config ADD COLUMN config_name TEXT
|
||||||
|
|
||||||
|
-- name: update-table-set-config-name
|
||||||
|
|
||||||
|
UPDATE config SET config_name = "default"
|
|
@ -3,18 +3,22 @@
|
||||||
SELECT
|
SELECT
|
||||||
config_id
|
config_id
|
||||||
,config_repo_id
|
,config_repo_id
|
||||||
|
,config_build_id
|
||||||
,config_hash
|
,config_hash
|
||||||
,config_data
|
,config_data
|
||||||
|
,config_name
|
||||||
FROM config
|
FROM config
|
||||||
WHERE config_id = ?
|
WHERE config_build_id = ?
|
||||||
|
|
||||||
-- name: config-find-repo-hash
|
-- name: config-find-repo-hash
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
config_id
|
config_id
|
||||||
,config_repo_id
|
,config_repo_id
|
||||||
|
,config_build_id
|
||||||
,config_hash
|
,config_hash
|
||||||
,config_data
|
,config_data
|
||||||
|
,config_name
|
||||||
FROM config
|
FROM config
|
||||||
WHERE config_repo_id = ?
|
WHERE config_repo_id = ?
|
||||||
AND config_hash = ?
|
AND config_hash = ?
|
||||||
|
@ -23,6 +27,6 @@ WHERE config_repo_id = ?
|
||||||
|
|
||||||
SELECT build_id FROM builds
|
SELECT build_id FROM builds
|
||||||
WHERE build_repo_id = ?
|
WHERE build_repo_id = ?
|
||||||
AND build_config_id = ?
|
AND build_id in (SELECT config_build_id FROM config WHERE config.config_id = ?)
|
||||||
AND build_status NOT IN ('blocked', 'pending')
|
AND build_status NOT IN ('blocked', 'pending')
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|
|
@ -57,18 +57,22 @@ var configFindId = `
|
||||||
SELECT
|
SELECT
|
||||||
config_id
|
config_id
|
||||||
,config_repo_id
|
,config_repo_id
|
||||||
|
,config_build_id
|
||||||
,config_hash
|
,config_hash
|
||||||
,config_data
|
,config_data
|
||||||
|
,config_name
|
||||||
FROM config
|
FROM config
|
||||||
WHERE config_id = ?
|
WHERE config_build_id = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
var configFindRepoHash = `
|
var configFindRepoHash = `
|
||||||
SELECT
|
SELECT
|
||||||
config_id
|
config_id
|
||||||
,config_repo_id
|
,config_repo_id
|
||||||
|
,config_build_id
|
||||||
,config_hash
|
,config_hash
|
||||||
,config_data
|
,config_data
|
||||||
|
,config_name
|
||||||
FROM config
|
FROM config
|
||||||
WHERE config_repo_id = ?
|
WHERE config_repo_id = ?
|
||||||
AND config_hash = ?
|
AND config_hash = ?
|
||||||
|
@ -77,7 +81,7 @@ WHERE config_repo_id = ?
|
||||||
var configFindApproved = `
|
var configFindApproved = `
|
||||||
SELECT build_id FROM builds
|
SELECT build_id FROM builds
|
||||||
WHERE build_repo_id = ?
|
WHERE build_repo_id = ?
|
||||||
AND build_config_id = ?
|
AND build_id in (SELECT config_build_id FROM config WHERE config.config_id = ?)
|
||||||
AND build_status NOT IN ('blocked', 'pending')
|
AND build_status NOT IN ('blocked', 'pending')
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
|
@ -111,7 +111,7 @@ type Store interface {
|
||||||
PermDelete(perm *model.Perm) error
|
PermDelete(perm *model.Perm) error
|
||||||
PermFlush(user *model.User, before int64) error
|
PermFlush(user *model.User, before int64) error
|
||||||
|
|
||||||
ConfigLoad(int64) (*model.Config, error)
|
ConfigLoad(int64) ([]*model.Config, error)
|
||||||
ConfigFind(*model.Repo, string) (*model.Config, error)
|
ConfigFind(*model.Repo, string) (*model.Config, error)
|
||||||
ConfigFindApproved(*model.Config) (bool, error)
|
ConfigFindApproved(*model.Config) (bool, error)
|
||||||
ConfigCreate(*model.Config) error
|
ConfigCreate(*model.Config) error
|
||||||
|
|
Loading…
Reference in a new issue