Skip to content

Commit ed6bb2c

Browse files
committed
Merge branch 'main' into dejacode-demo
2 parents 97c42c3 + 3493e35 commit ed6bb2c

78 files changed

Lines changed: 426 additions & 1040 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ include
1616
.settings
1717
TAGS
1818
.idea
19+
.vscode
1920
Include
2021
Lib
2122
.env

CHANGELOG.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
Release notes
22
=============
33

4+
### Version 5.8.0
5+
6+
* feat: [five-c] Compliance dashboard export/report by @tdruez in https://github.com/aboutcode-org/dejacode/pull/522
7+
* feat: [five-c] Compliance extended report set by @tdruez in https://github.com/aboutcode-org/dejacode/pull/523
8+
* feat: [five-c] User experience (UX) enhancements by @tdruez in https://github.com/aboutcode-org/dejacode/pull/524
9+
* feat: [five-c] Compliance dashboards improved by @tdruez in https://github.com/aboutcode-org/dejacode/pull/532
10+
* feat: [five-c] Compliance dashboards extended by @tdruez in https://github.com/aboutcode-org/dejacode/pull/537
11+
* fix: REQUESTS_TIMEOUT by converting to int by @rogu-beta in https://github.com/aboutcode-org/dejacode/pull/526
12+
* feat: replace pip install by uv and lock file by @tdruez in https://github.com/aboutcode-org/dejacode/pull/529
13+
* chore: upgrade multiple dependencies by @tdruez in https://github.com/aboutcode-org/dejacode/pull/530
14+
* chore: upgrade django-registration to latest version by @tdruez in https://github.com/aboutcode-org/dejacode/pull/531
15+
* chore: upgrade dependencies by @tdruez in https://github.com/aboutcode-org/dejacode/pull/538
16+
* chore: remove the dependency on gitpython by @tdruez in https://github.com/aboutcode-org/dejacode/pull/539
17+
* feat: add create_dependencies option to all import forms by @tdruez in https://github.com/aboutcode-org/dejacode/pull/540
18+
* chore: update seed data and add instructions by @tdruez in https://github.com/aboutcode-org/dejacode/pull/541
19+
* feat: add a set_key method on AbstractAPIToken by @tdruez in https://github.com/aboutcode-org/dejacode/pull/521
20+
421
### Version 5.7.1
522

623
- feat: Product compliance tab

RELEASE.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Release instructions for `DejaCode
22

3-
### Automated release workflow
3+
## Automated release workflow
44

55
- Create a new `release-x.x.x` branch
66
- Update the version in:
@@ -11,10 +11,12 @@
1111
- Create a PR and merge once approved
1212
- Tag and push that tag. This will trigger the `create-github-release.yml`
1313
and `publish-docker-image.yml` GitHub workflows:
14-
```
14+
15+
```sh
1516
VERSION=vx.x.x # <- Set the new version here
1617
git tag -a $VERSION -m ""
1718
git push origin $VERSION
1819
```
19-
- Review the GitHub release created by the workflow at
20-
https://github.com/aboutcode-org/dejacode/releases/
20+
21+
- Review the GitHub release created by the workflow at
22+
<https://github.com/aboutcode-org/dejacode/releases/>

