mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-24 10:07:21 +02:00
1:n relationship for build-config
This commit is contained in:
parent
3f9356c6a7
commit
3fe710bbe4
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,4 +8,5 @@ release/
|
||||
cli/release/
|
||||
|
||||
server/swagger/files/*.json
|
||||
server/swagger/swagger_gen.go
|
||||
.idea/
|
||||
|
@ -16,7 +16,7 @@ package model
|
||||
|
||||
// ConfigStore persists pipeline configuration to storage.
|
||||
type ConfigStore interface {
|
||||
ConfigLoad(ID int64) (*Config, error)
|
||||
ConfigLoad(buildID int64) ([]*Config, error)
|
||||
ConfigFind(repo *Repo, sha string) (*Config, error)
|
||||
ConfigFindApproved(*Config) (bool, error)
|
||||
ConfigCreate(*Config) error
|
||||
@ -24,8 +24,10 @@ type ConfigStore interface {
|
||||
|
||||
// Config represents a pipeline configuration.
|
||||
type Config struct {
|
||||
ID int64 `json:"-" meddler:"config_id,pk"`
|
||||
RepoID int64 `json:"-" meddler:"config_repo_id"`
|
||||
Data string `json:"data" meddler:"config_data"`
|
||||
Hash string `json:"hash" meddler:"config_hash"`
|
||||
ID int64 `json:"-" meddler:"config_id,pk"`
|
||||
RepoID int64 `json:"-" meddler:"config_repo_id"`
|
||||
BuildID int64 `json:"-" meddler:"config_build_id"`
|
||||
Data string `json:"data" meddler:"config_data"`
|
||||
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
|
||||
|
||||
// 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 {
|
||||
logrus.Errorf("failure to get build config for %s. %s", repo.FullName, 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{
|
||||
Repo: repo,
|
||||
Curr: build,
|
||||
@ -323,7 +328,7 @@ func PostApproval(c *gin.Context) {
|
||||
Secs: secs,
|
||||
Regs: regs,
|
||||
Link: httputil.GetURL(c.Request),
|
||||
Yamls: []string{conf.Data},
|
||||
Yamls: yamls,
|
||||
Envs: envs,
|
||||
}
|
||||
buildItems, err := b.Build()
|
||||
@ -435,7 +440,7 @@ func PostBuild(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
logrus.Errorf("failure to get build config for %s. %s", repo.FullName, 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{
|
||||
Repo: repo,
|
||||
Curr: build,
|
||||
@ -511,7 +521,7 @@ func PostBuild(c *gin.Context) {
|
||||
Secs: secs,
|
||||
Regs: regs,
|
||||
Link: httputil.GetURL(c.Request),
|
||||
Yamls: []string{conf.Data},
|
||||
Yamls: yamls,
|
||||
Envs: buildParams,
|
||||
}
|
||||
buildItems, err := b.Build()
|
||||
|
@ -22,11 +22,11 @@ import (
|
||||
"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")
|
||||
conf := new(model.Config)
|
||||
err := meddler.QueryRow(db, conf, stmt, id)
|
||||
return conf, err
|
||||
var configs = []*model.Config{}
|
||||
err := meddler.QueryAll(db, &configs, stmt, buildID)
|
||||
return configs, err
|
||||
}
|
||||
|
||||
func (db *datastore) ConfigFind(repo *model.Repo, hash string) (*model.Config, error) {
|
||||
|
@ -28,15 +28,18 @@ func TestConfig(t *testing.T) {
|
||||
}()
|
||||
|
||||
var (
|
||||
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
||||
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
||||
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
||||
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
||||
buildID = int64(1)
|
||||
)
|
||||
|
||||
if err := s.ConfigCreate(
|
||||
&model.Config{
|
||||
RepoID: 2,
|
||||
Data: data,
|
||||
Hash: hash,
|
||||
RepoID: 2,
|
||||
BuildID: 1,
|
||||
Data: data,
|
||||
Hash: hash,
|
||||
Name: "default",
|
||||
},
|
||||
); err != nil {
|
||||
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 {
|
||||
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 {
|
||||
t.Errorf("Want config data %s, got %s", want, got)
|
||||
}
|
||||
if got, want := config.Hash, hash; got != want {
|
||||
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 {
|
||||
t.Errorf("Want config by id, got error %q", err)
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -89,46 +98,57 @@ func TestConfigApproved(t *testing.T) {
|
||||
s.CreateRepo(repo)
|
||||
|
||||
var (
|
||||
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
||||
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
||||
conf = &model.Config{
|
||||
data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]"
|
||||
hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26"
|
||||
buildBlocked = &model.Build{
|
||||
RepoID: repo.ID,
|
||||
Data: data,
|
||||
Hash: hash,
|
||||
Status: model.StatusBlocked,
|
||||
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 {
|
||||
t.Errorf("Unexpected error: insert config: %s", err)
|
||||
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 {
|
||||
t.Errorf("Want config not approved, when blocked or pending")
|
||||
if approved, err := s.ConfigFindApproved(conf); approved != false || err != nil {
|
||||
t.Errorf("Want config not approved, when blocked or pending. %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
s.CreateBuild(&model.Build{
|
||||
RepoID: repo.ID,
|
||||
ConfigID: conf.ID,
|
||||
Status: model.StatusRunning,
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||
})
|
||||
s.CreateBuild(buildRunning)
|
||||
conf2 := &model.Config{
|
||||
RepoID: repo.ID,
|
||||
BuildID: buildRunning.ID,
|
||||
Data: data,
|
||||
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 {
|
||||
t.Errorf("Want config approved, when running.")
|
||||
if approved, err := s.ConfigFindApproved(conf2); approved != true || err != nil {
|
||||
t.Errorf("Want config approved, when running. %v", err)
|
||||
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
|
||||
|
||||
import (
|
||||
@ -174,6 +160,22 @@ var migrations = []struct {
|
||||
name: "alter-table-update-file-meta",
|
||||
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
|
||||
@ -637,3 +639,27 @@ UPDATE files SET
|
||||
,file_meta_failed=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
|
||||
config_id
|
||||
,config_repo_id
|
||||
,config_build_id
|
||||
,config_hash
|
||||
,config_data
|
||||
,config_name
|
||||
FROM config
|
||||
WHERE config_id = ?
|
||||
WHERE config_build_id = ?
|
||||
|
||||
-- name: config-find-repo-hash
|
||||
|
||||
SELECT
|
||||
config_id
|
||||
,config_repo_id
|
||||
,config_build_id
|
||||
,config_hash
|
||||
,config_data
|
||||
,config_name
|
||||
FROM config
|
||||
WHERE config_repo_id = ?
|
||||
AND config_hash = ?
|
||||
@ -23,6 +27,6 @@ WHERE config_repo_id = ?
|
||||
|
||||
SELECT build_id FROM builds
|
||||
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')
|
||||
LIMIT 1
|
||||
|
@ -57,18 +57,22 @@ var configFindId = `
|
||||
SELECT
|
||||
config_id
|
||||
,config_repo_id
|
||||
,config_build_id
|
||||
,config_hash
|
||||
,config_data
|
||||
,config_name
|
||||
FROM config
|
||||
WHERE config_id = ?
|
||||
WHERE config_build_id = ?
|
||||
`
|
||||
|
||||
var configFindRepoHash = `
|
||||
SELECT
|
||||
config_id
|
||||
,config_repo_id
|
||||
,config_build_id
|
||||
,config_hash
|
||||
,config_data
|
||||
,config_name
|
||||
FROM config
|
||||
WHERE config_repo_id = ?
|
||||
AND config_hash = ?
|
||||
@ -77,7 +81,7 @@ WHERE config_repo_id = ?
|
||||
var configFindApproved = `
|
||||
SELECT build_id FROM builds
|
||||
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')
|
||||
LIMIT 1
|
||||
`
|
||||
|
@ -111,7 +111,7 @@ type Store interface {
|
||||
PermDelete(perm *model.Perm) 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)
|
||||
ConfigFindApproved(*model.Config) (bool, error)
|
||||
ConfigCreate(*model.Config) error
|
||||
|
Loading…
Reference in New Issue
Block a user