Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
8f920ff
fix(gitlab): always re-collect MR commits regardless of MR updated_at…
bujjibabukatta Jun 27, 2026
0e96ba1
fix: recover create a new connection action (#8952)
kirillNevedrov Jun 30, 2026
c43696a
fix(azuredevops): treat 204 No Content as graceful skip in timeline c…
bujjibabukatta Jun 30, 2026
6f2ee9d
Add Copilot team adoption dashboards (#8966)
ewega Jul 2, 2026
15e34bb
fix(jira): collect issues via search API to avoid kanban sub-filter e…
jbsmith7741 Jul 2, 2026
edb9b0d
fix(opsgenie): align access-rights error with docs (#8976)
TOGEP Jul 9, 2026
7a51deb
feat:allow claude organization support (#8978)
salim8898 Jul 9, 2026
ee919fa
fix: docker file path in build-grafana-image target (#8979)
kirillNevedrov Jul 9, 2026
cd7bebf
feat(jira): Allow extra JQL when querying JIRA board (#8972)
VaughanJ Jul 9, 2026
e7ac139
refactor: deprecating dbt plugin (#8971)
klesh Jul 10, 2026
50f664e
feat(auth): add OIDC allowlist restrictions (#8984)
MauricioApu Jul 10, 2026
52278b0
fix(bitbucket): migrate off cross-workspace APIs removed by CHANGE-27…
KennethWKZ Jul 11, 2026
f93895f
fix(gh-copilot): preserve hyphenated enterprise slugs (#8935)
bujjibabukatta Jul 13, 2026
082a402
fix(dora): use two-phase deployment lookup to prevent first-deploymen…
bujjibabukatta Jul 15, 2026
3a4333e
fix(python): add missing composite primary keys in domain_layer/code.…
bujjibabukatta Jul 15, 2026
1cbd835
feat(sonarqube): collect historical project metrics and Grafana trend…
jbsmith7741 Jul 15, 2026
eaf86ce
build: pin swag CLI and oauth2-proxy, ignore build artifacts in docke…
DoDiODev Jul 15, 2026
060af3a
fix(config-ui): explicitly set initialValues for plugins missing it (…
bramhanandlingala Jul 19, 2026
b34d761
fix(sonarqube): support long issue code block components (#8986)
DoDiODev Jul 19, 2026
b4b53b8
fix(domain): migrate issue component to text (#8987)
DoDiODev Jul 19, 2026
27c771a
fix(jira): change _tool_jira_issues.fix_versions column to text (#8988)
DoDiODev Jul 19, 2026
9e8ca1b
feat(grafana): upgrade dashboards and provisioning for Grafana 13 (#8…
DoDiODev Jul 20, 2026
b70ac93
chore(docker): bump PostgreSQL to 18.1 and MySQL to 8.4.10 (#9003)
DoDiODev Jul 26, 2026
c4a15bf
fix(bitbucket): paginate remote-scopes API to return all repositories…
bramhanandlingala Jul 26, 2026
20179fa
Fix webhook authorization when AUTH_ENABLED=true (#9008)
kamphaus Jul 27, 2026
21ea61c
feat(jira): persist Sprint Report snapshot for accurate committed/com…
bramhanandlingala Jul 27, 2026
7f7cf09
fix(sonarqube): tolerate missing migration indexes (#9012)
frederic-huebner Jul 27, 2026
2127e84
chore(config-ui): modernize frontend toolchain and framework stack (#…
DoDiODev Jul 30, 2026
73fa07d
feat(clickup): add ClickUp data-source plugin (folder-scope boards, s…
elynch303 Jul 30, 2026
e217c67
fix(dashboards): fix string team/user ID filtering in MySQL dashboard…
bujjibabukatta Jul 30, 2026
2cfe630
fix(config-ui): improve copy text contrast in dark mode (#9020)
TOGEP Jul 30, 2026
2d4834c
fix(org): resolve API handlers at request time to survive late plugin…
pballester Jul 30, 2026
0194a41
feat(incidentio): add incident.io data source plugin (#9023)
serroba Jul 30, 2026
705280d
feat(gh-copilot): add AI credit usage billing metrics and fix report-…
PankajChaudhari-Atos Jul 30, 2026
14a4e5b
feat(jira): add Atlassian API Gateway authentication mode (#9024)
pingkscodelabs Jul 30, 2026
e3a4271
feat(jira): add JIRA_SKIP_UNPARSEABLE_ISSUES to survive unparseable i…
vbhanuchander-lang Aug 3, 2026
5eee167
fix(customize): skip rows with a missing raw record instead of ending…
vbhanuchander-lang Aug 3, 2026
352f3b5
fix(jira): add missing _raw_data_* columns to _tool_jira_sprint_repor…
DoDiODev Aug 3, 2026
b7e5efa
chore(python): bump Python runtime from 3.9 to 3.11 (#9005)
DoDiODev Aug 3, 2026
6ea77c9
fix(core): replace constraints.Unsigned with local interface in archi…
mfrancisc Aug 6, 2026
361455e
fix(sonarqube): correct aggregate coverage formula in Grafana dashboa…
bramhanandlingala Aug 7, 2026
d323c16
feat(github): warn when adding a repo already scoped on another conne…
mfrancisc Aug 8, 2026
3d98fd6
Merge branch 'fix/#8818' of https://github.com/bujjibabukatta/incubat…
bujjibabukatta Aug 9, 2026
5c66376
fix(gitlab): correct if-brace syntax in GetMergeRequestsIterator
bujjibabukatta Aug 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"ghcr.io/jungaretti/features/make:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:2.12.0": {},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.9"
"version": "3.11"
},
"ghcr.io/devcontainers-extra/features/poetry:2": {},
"ghcr.io/devcontainers/features/node:1": {
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ services:
- default
command: sleep infinity
mysql:
image: mysql:8
image: mysql:8.4.10
volumes:
- mysql-storage:/var/lib/mysql
restart: always
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/config-ui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '18'
node-version: '24'
cache: 'yarn'
cache-dependency-path: config-ui/yarn.lock
- name: Install with Yarn
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ build-config-ui-image:
cd config-ui; docker build -t $(IMAGE_REPO)/devlake-config-ui:$(TAG) --file ./Dockerfile .

build-grafana-image:
cd grafana; docker build -t $(IMAGE_REPO)/devlake-dashboard:$(TAG) --file ./backend/Dockerfile .
cd grafana; docker build -t $(IMAGE_REPO)/devlake-dashboard:$(TAG) --file ./Dockerfile .

build-images: build-server-image build-config-ui-image build-grafana-image

Expand Down
24 changes: 24 additions & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Build artifacts: regenerated inside the image (GOBIN=/app/bin + make build-plugin/build-server).
# Shipping the host's pre-built bin/ (multiple GB of plugin .so files) bloats the
# build context and the builder layer, which can exhaust the Docker VM and crash BuildKit.
bin/

# Generated mocks (regenerated via make mock inside the image)
mocks/

# Runtime logs
logs/

# Python build/venv artifacts (regenerated; Dockerfile.server reinstalls from
# requirements.txt / pyproject and runs python/build.sh). Source under python/ is kept.
**/.venv/
**/__pycache__/
**/*.pyc
python/.devlake-python-build-root/

# Test / coverage output
*.out
coverage.txt

# OS / editor junk
.DS_Store
4 changes: 2 additions & 2 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ RUN if [ "$(arch)" != "x86_64" ] ; then \
fi

RUN go install github.com/vektra/mockery/v2@v2.53.6
RUN go install github.com/swaggo/swag/cmd/swag@v1.16.1
RUN go install github.com/swaggo/swag/cmd/swag@v1.16.6

COPY --from=debian-amd64 /usr/include /rootfs-amd64/usr/include
COPY --from=debian-amd64 /usr/lib/x86_64-linux-gnu /rootfs-amd64/usr/lib/x86_64-linux-gnu
Expand Down Expand Up @@ -113,7 +113,7 @@ RUN cd /usr/local/deps/target/lib && \
done


FROM python:3.9-slim-bookworm as base
FROM python:3.11-slim-bookworm as base

RUN apt-get update && \
apt-get install -y python3-dev python3-pip tar pkg-config curl libssh2-1 zlib1g libffi-dev default-libmysqlclient-dev libpq-dev tini git openssh-client corkscrew && \
Expand Down
2 changes: 1 addition & 1 deletion backend/Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ RUN mkdir -p /tmp/build && cd /tmp/build && \
ldconfig

RUN go install github.com/vektra/mockery/v2@v2.53.6
RUN go install github.com/swaggo/swag/cmd/swag@v1.16.1
RUN go install github.com/swaggo/swag/cmd/swag@v1.16.6

WORKDIR /app
COPY . /app
Expand Down
2 changes: 1 addition & 1 deletion backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ all: build

go-dep:
go install github.com/vektra/mockery/v2@v2.53.6
go install github.com/swaggo/swag/cmd/swag@v1.16.1
go install github.com/swaggo/swag/cmd/swag@v1.16.6
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2

go-dev-tools:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import "github.com/apache/incubator-devlake/core/models/domainlayer"
type CqIssueCodeBlock struct {
domainlayer.DomainEntity
IssueKey string `json:"key" gorm:"index"`
Component string `gorm:"index"`
Component string `gorm:"type:text"`
StartLine int
EndLine int
StartOffset int
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 codequality

import (
"time"

"github.com/apache/incubator-devlake/core/models/domainlayer"
)

type CqProjectMetricsHistory struct {
domainlayer.DomainEntity
ProjectKey string `gorm:"index;type:varchar(500)"`
AnalysisDate time.Time `gorm:"index"`
Coverage *float64
Ncloc *int
Bugs *int
ReliabilityRating string `gorm:"type:varchar(5)"`
CodeSmells *int
SqaleRating string `gorm:"type:varchar(5)"`
Complexity *int
CognitiveComplexity *int
Vulnerabilities *int
SecurityRating string `gorm:"type:varchar(5)"`
SecurityHotspots *int
DuplicatedLinesDensity *float64
}

func (CqProjectMetricsHistory) TableName() string {
return "cq_project_metrics_history"
}
1 change: 1 addition & 0 deletions backend/core/models/domainlayer/domaininfo/domaininfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func GetDomainTablesInfo() []dal.Tabler {
&codequality.CqIssue{},
&codequality.CqIssueImpact{},
&codequality.CqProject{},
&codequality.CqProjectMetricsHistory{},
// crossdomain
&crossdomain.Account{},
&crossdomain.BoardRepo{},
Expand Down
19 changes: 11 additions & 8 deletions backend/core/models/domainlayer/ticket/sprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ limitations under the License.
package ticket

import (
"time"

"github.com/apache/incubator-devlake/core/models/common"
"github.com/apache/incubator-devlake/core/models/domainlayer"
"time"
)

var (
Expand All @@ -31,13 +32,15 @@ var (

type Sprint struct {
domainlayer.DomainEntity
Name string `gorm:"type:varchar(255)"`
Url string `gorm:"type:varchar(255)"`
Status string `gorm:"type:varchar(100)"`
StartedDate *time.Time
EndedDate *time.Time
CompletedDate *time.Time
OriginalBoardID string `gorm:"type:varchar(255)"`
Name string `gorm:"type:varchar(255)"`
Url string `gorm:"type:varchar(255)"`
Status string `gorm:"type:varchar(100)"`
StartedDate *time.Time
EndedDate *time.Time
CompletedDate *time.Time
OriginalBoardID string `gorm:"type:varchar(255)"`
CommittedStoryPoint *float64
CompletedStoryPoint *float64
}

func (Sprint) TableName() string {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 migrationscripts

import (
"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
)

var _ plugin.MigrationScript = (*changeIssueComponentToText)(nil)

type changeIssueComponentToText struct{}

func (*changeIssueComponentToText) Up(basicRes context.BasicRes) errors.Error {
// The 20240813 migration targeted the non-existent plural "components" column.
return basicRes.GetDal().ModifyColumnType("issues", "component", "text")
}

func (*changeIssueComponentToText) Version() uint64 {
return 20260629120000
}

func (*changeIssueComponentToText) Name() string {
return "change issues.component type to text"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 migrationscripts

import (
"testing"

"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
)

type modifyColumnTypeCall struct {
tableName string
columnName string
columnType string
}

type recordingDal struct {
dal.Dal
call *modifyColumnTypeCall
}

func (d *recordingDal) ModifyColumnType(tableName string, columnName string, columnType string) errors.Error {
d.call = &modifyColumnTypeCall{tableName, columnName, columnType}
return nil
}

type basicResWithDal struct {
context.BasicRes
database dal.Dal
}

func (r *basicResWithDal) GetDal() dal.Dal {
return r.database
}

func TestChangeIssueComponentToText(t *testing.T) {
database := new(recordingDal)
script := new(changeIssueComponentToText)

if err := script.Up(&basicResWithDal{database: database}); err != nil {
t.Fatalf("migration failed: %v", err)
}

want := &modifyColumnTypeCall{"issues", "component", "text"}
if database.call == nil || *database.call != *want {
t.Fatalf("ModifyColumnType call = %#v, want %#v", database.call, want)
}
if script.Version() != 20260629120000 {
t.Fatalf("Version() = %d, want 20260629120000", script.Version())
}
if script.Name() != "change issues.component type to text" {
t.Fatalf("Name() = %q, want %q", script.Name(), "change issues.component type to text")
}

found := false
for _, registeredScript := range All() {
if registeredScript.Version() == script.Version() {
found = true
break
}
}
if !found {
t.Fatalf("migration version %d is not registered", script.Version())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 migrationscripts

import (
"github.com/apache/incubator-devlake/core/context"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
)

var _ plugin.MigrationScript = (*changeCqIssueCodeBlocksComponentToText)(nil)

type changeCqIssueCodeBlocksComponentToText struct{}

func (script *changeCqIssueCodeBlocksComponentToText) Up(basicRes context.BasicRes) errors.Error {
db := basicRes.GetDal()
if err := db.DropIndexes("cq_issue_code_blocks", "idx_cq_issue_code_blocks_component"); err != nil {
return err
}
return db.ModifyColumnType("cq_issue_code_blocks", "component", "text")
}

func (*changeCqIssueCodeBlocksComponentToText) Version() uint64 {
return 20260701000000
}

func (*changeCqIssueCodeBlocksComponentToText) Name() string {
return "change cq_issue_code_blocks.component type to text"
}
Loading