data/postgresql/README.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Generate `initdb.sql.gz` (shareable initial seed)
2+
3+
This guide produces a compressed SQL dump (`initdb.sql.gz`) that Postgres loads
4+
automatically on first startup (via `/docker-entrypoint-initdb.d/`). It uses plain
5+
`docker` commands only, with no extra compose file, and never touches your local stack.
6+
7+
## Prerequisites: Dump the reference data from server
8+
9+
Run against the reference instance:
10+
11+
```sh
12+
docker compose -f /opt/dejacode/docker-compose.yml exec web ./manage.py dumpinitdata nexB > initdb_dataset.json
13+
```
14+
15+
## Steps
16+
17+
Run the following on your local DejaCode checkout.
18+
19+
### 1. Fetch the initdb_dataset.json file from the server
20+
21+
### 2. Build web image from the project root
22+
23+
```sh
24+
cd dejacode
25+
docker build -t dejacode-web .
26+
```
27+
28+
### 3. Create a network and start the empty database
29+
30+
The container has no named volume (ephemeral) and is reachable as `db` on the network.
31+
32+
```sh
33+
docker network create dejacode-seed-net
34+
35+
docker run -d \
36+
--name dejacode-seed-db \
37+
--network dejacode-seed-net \
38+
--network-alias db \
39+
--env-file docker.env \
40+
--shm-size=1g \
41+
docker.io/library/postgres:16.13
42+
```
43+
44+
### 4. Apply migrations on the fresh database
45+
46+
```sh
47+
docker run --rm \
48+
--network dejacode-seed-net \
49+
--env-file docker.env \
50+
-v "$(pwd)/.env:/opt/dejacode/.env" \
51+
-v /etc/dejacode/:/etc/dejacode/ \
52+
dejacode-web ./manage.py migrate
53+
```
54+
55+
### 5. Load the data from stdin
56+
57+
`loaddata` reads the JSON from standard input, so there is no file to mount.
58+
The `-i` flag keeps stdin open for the redirection.
59+
60+
```sh
61+
docker run --rm -i \
62+
--network dejacode-seed-net \
63+
--env-file docker.env \
64+
-v "$(pwd)/.env:/opt/dejacode/.env" \
65+
-v /etc/dejacode/:/etc/dejacode/ \
66+
dejacode-web ./manage.py loaddata --format=json - < initdb_dataset.json
67+
```
68+
69+
This will take over 10 minutes to run.
70+
71+
### 6. Inspect and tweak
72+
73+
```sh
74+
docker run --rm -it \
75+
--network dejacode-seed-net \
76+
--env-file docker.env \
77+
-v "$(pwd)/.env:/opt/dejacode/.env" \
78+
-v /etc/dejacode/:/etc/dejacode/ \
79+
dejacode-web ./manage.py shell
80+
```
81+
82+
```python
83+
dataspace = Dataspace.objects.get_reference()
84+
values = {
85+
"homepage_url": "",
86+
"contact_info": "",
87+
"notes": "",
88+
"logo_url": "",
89+
"address": "",
90+
"open_source_information_url": "",
91+
"open_source_download_url": "",
92+
# "home_page_announcements": "",
93+
"show_license_profile_in_license_list_view": True,
94+
"show_spdx_short_identifier_in_license_list_view": True,
95+
"show_usage_policy_in_user_views": True,
96+
"show_type_in_component_list_view": False,
97+
"hide_empty_fields_in_component_details_view": True,
98+
"set_usage_policy_on_new_component_from_licenses": True,
99+
"enable_package_scanning": True,
100+
"update_packages_from_scan": True,
101+
"enable_purldb_access": True,
102+
"enable_vulnerablecodedb_access": True,
103+
"vulnerabilities_updated_at": None,
104+
}
105+
Dataspace.objects.filter(id=dataspace.id).update(**values)
106+
dataspace.set_configuration("homepage_layout", None)
107+
dataspace.set_configuration("vulnerablecode_url", "https://public.vulnerablecode.io/")
108+
dataspace.set_configuration("purldb_url", "https://public.purldb.io/")
109+
```
110+
111+
### 7. Extract the compressed SQL dump
112+
113+
`pg_dump` runs inside the container (Postgres 16.13). `--no-owner --no-privileges`
114+
makes the dump replayable even if another deployment uses a different `POSTGRES_USER`.
115+
116+
```sh
117+
docker exec dejacode-seed-db \
118+
sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" --no-owner --no-privileges' \
119+
| gzip > data/postgresql/initdb.sql.gz
120+
```
121+
122+
### 8. Verify the seed
123+
124+
The `initdb.d` scripts run **only on a fresh db volume**. To test the artifact without
125+
breaking your local setup, start the main stack with a throwaway project name and a new
126+
volume:
127+
128+
```sh
129+
docker compose -p dejacode-check up -d db
130+
# check the data is present, then:
131+
docker compose -p dejacode-check down -v
132+
```
133+
134+
### 9. Tear everything down
135+
136+
```sh
137+
docker rm -fv dejacode-seed-db
138+
docker network rm dejacode-seed-net
139+
```
140+
141+
`-v` removes the anonymous volume created by the Postgres image. Your local `dejacode`
142+
stack was never touched.

data/postgresql/initdb.sql.gz

1.25 MB
Binary file not shown.

dejacode/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from contextlib import suppress
1515
from pathlib import Path
1616

17-
VERSION = "5.7.1"
17+
VERSION = "5.8.0"
1818

1919
PROJECT_DIR = Path(__file__).resolve().parent
2020
ROOT_DIR = PROJECT_DIR.parent

product_portfolio/api.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,11 @@ class LoadSBOMsFormSerializer(serializers.Serializer):
243243
default=False,
244244
help_text=LoadSBOMsForm.base_fields["scan_all_packages"].help_text,
245245
)
246+
create_dependencies = serializers.BooleanField(
247+
required=False,
248+
default=False,
249+
help_text=LoadSBOMsForm.base_fields["create_dependencies"].help_text,
250+
)
246251

247252

248253
class ImportManifestsFormSerializer(serializers.Serializer):
@@ -268,6 +273,11 @@ class ImportManifestsFormSerializer(serializers.Serializer):
268273
default=False,
269274
help_text=ImportManifestsForm.base_fields["scan_all_packages"].help_text,
270275
)
276+
create_dependencies = serializers.BooleanField(
277+
required=False,
278+
default=False,
279+
help_text=ImportManifestsForm.base_fields["create_dependencies"].help_text,
280+
)
271281

272282

273283
class ImportFromScanSerializer(serializers.Serializer):
@@ -281,6 +291,11 @@ class ImportFromScanSerializer(serializers.Serializer):
281291
default=False,
282292
help_text=ImportFromScanForm.base_fields["create_codebase_resources"].help_text,
283293
)
294+
create_dependencies = serializers.BooleanField(
295+
required=False,
296+
default=False,
297+
help_text=ImportFromScanForm.base_fields["create_dependencies"].help_text,
298+
)
284299
stop_on_error = serializers.BooleanField(
285300
required=False,
286301
default=False,
@@ -300,6 +315,11 @@ class PullProjectDataSerializer(serializers.Serializer):
300315
default=False,
301316
help_text=PullProjectDataForm.base_fields["update_existing_packages"].help_text,
302317
)
318+
create_dependencies = serializers.BooleanField(
319+
required=False,
320+
default=False,
321+
help_text=PullProjectDataForm.base_fields["create_dependencies"].help_text,
322+
)
303323

304324

305325
class ScanCodeProjectSerializer(DataspacedSerializer):

product_portfolio/forms.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,15 @@ class ImportFromScanForm(forms.Form):
554554
"imported Packages."
555555
),
556556
)
557+
create_dependencies = forms.BooleanField(
558+
label=_("Create Dependencies"),
559+
required=False,
560+
initial=False,
561+
help_text=_(
562+
"When checked, dependency relationships between packages discovered in the "
563+
"import will be created on the Product."
564+
),
565+
)
557566
stop_on_error = forms.BooleanField(
558567
label=_("Stop and cancel import on data validation error"),
559568
required=False,
@@ -580,6 +589,7 @@ def helper(self):
580589
None,
581590
"upload_file",
582591
"create_codebase_resources",
592+
"create_dependencies",
583593
"stop_on_error",
584594
StrictSubmit("submit", _("Import"), css_class="btn-success col-2"),
585595
),
@@ -595,6 +605,7 @@ def save(self, product):
595605
self.user,
596606
upload_file=self.cleaned_data.get("upload_file"),
597607
create_codebase_resources=self.cleaned_data.get("create_codebase_resources"),
608+
create_dependencies=self.cleaned_data.get("create_dependencies"),
598609
stop_on_error=self.cleaned_data.get("stop_on_error"),
599610
)
600611

@@ -650,6 +661,15 @@ class BaseProductImportFormView(forms.Form):
650661
"from the Package URL (purl). A download URL is required for package scanning."
651662
),
652663
)
664+
create_dependencies = forms.BooleanField(
665+
label=_("Create Dependencies"),
666+
required=False,
667+
initial=False,
668+
help_text=_(
669+
"When checked, dependency relationships between packages discovered in the "
670+
"import will be created on the Product."
671+
),
672+
)
653673

654674
@property
655675
def helper(self):
@@ -664,6 +684,7 @@ def helper(self):
664684
"infer_download_urls",
665685
"update_existing_packages",
666686
"scan_all_packages",
687+
"create_dependencies",
667688
StrictSubmit("submit", _("Import"), css_class="btn-success col-2"),
668689
),
669690
)
@@ -678,6 +699,9 @@ def submit(self, product, user):
678699
update_existing_packages=self.cleaned_data.get("update_existing_packages"),
679700
scan_all_packages=self.cleaned_data.get("scan_all_packages"),
680701
infer_download_urls=self.cleaned_data.get("infer_download_urls"),
702+
import_options={
703+
"create_dependencies": self.cleaned_data.get("create_dependencies", False),
704+
},
681705
created_by=user,
682706
)
683707

@@ -975,6 +999,15 @@ class PullProjectDataForm(forms.Form):
975999
"without any modification."
9761000
),
9771001
)
1002+
create_dependencies = forms.BooleanField(
1003+
label=_("Create Dependencies"),
1004+
required=False,
1005+
initial=False,
1006+
help_text=_(
1007+
"When checked, dependency relationships between packages discovered in the "
1008+
"import will be created on the Product."
1009+
),
1010+
)
9781011

9791012
@property
9801013
def helper(self):
@@ -1007,6 +1040,9 @@ def submit(self, product, user):
10071040
project_uuid=project_data.get("uuid"),
10081041
update_existing_packages=self.cleaned_data.get("update_existing_packages"),
10091042
scan_all_packages=False,
1043+
import_options={
1044+
"create_dependencies": self.cleaned_data.get("create_dependencies", False),
1045+
},
10101046
status=ScanCodeProject.Status.SUBMITTED,
10111047
created_by=user,
10121048
)

0 commit comments

Comments
 (0)