Improve packages changelog (#1286)

Closes #1209

Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
Signed-off-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
Co-authored-by: Sergio Castaño Arteaga <tegioz@icloud.com>
Co-authored-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
This commit is contained in:
Sergio C. Arteaga 2021-05-03 20:31:12 +02:00 committed by GitHub
parent 4782c583e5
commit bf58fc2a1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 1544 additions and 689 deletions

View File

@ -12,7 +12,6 @@ declare
v_display_name text := nullif(p_pkg->>'display_name', '');
v_description text := nullif(p_pkg->>'description', '');
v_keywords text[] := (select nullif(array(select jsonb_array_elements_text(nullif(p_pkg->'keywords', 'null'::jsonb))), '{}'));
v_changes text[] := (select nullif(array(select jsonb_array_elements_text(nullif(p_pkg->'changes', 'null'::jsonb))), '{}'));
v_version text := p_pkg->>'version';
v_repository_id uuid := ((p_pkg->'repository')->>'repository_id')::uuid;
v_maintainer jsonb;
@ -181,7 +180,7 @@ begin
nullif(p_pkg->'containers_images', 'null'),
v_provider,
nullif(p_pkg->'values_schema', 'null'),
v_changes,
nullif(p_pkg->'changes', 'null'),
(p_pkg->>'contains_security_updates')::boolean,
(p_pkg->>'prerelease')::boolean,
nullif(p_pkg->'recommendations', 'null'),

View File

@ -0,0 +1,11 @@
alter table snapshot add column changes_tmp jsonb;
update snapshot set changes_tmp = (select json_agg(json_build_object('description', description)) from unnest(changes) as description) where changes is not null;
alter table snapshot drop column changes;
alter table snapshot rename column changes_tmp to changes;
---- create above / drop below ----
alter table snapshot add column changes_tmp text[];
update snapshot set changes_tmp = (select array_agg(entry->>'description') from jsonb_array_elements(changes) as entry) where changes is not null;
alter table snapshot drop column changes;
alter table snapshot rename column changes_tmp to changes;

View File

@ -127,7 +127,13 @@ insert into snapshot (
'[{"image": "quay.io/org/img:1.0.0"}]',
'Org Inc',
'{"key": "value"}',
'{"feature 1", "fix 1"}',
'[
{
"kind": "added",
"description": "feature 1",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
]',
true,
true,
'[{"url": "https://artifacthub.io/packages/helm/artifact-hub/artifact-hub"}]',
@ -299,8 +305,16 @@ select is(
"has_values_schema": true,
"has_changelog": true,
"changes": [
"feature 1",
"fix 1"
{
"kind": "added",
"description": "feature 1",
"links": [
{
"name": "github issue",
"url": "https://issue.url"
}
]
}
],
"ts": 1592299234,
"maintainers": [
@ -422,8 +436,16 @@ select is(
"has_values_schema": true,
"has_changelog": true,
"changes": [
"feature 1",
"fix 1"
{
"kind": "added",
"description": "feature 1",
"links": [
{
"name": "github issue",
"url": "https://issue.url"
}
]
}
],
"ts": 1592299234,
"maintainers": [

View File

@ -33,7 +33,18 @@ insert into snapshot (
:'package1ID',
'1.0.0',
'2020-06-16 11:20:34+02',
'{"feature 3", "fix 3"}',
'[
{
"kind": "added",
"description": "feature 3",
"links": [{"name": "github issue", "url": "https://issue.url"}]
},
{
"kind": "fixed",
"description": "fix 3",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
]',
true,
true
);
@ -48,7 +59,18 @@ insert into snapshot (
:'package1ID',
'0.0.9',
'2020-06-16 11:20:33+02',
'{"feature 2", "fix 2"}',
'[
{
"kind": "added",
"description": "feature 2",
"links": [{"name": "github issue", "url": "https://issue.url"}]
},
{
"kind": "fixed",
"description": "fix 2",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
]',
false,
false
);
@ -61,7 +83,18 @@ insert into snapshot (
:'package1ID',
'0.0.8',
'2020-06-16 11:20:32+02',
'{"feature 1", "fix 1"}'
'[
{
"kind": "added",
"description": "feature 1",
"links": [{"name": "github issue", "url": "https://issue.url"}]
},
{
"kind": "fixed",
"description": "fix 1",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
]'
);
-- Run some tests
@ -71,21 +104,54 @@ select is(
{
"version": "1.0.0",
"ts": 1592299234,
"changes": ["feature 3", "fix 3"],
"changes": [
{
"kind": "added",
"description": "feature 3",
"links": [{"name": "github issue", "url": "https://issue.url"}]
},
{
"kind": "fixed",
"description": "fix 3",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
],
"contains_security_updates": true,
"prerelease": true
},
{
"version": "0.0.9",
"ts": 1592299233,
"changes": ["feature 2", "fix 2"],
"changes": [
{
"kind": "added",
"description": "feature 2",
"links": [{"name": "github issue", "url": "https://issue.url"}]
},
{
"kind": "fixed",
"description": "fix 2",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
],
"contains_security_updates": false,
"prerelease": false
},
{
"version": "0.0.8",
"ts": 1592299232,
"changes": ["feature 1", "fix 1"]
"changes": [
{
"kind": "added",
"description": "feature 1",
"links": [{"name": "github issue", "url": "https://issue.url"}]
},
{
"kind": "fixed",
"description": "fix 1",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
]
}
]'::jsonb,
'Package changelog should be returned'

View File

@ -75,8 +75,16 @@ select register_package('
"key": "value"
},
"changes": [
"Added cool feature",
"Fixed minor bug"
{
"kind": "added",
"description": "feature 1",
"links": [
{
"name": "github issue",
"url": "https://issue.url"
}
]
}
],
"contains_security_updates": true,
"prerelease": true,
@ -195,10 +203,13 @@ select results_eq(
'[{"image": "quay.io/org/img:1.0.0"}]'::jsonb,
'Org Inc',
'{"key": "value"}'::jsonb,
'{
"Added cool feature",
"Fixed minor bug"
}'::text[],
'[
{
"kind": "added",
"description": "feature 1",
"links": [{"name": "github issue", "url": "https://issue.url"}]
}
]'::jsonb,
true,
true,
'[{"url": "https://artifacthub.io/packages/helm/artifact-hub/artifact-hub"}]'::jsonb,
@ -332,7 +343,7 @@ select results_eq(
'[{"image": "quay.io/org/img:2.0.0"}]'::jsonb,
'Org Inc 2',
null::jsonb,
null::text[],
null::jsonb,
null::boolean,
null::boolean,
'2020-06-16 11:20:35+02'::timestamptz

View File

@ -1802,7 +1802,31 @@ paths:
changes:
type: array
items:
type: string
type: object
required:
- description
properties:
description:
type: string
nullable: false
kind:
$ref: "#/components/schemas/ChangeKind"
links:
type: array
items:
type: object
required:
- name
- url
properties:
name:
type: string
nullable: false
url:
type: string
format: uri
nullable: false
nullable: false
nullable: false
contains_security_updates:
type: boolean
@ -2768,6 +2792,24 @@ components:
allowed_actions:
- addOrganizationMember
- addOrganizationRepository
ChangeKind:
type: string
enum:
- added
- changed
- deprecated
- removed
- fixed
- security
nullable: false
description: |
Types of changes:
* `added` - New features
* `changed` - Changes in existing functionality
* `deprecated` - Soon-to-be removed features
* `removed` - Removed features
* `fixed` - Any bug fixed
* `security` - In case of vulnerabilities
Error:
type: object
properties:

View File

@ -10,6 +10,8 @@ However, sometimes there might be cases in which it may be useful to provide som
This annotation is used to provide some details about the changes introduced by a given chart version. Artifact Hub can generate and display a **ChangeLog** based on the entries in the `changes` field in all your chart versions. You can see an example of how the changelog would look like in the Artifact Hub UI [here](https://artifacthub.io/packages/helm/artifact-hub/artifact-hub?modal=changelog).
This annotation can be provided using two different formats: using a plain list of strings with the description of the change or using a list of objects with some extra structured information (see example below). Please feel free to use the one that better suits your needs. The UI experience will be slightly different depending on the choice. When using the *list of objects* option the valid **supported kinds** are *added*, *changed*, *deprecated*, *removed*, *fixed* and *security*.
- **artifacthub.io/containsSecurityUpdates** *(boolean string, see example below)*
Use this annotation to indicate that this chart version contains security updates. When a package release contains security updates, a special message will be displayed in the Artifact Hub UI as well as in the new release email notification.
@ -63,6 +65,19 @@ annotations:
artifacthub.io/changes: |
- Added cool feature
- Fixed minor bug
artifacthub.io/changes: |
- kind: added
description: Cool feature
links:
- name: Github Issue
url: https://github.com/issue-url
- name: Github PR
url: https://github.com/pr-url
- kind: fixed
description: Minor bug
links:
- name: Github Issue
url: https://github.com/issue-url
artifacthub.io/containsSecurityUpdates: "true"
artifacthub.io/images: |
- name: img1

View File

@ -32,9 +32,19 @@ install: | # (optional)
Brief install instructions in markdown format
Content added here will be displayed when the INSTALL button on the package details page is clicked.
changes: # (optional)
- A list of changes introduced in this package version
- Use one entry for each of them
changes: # (optional - it is also possible to provide a list of strings with just the descriptions instead of using objects)
- kind: added # Supported kinds are: added, changed, deprecated, removed, fixed and security
description: cool feature
links:
- name: Github Issue
url: https://github.com/issue-url
- name: Github PR
url: https://github.com/pr-url
- kind: fixed
description: minor bug
links:
- name: Github Issue
url: https://github.com/issue-url
maintainers: # (optional)
- name: The maintainer name (required for each maintainer)
email: The maintainer email (required for each maintainer)

View File

@ -10,6 +10,8 @@ However, sometimes there might be cases in which it may be useful to provide som
This annotation is used to provide some details about the changes introduced by a given operator version. Artifact Hub can generate and display a **ChangeLog** based on the entries in the `changes` field in all your operator versions. You can see an example of how the changelog would look like in the Artifact Hub UI [here](https://artifacthub.io/packages/helm/artifact-hub/artifact-hub?modal=changelog).
This annotation can be provided using two different formats: using a plain list of strings with the description of the change or using a list of objects with some extra structured information (see example below). Please feel free to use the one that better suits your needs. The UI experience will be slightly different depending on the choice. When using the *list of objects* option the valid **supported kinds** are *added*, *changed*, *deprecated*, *removed*, *fixed* and *security*.
- **artifacthub.io/containsSecurityUpdates** *(boolean string, see example below)*
Use this annotation to indicate that this operator version contains security updates. When a package release contains security updates, a special message will be displayed in the Artifact Hub UI as well as in the new release email notification.
@ -44,6 +46,19 @@ metadata:
artifacthub.io/changes: |
- Added cool feature
- Fixed minor bug
artifacthub.io/changes: |
- kind: added
description: Cool feature
links:
- name: Github Issue
url: https://github.com/issue-url
- name: Github PR
url: https://github.com/pr-url
- kind: fixed
description: Minor bug
links:
- name: Github Issue
url: https://github.com/issue-url
artifacthub.io/containsSecurityUpdates: "true"
artifacthub.io/imagesWhitelist: |
- repo/img2:2.0.0

View File

@ -10,6 +10,8 @@ However, sometimes there might be cases in which it may be useful to provide som
This annotation is used to provide some details about the changes introduced by a given task version. Artifact Hub can generate and display a **ChangeLog** based on the entries in the `changes` field in all your task versions. You can see an example of how the changelog would look like in the Artifact Hub UI [here](https://artifacthub.io/packages/helm/artifact-hub/artifact-hub?modal=changelog).
This annotation can be provided using two different formats: using a plain list of strings with the description of the change or using a list of objects with some extra structured information (see example below). Please feel free to use the one that better suits your needs. The UI experience will be slightly different depending on the choice. When using the *list of objects* option the valid **supported kinds** are *added*, *changed*, *deprecated*, *removed*, *fixed* and *security*.
- **artifacthub.io/license** *(string)*
Use this annotation to indicate the package's license. It must be a valid [SPDX identifier](https://spdx.org/licenses/).
@ -40,6 +42,19 @@ metadata:
artifacthub.io/changes: |
- Added cool feature
- Fixed minor bug
artifacthub.io/changes: |
- kind: added
description: Cool feature
links:
- name: Github Issue
url: https://github.com/issue-url
- name: Github PR
url: https://github.com/pr-url
- kind: fixed
description: Minor bug
links:
- name: Github Issue
url: https://github.com/issue-url
artifacthub.io/license: Apache-2.0
artifacthub.io/links: |
- name: link1

View File

@ -174,23 +174,27 @@ func (h *Handlers) Update(w http.ResponseWriter, r *http.Request) {
var webhookTestTemplateData = &hub.PackageNotificationTemplateData{
BaseURL: "https://artifacthub.io",
Event: map[string]interface{}{
"id": "00000000-0000-0000-0000-000000000001",
"kind": "package.new-release",
"ID": "00000000-0000-0000-0000-000000000001",
"Kind": "package.new-release",
},
Package: map[string]interface{}{
"name": "sample-package",
"version": "1.0.0",
"url": "https://artifacthub.io/packages/helm/artifacthub/sample-package/1.0.0",
"changes": []string{
"Cool feature",
"Bug fixed",
"Name": "sample-package",
"Version": "1.0.0",
"URL": "https://artifacthub.io/packages/helm/artifacthub/sample-package/1.0.0",
"Changes": []*hub.Change{
{
Description: "Cool feature",
},
{
Description: "Bug fixed",
},
},
"containsSecurityUpdates": true,
"prerelease": true,
"repository": map[string]interface{}{
"kind": "helm",
"name": "repo1",
"publisher": "org1",
"ContainsSecurityUpdates": true,
"Prerelease": true,
"Repository": map[string]interface{}{
"Kind": "helm",
"Name": "repo1",
"Publisher": "org1",
},
},
}

View File

@ -539,7 +539,7 @@ func TestTriggerTest(t *testing.T) {
{
"2",
"custom/type",
"Package {{ .Package.name }} {{ .Package.version}} updated!",
"Package {{ .Package.Name }} {{ .Package.Version}} updated!",
"very",
[]byte("Package sample-package 1.0.0 updated!"),
},

View File

@ -11,6 +11,13 @@ const (
PackageMetadataFile = "artifacthub-pkg"
)
// Change represents a change introduced in a package version.
type Change struct {
Kind string `json:"kind,omitempty"`
Description string `json:"description"`
Links []*Link `json:"links,omitempty"`
}
// Channel represents a package's channel.
type Channel struct {
Name string `json:"name"`
@ -82,7 +89,7 @@ type Package struct {
HasValuesSchema bool `json:"has_values_schema"`
ValuesSchema json.RawMessage `json:"values_schema,omitempty"`
HasChangeLog bool `json:"has_changelog"`
Changes []string `json:"changes"`
Changes []*Change `json:"changes"`
ContainsSecurityUpdates bool `json:"contains_security_updates"`
Prerelease bool `json:"prerelease"`
Maintainers []*Maintainer `json:"maintainers"`
@ -138,9 +145,9 @@ type PackageMetadata struct {
Links []*Link `yaml:"links"`
Readme string `yaml:"readme"`
Install string `yaml:"install"`
Changes []string `yaml:"changes"`
Changes []*Change `yaml:"changes"`
ContainsSecurityUpdates bool `yaml:"containsSecurityUpdates"`
Prerelease bool `json:"prerelease"`
Prerelease bool `yaml:"prerelease"`
Maintainers []*Maintainer `yaml:"maintainers"`
Provider *Provider `yaml:"provider"`
Ignore []string `yaml:"ignore"`

View File

@ -8,7 +8,7 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>{{ .Package.name }} new release</title>
<title>{{ .Package.Name }} new release</title>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
@ -145,6 +145,39 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
border: 1px solid #856404;
}
.badge {
padding: 0 10px;
border-radius: 8px;
font-size: 10px;
text-transform: uppercase;
color: #ffffff;
width: 75px;
}
.badge-added {
background-color: #0594cb;
}
.badge-changed {
background-color: #e0ae0b;
}
.badge-deprecated {
background-color: #6c757d;
}
.badge-removed {
background-color: #f7860f;
}
.badge-fixed {
background-color: #28a745;
}
.badge-security {
background-color: #df2a29;
}
@media (prefers-color-scheme: dark ) {
.body {
background-color: #222529 !important;
@ -195,7 +228,7 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Package.name }} version {{ .Package.version }} released</span>
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Package.Name }} version {{ .Package.Version }} released</span>
<table class="main line" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
@ -204,8 +237,8 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top; text-align: center;">
<img style="margin: 30px;" height="40px" src="{{ .BaseURL }}{{ if .Package.logoImageID }}/image/{{ .Package.logoImageID }}@3x{{ else }}/static/media/placeholder_pkg_{{ .Package.repository.kind }}.png{{ end }}">
<h2 class="title" style="font-family: sans-serif; margin: 0; Margin-bottom: 15px;"><img style="margin-right: 5px; margin-bottom: -2px;" height="18px" src="{{ .BaseURL }}/static/media/{{ .Package.repository.kind }}_icon.png">{{ .Package.name }}</h2>
<img style="margin: 30px;" height="40px" src="{{ .BaseURL }}{{ if .Package.LogoImageID }}/image/{{ .Package.LogoImageID }}@3x{{ else }}/static/media/placeholder_pkg_{{ .Package.Repository.Kind }}.png{{ end }}">
<h2 class="title" style="font-family: sans-serif; margin: 0; Margin-bottom: 15px;"><img style="margin-right: 5px; margin-bottom: -2px;" height="18px" src="{{ .BaseURL }}/static/media/{{ .Package.Repository.Kind }}_icon.png">{{ .Package.Name }}</h2>
<h4 class="subtitle" style="font-family: sans-serif; margin: 0; Margin-bottom: 15px;">{{ .Package.repository.publisher }} </h4>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 30px;">Version <b>{{ .Package.version }}</b> has been released</p>
@ -214,11 +247,11 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<tr>
<td>
{{ if .Package.prerelease }}
{{ if .Package.Prerelease }}
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;">
<tbody>
<tr>
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-top: 5px; padding-bottom: {{ if .Package.containsSecurityUpdates }} 15px; {{ else }} 30px;{{ end }}">
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-top: 5px; padding-bottom: {{ if .Package.ContainsSecurityUpdates }} 15px; {{ else }} 30px;{{ end }}">
<div class="warning" style="border-radius: 5px; box-sizing: border-box; cursor: pointer; font-size: 14px; font-weight: 400; margin: 0; padding: 12px 20px; text-align: left;">This package version is a <b>pre-release</b> and it is not ready for production use.</div>
</td>
</tr>
@ -230,7 +263,7 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<tr>
<td>
{{ if .Package.containsSecurityUpdates }}
{{ if .Package.ContainsSecurityUpdates }}
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;">
<tbody>
<tr>
@ -246,14 +279,37 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<tr>
<td style="font-family: sans-serif; font-size: 14px;">
{{ if .Package.changes }}
{{ if .Package.Changes }}
<hr class="hr" style="border-bottom: none;" />
<h4 class="subtitle" style="font-family: sans-serif; font-size: 12px; Margin-top: 20px;">CHANGES:</h4>
<ul style="Margin-bottom: 20px;">
{{range $change := .Package.changes}}
<li>{{$change}}</li>
{{end}}
</ul>
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
{{range $change := .Package.Changes}}
<tr>
<td style="vertical-align: top; padding-top: 2px; padding-right: 10px;">
{{ if $change.Kind}}
<div class="badge badge-{{ $change.Kind }}" style="text-align: center;">{{ $change.Kind }}</div>
{{ else }}
<p style="margin: 0;">&bull;</p>
{{ end }}
</td>
<td>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 10px;">
{{ $change.Description }}
{{if $change.Links}}
<br />
{{range $i, $link := $change.Links}}
{{if $i}} &bull; {{end}}
<a href="{{ $link.URL }}" class="AHlink" style="font-size: 12px; text-align: center; text-decoration: none;">{{ $link.Name }}</a>
{{end}}
{{ end }}
</p>
</td>
</tr>
{{ end }}
</tbody>
</table>
<hr class="hr" style="border-bottom: none;" />
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 45px;"></p>
{{ end }}
@ -269,7 +325,7 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt;">
<tbody>
<tr>
<td style="font-family: sans-serif; font-size: 14px; border-radius: 5px; vertical-align: top;"><div style="text-align: center;"> <a href="{{ .Package.url }}" class="AHbtn" target="_blank" style="display: inline-block; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px;">View in Artifact Hub</a> </div></td>
<td style="font-family: sans-serif; font-size: 14px; border-radius: 5px; vertical-align: top;"><div style="text-align: center;"> <a href="{{ .Package.URL }}" class="AHbtn" target="_blank" style="display: inline-block; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px;">View in Artifact Hub</a> </div></td>
</tr>
</tbody>
</table>
@ -282,7 +338,7 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<tbody>
<tr>
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; font-size: 11px; padding-bottom: 30px; padding-top: 10px;">
<p class="text-muted" style="font-size: 11px; text-decoration: none;">Or you can copy-paste this link: <span class="copy-link">{{ .Package.url }}</span></p>
<p class="text-muted" style="font-size: 11px; text-decoration: none;">Or you can copy-paste this link: <span class="copy-link">{{ .Package.URL }}</span></p>
</td>
</tr>
</tbody>
@ -301,7 +357,7 @@ var newReleaseEmailTmpl = template.Must(template.New("").Parse(`
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 10px; text-align: center;">
<p class="text-muted" style="font-size: 10px; text-align: center; text-decoration: none;">Didn't subscribe to Artifact Hub notifications for {{ .Package.name }} package? You can unsubscribe <a href="{{ .BaseURL }}/control-panel/settings/subscriptions" target="_blank" class="text-muted" style="text-decoration: underline;">here</a>.</p>
<p class="text-muted" style="font-size: 10px; text-align: center; text-decoration: none;">Didn't subscribe to Artifact Hub notifications for {{ .Package.Name }} package? You can unsubscribe <a href="{{ .BaseURL }}/control-panel/settings/subscriptions" target="_blank" class="text-muted" style="text-decoration: underline;">here</a>.</p>
</td>
</tr>
<tr>

View File

@ -8,7 +8,7 @@ var ownershipClaimEmailTmpl = template.Must(template.New("").Parse(`
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>{{ .Repository.name }} repository ownership has been claimed</title>
<title>{{ .Repository.Name }} repository ownership has been claimed</title>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
@ -173,7 +173,7 @@ var ownershipClaimEmailTmpl = template.Must(template.New("").Parse(`
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Repository.name }} repository ownership has been claimed</span>
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Repository.Name }} repository ownership has been claimed</span>
<table class="main line" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
@ -182,8 +182,8 @@ var ownershipClaimEmailTmpl = template.Must(template.New("").Parse(`
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<h4 style="font-family: sans-serif; margin: 0; Margin-bottom: 30px;"><span class="AHlink">{{ .Repository.name }}</span> repository has been transferred to {{ if .Repository.userAlias }} user <span class="AHlink">{{ .Repository.userAlias }}</span> {{ else }} organization <span class="AHlink">{{ .Repository.organizationName }}</span> {{ end }}</h4>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 30px;">{{ if .Repository.userAlias }} User <b>{{ .Repository.userAlias }}</b> {{ else }} Organization <b>{{ .Repository.organizationName }}</b> {{ end }} claimed the ownership of the <b>{{ .Repository.name }}</b> repository. After successfully verifying that the claiming entity owns it, we have proceeded with the transfer.</p>
<h4 style="font-family: sans-serif; margin: 0; Margin-bottom: 30px;"><span class="AHlink">{{ .Repository.Name }}</span> repository has been transferred to {{ if .Repository.UserAlias }} user <span class="AHlink">{{ .Repository.UserAlias }}</span> {{ else }} organization <span class="AHlink">{{ .Repository.OrganizationName }}</span> {{ end }}</h4>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 30px;">{{ if .Repository.UserAlias }} User <b>{{ .Repository.UserAlias }}</b> {{ else }} Organization <b>{{ .Repository.OrganizationName }}</b> {{ end }} claimed the ownership of the <b>{{ .Repository.Name }}</b> repository. After successfully verifying that the claiming entity owns it, we have proceeded with the transfer.</p>
</td>
</tr>
</table>

View File

@ -8,7 +8,7 @@ var scanningErrorsEmailTmpl = template.Must(template.New("").Parse(`
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>{{ .Repository.name }} scanning errors</title>
<title>{{ .Repository.Name }} scanning errors</title>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
@ -173,7 +173,7 @@ var scanningErrorsEmailTmpl = template.Must(template.New("").Parse(`
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Repository.name }} security vulnerabilities scan errors</span>
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Repository.Name }} security vulnerabilities scan errors</span>
<table class="main line-danger" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
@ -183,7 +183,7 @@ var scanningErrorsEmailTmpl = template.Must(template.New("").Parse(`
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
We encountered some errors while scanning the packages in repository <strong>{{ .Repository.name }}</strong> for security vulnerabilities.
We encountered some errors while scanning the packages in repository <strong>{{ .Repository.Name }}</strong> for security vulnerabilities.
</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 30px;">
@ -197,7 +197,7 @@ var scanningErrorsEmailTmpl = template.Must(template.New("").Parse(`
<tr>
<td align="left" style="font-family: sans-serif; font-size: 14px; vertical-align: top; padding: 16px;">
<code style="overflow-x: auto;">
{{ range $index, $scanningError := .Repository.lastScanningErrors }}
{{ range $index, $scanningError := .Repository.LastScanningErrors }}
{{ if $index }}
<p style="font-family: 'Courier New', Courier, monospace; color: #C5C8C6 !important; border-top: 1px solid #333; padding-top: 15px; font-size: 13px; ">{{ $scanningError }}</p>
{{ else }}
@ -217,7 +217,7 @@ var scanningErrorsEmailTmpl = template.Must(template.New("").Parse(`
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt;">
<tbody>
<tr>
<td style="font-family: sans-serif; font-size: 14px; border-radius: 5px; vertical-align: top;"><div style="text-align: center;"> <a href="{{ .BaseURL }}/control-panel/repositories?modal=scanning&user-alias={{ .Repository.userAlias }}&org-name={{ .Repository.organizationName }}&repo-name={{ .Repository.name }}" class="AHbtn" target="_blank" style="display: inline-block; color: #ffffff; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px;">View in Artifact Hub</a> </div></td>
<td style="font-family: sans-serif; font-size: 14px; border-radius: 5px; vertical-align: top;"><div style="text-align: center;"> <a href="{{ .BaseURL }}/control-panel/repositories?modal=scanning&user-alias={{ .Repository.UserAlias }}&org-name={{ .Repository.OrganizationName }}&repo-name={{ .Repository.Name }}" class="AHbtn" target="_blank" style="display: inline-block; color: #ffffff; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px;">View in Artifact Hub</a> </div></td>
</tr>
</tbody>
</table>
@ -230,7 +230,7 @@ var scanningErrorsEmailTmpl = template.Must(template.New("").Parse(`
<tbody>
<tr>
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; font-size: 11px; padding-bottom: 10px; padding-top: 10px; text-align: center;">
<p class="text-muted" style="font-size: 11px; text-decoration: none;">Or you can copy-paste this link: <span class="copy-link" style="text-align: center;">{{ .BaseURL }}/control-panel/repositories?modal=scanning&user-alias={{ .Repository.userAlias }}&org-name={{ .Repository.organizationName }}&repo-name={{ .Repository.name }}</span></p>
<p class="text-muted" style="font-size: 11px; text-decoration: none;">Or you can copy-paste this link: <span class="copy-link" style="text-align: center;">{{ .BaseURL }}/control-panel/repositories?modal=scanning&user-alias={{ .Repository.UserAlias }}&org-name={{ .Repository.OrganizationName }}&repo-name={{ .Repository.Name }}</span></p>
</td>
</tr>
</tbody>

View File

@ -8,7 +8,7 @@ var trackingErrorsEmailTmpl = template.Must(template.New("").Parse(`
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>{{ .Repository.name }} tracking errors</title>
<title>{{ .Repository.Name }} tracking errors</title>
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
@ -173,7 +173,7 @@ var trackingErrorsEmailTmpl = template.Must(template.New("").Parse(`
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Repository.name }} tracking errors</span>
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{ .Repository.Name }} tracking errors</span>
<table class="main line-danger" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
@ -183,7 +183,7 @@ var trackingErrorsEmailTmpl = template.Must(template.New("").Parse(`
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
We encountered some errors while tracking repository <strong>{{ .Repository.name }}</strong>.
We encountered some errors while tracking repository <strong>{{ .Repository.Name }}</strong>.
</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
@ -201,7 +201,7 @@ var trackingErrorsEmailTmpl = template.Must(template.New("").Parse(`
<tr>
<td align="left" style="font-family: sans-serif; font-size: 14px; vertical-align: top; padding: 16px;">
<code style="overflow-x: auto;">
{{ range $index, $trackingError := .Repository.lastTrackingErrors }}
{{ range $index, $trackingError := .Repository.LastTrackingErrors }}
{{ if $index }}
<p style="font-family: 'Courier New', Courier, monospace; color: #C5C8C6 !important; border-top: 1px solid #333; padding-top: 15px; font-size: 13px; ">{{ $trackingError }}</p>
{{ else }}
@ -221,7 +221,7 @@ var trackingErrorsEmailTmpl = template.Must(template.New("").Parse(`
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt;">
<tbody>
<tr>
<td style="font-family: sans-serif; font-size: 14px; border-radius: 5px; vertical-align: top;"><div style="text-align: center;"> <a href="{{ .BaseURL }}/control-panel/repositories?modal=tracking&user-alias={{ .Repository.userAlias }}&org-name={{ .Repository.organizationName }}&repo-name={{ .Repository.name }}" class="AHbtn" target="_blank" style="display: inline-block; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px;">View in Artifact Hub</a> </div></td>
<td style="font-family: sans-serif; font-size: 14px; border-radius: 5px; vertical-align: top;"><div style="text-align: center;"> <a href="{{ .BaseURL }}/control-panel/repositories?modal=tracking&user-alias={{ .Repository.UserAlias }}&org-name={{ .Repository.OrganizationName }}&repo-name={{ .Repository.Name }}" class="AHbtn" target="_blank" style="display: inline-block; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px;">View in Artifact Hub</a> </div></td>
</tr>
</tbody>
</table>
@ -234,7 +234,7 @@ var trackingErrorsEmailTmpl = template.Must(template.New("").Parse(`
<tbody>
<tr>
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; font-size: 11px; padding-bottom: 10px; padding-top: 10px; text-align: center;">
<p class="text-muted" style="font-size: 11px; text-decoration: none;">Or you can copy-paste this link: <span class="copy-link" style="text-align: center;">{{ .BaseURL }}/control-panel/repositories?modal=tracking&user-alias={{ .Repository.userAlias }}&org-name={{ .Repository.organizationName }}&repo-name={{ .Repository.name }}</span></p>
<p class="text-muted" style="font-size: 11px; text-decoration: none;">Or you can copy-paste this link: <span class="copy-link" style="text-align: center;">{{ .BaseURL }}/control-panel/repositories?modal=tracking&user-alias={{ .Repository.UserAlias }}&org-name={{ .Repository.OrganizationName }}&repo-name={{ .Repository.Name }}</span></p>
</td>
</tr>
</tbody>

View File

@ -199,7 +199,7 @@ func (w *Worker) prepareEmailData(ctx context.Context, e *hub.Event) (email.Data
if err != nil {
return email.Data{}, err
}
subject = fmt.Sprintf("%s version %s released", tmplData.Package["name"], tmplData.Package["version"])
subject = fmt.Sprintf("%s version %s released", tmplData.Package["Name"], tmplData.Package["Version"])
if err := newReleaseEmailTmpl.Execute(&emailBody, tmplData); err != nil {
return email.Data{}, err
}
@ -208,7 +208,7 @@ func (w *Worker) prepareEmailData(ctx context.Context, e *hub.Event) (email.Data
if err != nil {
return email.Data{}, err
}
subject = fmt.Sprintf("Something went wrong scanning repository %s", tmplData.Repository["name"])
subject = fmt.Sprintf("Something went wrong scanning repository %s", tmplData.Repository["Name"])
if err := scanningErrorsEmailTmpl.Execute(&emailBody, tmplData); err != nil {
return email.Data{}, err
}
@ -217,7 +217,7 @@ func (w *Worker) prepareEmailData(ctx context.Context, e *hub.Event) (email.Data
if err != nil {
return email.Data{}, err
}
subject = fmt.Sprintf("Something went wrong tracking repository %s", tmplData.Repository["name"])
subject = fmt.Sprintf("Something went wrong tracking repository %s", tmplData.Repository["Name"])
if err := trackingErrorsEmailTmpl.Execute(&emailBody, tmplData); err != nil {
return email.Data{}, err
}
@ -226,7 +226,7 @@ func (w *Worker) prepareEmailData(ctx context.Context, e *hub.Event) (email.Data
if err != nil {
return email.Data{}, err
}
subject = fmt.Sprintf("%s repository ownership has been claimed", tmplData.Repository["name"])
subject = fmt.Sprintf("%s repository ownership has been claimed", tmplData.Repository["Name"])
if err := ownershipClaimEmailTmpl.Execute(&emailBody, tmplData); err != nil {
return email.Data{}, err
}
@ -276,21 +276,21 @@ func (w *Worker) preparePkgNotificationTemplateData(
return &hub.PackageNotificationTemplateData{
BaseURL: w.baseURL,
Event: map[string]interface{}{
"id": e.EventID,
"kind": eventKindStr,
"ID": e.EventID,
"Kind": eventKindStr,
},
Package: map[string]interface{}{
"name": p.Name,
"version": p.Version,
"logoImageID": p.LogoImageID,
"url": pkg.BuildURL(w.baseURL, p, e.PackageVersion),
"changes": p.Changes,
"containsSecurityUpdates": p.ContainsSecurityUpdates,
"prerelease": p.Prerelease,
"repository": map[string]interface{}{
"kind": hub.GetKindName(p.Repository.Kind),
"name": p.Repository.Name,
"publisher": publisher,
"Name": p.Name,
"Version": p.Version,
"LogoImageID": p.LogoImageID,
"URL": pkg.BuildURL(w.baseURL, p, e.PackageVersion),
"Changes": p.Changes,
"ContainsSecurityUpdates": p.ContainsSecurityUpdates,
"Prerelease": p.Prerelease,
"Repository": map[string]interface{}{
"Kind": hub.GetKindName(p.Repository.Kind),
"Name": p.Repository.Name,
"Publisher": publisher,
},
},
}, nil
@ -331,16 +331,16 @@ func (w *Worker) prepareRepoNotificationTemplateData(
return &hub.RepositoryNotificationTemplateData{
BaseURL: w.baseURL,
Event: map[string]interface{}{
"id": e.EventID,
"kind": eventKindStr,
"ID": e.EventID,
"Kind": eventKindStr,
},
Repository: map[string]interface{}{
"kind": hub.GetKindName(r.Kind),
"name": r.Name,
"userAlias": r.UserAlias,
"organizationName": r.OrganizationName,
"lastScanningErrors": strings.Split(r.LastScanningErrors, "\n"),
"lastTrackingErrors": strings.Split(r.LastTrackingErrors, "\n"),
"Kind": hub.GetKindName(r.Kind),
"Name": r.Name,
"UserAlias": r.UserAlias,
"OrganizationName": r.OrganizationName,
"LastScanningErrors": strings.Split(r.LastScanningErrors, "\n"),
"LastTrackingErrors": strings.Split(r.LastTrackingErrors, "\n"),
},
}, nil
}
@ -350,22 +350,22 @@ func (w *Worker) prepareRepoNotificationTemplateData(
var DefaultWebhookPayloadTmpl = template.Must(template.New("").Parse(`
{
"specversion" : "1.0",
"id" : "{{ .Event.id }}",
"id" : "{{ .Event.ID }}",
"source" : "https://artifacthub.io/cloudevents",
"type" : "io.artifacthub.{{ .Event.kind }}",
"type" : "io.artifacthub.{{ .Event.Kind }}",
"datacontenttype" : "application/json",
"data" : {
"package": {
"name": "{{ .Package.name }}",
"version": "{{ .Package.version }}",
"url": "{{ .Package.url }}",
"changes": [{{range $i, $e := .Package.changes}}{{if $i}}, {{end}}"{{.}}"{{end}}],
"containsSecurityUpdates": {{ .Package.containsSecurityUpdates }},
"prerelease": {{ .Package.prerelease }},
"name": "{{ .Package.Name }}",
"version": "{{ .Package.Version }}",
"url": "{{ .Package.URL }}",
"changes": [{{range $i, $e := .Package.Changes}}{{if $i}}, {{end}}"{{.Description}}"{{end}}],
"containsSecurityUpdates": {{ .Package.ContainsSecurityUpdates }},
"prerelease": {{ .Package.Prerelease }},
"repository": {
"kind": "{{ .Package.repository.kind }}",
"name": "{{ .Package.repository.name }}",
"publisher": "{{ .Package.repository.publisher }}"
"kind": "{{ .Package.Repository.Kind }}",
"name": "{{ .Package.Repository.Name }}",
"publisher": "{{ .Package.Repository.Publisher }}"
}
}
}

View File

@ -63,9 +63,15 @@ func TestWorker(t *testing.T) {
Name: "package1",
NormalizedName: "package1",
Version: "1.0.0",
Changes: []string{
"Cool feature",
"Bug fixed",
Changes: []*hub.Change{
{
Kind: "added",
Description: "feature 1",
},
{
Kind: "fixed",
Description: "bug 1",
},
},
ContainsSecurityUpdates: true,
Prerelease: true,
@ -268,7 +274,7 @@ func TestWorker(t *testing.T) {
"name": "package1",
"version": "1.0.0",
"url": "http://baseURL/packages/helm/repo1/package1/1.0.0",
"changes": ["Cool feature", "Bug fixed"],
"changes": ["feature 1", "bug 1"],
"containsSecurityUpdates": true,
"prerelease": true,
"repository": {
@ -284,7 +290,7 @@ func TestWorker(t *testing.T) {
{
"2",
"custom/type",
"Package {{ .Package.name }} {{ .Package.version}} updated!",
"Package {{ .Package.Name }} {{ .Package.Version}} updated!",
"very",
[]byte("Package package1 1.0.0 updated!"),
},

View File

@ -108,9 +108,17 @@ func TestGet(t *testing.T) {
},
},
Provider: "Org Inc",
Changes: []string{
"feature 1",
"fix 1",
Changes: []*hub.Change{
{
Kind: "added",
Description: "feature 1",
Links: []*hub.Link{
{
Name: "github issue",
URL: "https://issue.url",
},
},
},
},
Maintainers: []*hub.Maintainer{
{
@ -205,8 +213,16 @@ func TestGet(t *testing.T) {
],
"provider": "Org Inc",
"changes": [
"feature 1",
"fix 1"
{
"kind": "added",
"description": "feature 1",
"links": [
{
"name": "github issue",
"url": "https://issue.url"
}
]
}
],
"maintainers": [
{

View File

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io/ioutil"
"strings"
"time"
"github.com/Masterminds/semver/v3"
@ -14,6 +15,16 @@ import (
var (
// ErrInvalidMetadata indicates that the metadata provided is not valid.
ErrInvalidMetadata = errors.New("invalid metadata")
// validChangeKinds is the list of valid kinds that a pkg change can use.
validChangeKinds = []string{
"added",
"changed",
"deprecated",
"removed",
"fixed",
"security",
}
)
// GetPackageMetadata reads, parses and validates the package metadata file provided.
@ -48,6 +59,9 @@ func PreparePackageFromMetadata(md *hub.PackageMetadata) (*hub.Package, error) {
if err := ValidatePackageMetadata(md); err != nil {
return nil, err
}
for _, change := range md.Changes {
NormalizeChange(change)
}
sv, _ := semver.NewVersion(md.Version)
p := &hub.Package{
Name: md.Name,
@ -102,5 +116,44 @@ func ValidatePackageMetadata(md *hub.PackageMetadata) error {
if md.Description == "" {
return fmt.Errorf("%w: %s", ErrInvalidMetadata, "description not provided")
}
for _, change := range md.Changes {
if err := ValidateChange(change); err != nil {
return fmt.Errorf("%w: %v", ErrInvalidMetadata, err)
}
}
return nil
}
// ValidateChange validates if the provided change is valid.
func ValidateChange(change *hub.Change) error {
if change.Kind != "" && !isValidChangeKind(change.Kind) {
return fmt.Errorf("invalid change: invalid kind: %s", change.Kind)
}
if change.Description == "" {
return errors.New("invalid change: description not provided")
}
for _, link := range change.Links {
if link.Name == "" {
return errors.New("invalid change: link name not provided")
}
if link.URL == "" {
return errors.New("invalid change: link url not provided")
}
}
return nil
}
// NormalizeChange normalizes some values of the change provided when needed.
func NormalizeChange(change *hub.Change) {
change.Kind = strings.ToLower(change.Kind)
}
// isValidChange checks if the provided change is valid.
func isValidChangeKind(kind string) bool {
for _, validKind := range validChangeKinds {
if strings.ToLower(kind) == validKind {
return true
}
}
return false
}

View File

@ -88,9 +88,15 @@ func TestPreparePackageFromMetadata(t *testing.T) {
},
Readme: "Package readme",
Install: "Package install",
Changes: []string{
"feature 1",
"fix 1",
Changes: []*hub.Change{
{
Kind: "Added",
Description: "feature 1",
},
{
Kind: "Fixed",
Description: "issue 1",
},
},
ContainsSecurityUpdates: true,
Prerelease: true,
@ -138,9 +144,15 @@ func TestPreparePackageFromMetadata(t *testing.T) {
},
},
Provider: "Package provider",
Changes: []string{
"feature 1",
"fix 1",
Changes: []*hub.Change{
{
Kind: "added",
Description: "feature 1",
},
{
Kind: "fixed",
Description: "issue 1",
},
},
ContainsSecurityUpdates: true,
Prerelease: true,
@ -230,6 +242,79 @@ func TestValidatePackageMetadata(t *testing.T) {
},
"description not provided",
},
{
&hub.PackageMetadata{
Version: "1.0.0",
Name: "pkg1",
DisplayName: "Package 1",
CreatedAt: "2006-01-02T15:04:05Z",
Description: "description",
Changes: []*hub.Change{
{
Kind: "test",
Description: "description",
},
},
},
"invalid change: invalid kind: test",
},
{
&hub.PackageMetadata{
Version: "1.0.0",
Name: "pkg1",
DisplayName: "Package 1",
CreatedAt: "2006-01-02T15:04:05Z",
Description: "description",
Changes: []*hub.Change{
{
Kind: "added",
},
},
},
"invalid change: description not provided",
},
{
&hub.PackageMetadata{
Version: "1.0.0",
Name: "pkg1",
DisplayName: "Package 1",
CreatedAt: "2006-01-02T15:04:05Z",
Description: "description",
Changes: []*hub.Change{
{
Kind: "added",
Description: "feature 1",
Links: []*hub.Link{
{
URL: "https://link1.url",
},
},
},
},
},
"invalid change: link name not provided",
},
{
&hub.PackageMetadata{
Version: "1.0.0",
Name: "pkg1",
DisplayName: "Package 1",
CreatedAt: "2006-01-02T15:04:05Z",
Description: "description",
Changes: []*hub.Change{
{
Kind: "added",
Description: "feature 1",
Links: []*hub.Link{
{
Name: "link1",
},
},
},
},
},
"invalid change: link url not provided",
},
}
for _, tc := range testCases {
tc := tc
@ -250,6 +335,18 @@ func TestValidatePackageMetadata(t *testing.T) {
DisplayName: "Package 1",
CreatedAt: "2006-01-02T15:04:05Z",
Description: "Package description",
Changes: []*hub.Change{
{
Kind: "Added",
Description: "feature 1",
Links: []*hub.Link{
{
Name: "link1",
URL: "https://link1.url",
},
},
},
},
}
err := ValidatePackageMetadata(md)
assert.Nil(t, err)

View File

@ -63,6 +63,20 @@ var (
// GitRepoURLRE is a regexp used to validate and parse a git based
// repository URL.
GitRepoURLRE = regexp.MustCompile(`^(https:\/\/(github|gitlab)\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)\/?(.*)$`)
// validRepositoryKinds contains the repository kinds supported.
validRepositoryKinds = []hub.RepositoryKind{
hub.Falco,
hub.Helm,
hub.HelmPlugin,
hub.Krew,
hub.OLM,
hub.OPA,
hub.TBAction,
hub.TektonTask,
hub.KedaScaler,
hub.CoreDNS,
}
)
// Manager provides an API to manage repositories.
@ -710,18 +724,7 @@ func isSchemeSupported(u *url.URL) bool {
// isValidKind checks if the provided repository kind is valid.
func isValidKind(kind hub.RepositoryKind) bool {
for _, validKind := range []hub.RepositoryKind{
hub.Falco,
hub.Helm,
hub.HelmPlugin,
hub.Krew,
hub.OLM,
hub.OPA,
hub.TBAction,
hub.TektonTask,
hub.KedaScaler,
hub.CoreDNS,
} {
for _, validKind := range validRepositoryKinds {
if kind == validKind {
return true
}

View File

@ -38,9 +38,15 @@ func TestTrackerSource(t *testing.T) {
},
Readme: "Package documentation in markdown format",
Install: "Brief install instructions in markdown format",
Changes: []string{
"feature 1",
"fix 1",
Changes: []*hub.Change{
{
Kind: "added",
Description: "feature 1",
},
{
Kind: "fixed",
Description: "issue 1",
},
},
Recommendations: []*hub.Recommendation{
{

View File

@ -23,8 +23,10 @@ links:
readme: Package documentation in markdown format
install: Brief install instructions in markdown format
changes:
- feature 1
- fix 1
- kind: added
description: feature 1
- kind: fixed
description: issue 1
maintainers:
- name: Maintainer
email: test@email.com

View File

@ -23,8 +23,10 @@ links:
readme: Package documentation in markdown format
install: Brief install instructions in markdown format
changes:
- feature 1
- fix 1
- kind: added
description: feature 1
- kind: fixed
description: issue 1
maintainers:
- name: Maintainer
email: test@email.com

View File

@ -23,8 +23,10 @@ links:
readme: Package documentation in markdown format
install: Brief install instructions in markdown format
changes:
- feature 1
- fix 1
- kind: added
description: feature 1
- kind: fixed
description: issue 1
maintainers:
- name: Maintainer
email: test@email.com

View File

@ -23,8 +23,10 @@ links:
readme: Package documentation in markdown format
install: Brief install instructions in markdown format
changes:
- feature 1
- fix 1
- kind: added
description: feature 1
- kind: fixed
description: issue 1
maintainers:
- name: Maintainer
email: test@email.com

View File

@ -23,8 +23,10 @@ links:
readme: Package documentation in markdown format
install: Brief install instructions in markdown format
changes:
- feature 1
- fix 1
- kind: added
description: feature 1
- kind: fixed
description: issue 1
maintainers:
- name: Maintainer
email: test@email.com

View File

@ -22,8 +22,10 @@ links:
url: https://link1.url
install: Brief install instructions in markdown format
changes:
- feature 1
- fix 1
- kind: added
description: feature 1
- kind: fixed
description: issue 1
maintainers:
- name: Maintainer
email: test@email.com

View File

@ -17,6 +17,7 @@ import (
"github.com/artifacthub/hub/internal/license"
"github.com/artifacthub/hub/internal/pkg"
"github.com/artifacthub/hub/internal/repo"
"github.com/artifacthub/hub/internal/tracker/source"
"github.com/containerd/containerd/remotes/docker"
"github.com/deislabs/oras/pkg/content"
ctxo "github.com/deislabs/oras/pkg/context"
@ -440,9 +441,9 @@ func enrichPackageFromArchive(p *hub.Package, chart *chart.Chart) error {
func enrichPackageFromAnnotations(p *hub.Package, annotations map[string]string) error {
// Changes
if v, ok := annotations[changesAnnotation]; ok {
var changes []string
if err := yaml.Unmarshal([]byte(v), &changes); err != nil {
return fmt.Errorf("invalid changes value: %s", v)
changes, err := source.ParseChangesAnnotation(v)
if err != nil {
return err
}
p.Changes = changes
}

View File

@ -84,9 +84,13 @@ func TestTrackerSource(t *testing.T) {
Whitelisted: true,
},
},
Changes: []string{
"Added cool feature",
"Fixed minor bug",
Changes: []*hub.Change{
{
Description: "Added cool feature",
},
{
Description: "Fixed minor bug",
},
},
Recommendations: []*hub.Recommendation{
{
@ -344,9 +348,37 @@ func TestEnrichPackageFromAnnotations(t *testing.T) {
`,
},
&hub.Package{
Changes: []string{
"Added cool feature",
"Fixed minor bug",
Changes: []*hub.Change{
{
Description: "Added cool feature",
},
{
Description: "Fixed minor bug",
},
},
},
"",
},
{
&hub.Package{},
map[string]string{
changesAnnotation: `
- kind: added
description: Cool feature
- kind: fixed
description: Minor bug
`,
},
&hub.Package{
Changes: []*hub.Change{
{
Kind: "added",
Description: "Cool feature",
},
{
Kind: "fixed",
Description: "Minor bug",
},
},
},
"",

View File

@ -0,0 +1,31 @@
package source
import (
"fmt"
"github.com/artifacthub/hub/internal/hub"
"github.com/artifacthub/hub/internal/pkg"
"gopkg.in/yaml.v2"
)
// ParseChangesAnnotation parses the provided changes annotation returning a
// slice of changes entries. Changes entries are also validated an normalized.
func ParseChangesAnnotation(annotation string) ([]*hub.Change, error) {
var changes []*hub.Change
if err := yaml.Unmarshal([]byte(annotation), &changes); err != nil {
var changesDescriptions []string
if err := yaml.Unmarshal([]byte(annotation), &changesDescriptions); err != nil {
return nil, fmt.Errorf("invalid changes annotation: %s", annotation)
}
for _, description := range changesDescriptions {
changes = append(changes, &hub.Change{Description: description})
}
}
for _, change := range changes {
if err := pkg.ValidateChange(change); err != nil {
return nil, err
}
pkg.NormalizeChange(change)
}
return changes, nil
}

View File

@ -0,0 +1,108 @@
package source
import (
"strconv"
"testing"
"github.com/artifacthub/hub/internal/hub"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestParseChangesAnnotation(t *testing.T) {
testCases := []struct {
annotation string
expectedChanges []*hub.Change
expectedErrMsg string
}{
{
`
1234
`,
nil,
"invalid changes annotation",
},
{
`
- invalid: entry
`,
nil,
"invalid change: description not provided",
},
{
`
- cool feature
- bug fixed
`,
[]*hub.Change{
{
Description: "cool feature",
},
{
Description: "bug fixed",
},
},
"",
},
{
`
- kind: added
description: feature 1
- kind: fixed
description: issue 1
`,
[]*hub.Change{
{
Kind: "added",
Description: "feature 1",
},
{
Kind: "fixed",
Description: "issue 1",
},
},
"",
},
{
`
- kind: Added
description: feature 1
- kind: FIXED
description: issue 1
`,
[]*hub.Change{
{
Kind: "added",
Description: "feature 1",
},
{
Kind: "fixed",
Description: "issue 1",
},
},
"",
},
{
`
- kind: invalid
description: feature 1
`,
nil,
"invalid change: invalid kind: invalid",
},
}
for i, tc := range testCases {
tc := tc
t.Run(strconv.Itoa(i), func(t *testing.T) {
t.Parallel()
changes, err := ParseChangesAnnotation(tc.annotation)
if tc.expectedErrMsg == "" {
assert.Nil(t, err)
} else {
require.Error(t, err)
assert.Contains(t, err.Error(), tc.expectedErrMsg)
}
assert.Equal(t, tc.expectedChanges, changes)
})
}
}

View File

@ -16,6 +16,7 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/artifacthub/hub/internal/hub"
"github.com/artifacthub/hub/internal/pkg"
"github.com/artifacthub/hub/internal/tracker/source"
"github.com/ghodss/yaml"
"github.com/operator-framework/api/pkg/manifests"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
@ -255,8 +256,8 @@ func (s *TrackerSource) preparePackage(
isGlobalOperator = true
}
}
var changes []string
if err := yaml.Unmarshal([]byte(csv.Annotations[changesAnnotation]), &changes); err == nil {
changes, err := source.ParseChangesAnnotation(csv.Annotations[changesAnnotation])
if err == nil {
p.Changes = changes
}
containsSecurityUpdates, err := strconv.ParseBool(csv.Annotations[securityUpdatesAnnotation])

View File

@ -55,9 +55,13 @@ func TestTrackerSource(t *testing.T) {
URL: "https://github.com/test/test-operator",
},
},
Changes: []string{
"feature 1",
"fix 1",
Changes: []*hub.Change{
{
Description: "feature 1",
},
{
Description: "fix 1",
},
},
ContainsSecurityUpdates: true,
Prerelease: true,

View File

@ -11,6 +11,7 @@ import (
"github.com/artifacthub/hub/internal/hub"
"github.com/artifacthub/hub/internal/pkg"
"github.com/artifacthub/hub/internal/repo"
"github.com/artifacthub/hub/internal/tracker/source"
"github.com/ghodss/yaml"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
)
@ -212,8 +213,8 @@ func getManifest(pkgPath string) (*v1beta1.Task, []byte, error) {
func enrichPackageFromAnnotations(p *hub.Package, annotations map[string]string) error {
// Changes
if v, ok := annotations[changesAnnotation]; ok {
var changes []string
if err := yaml.Unmarshal([]byte(v), &changes); err == nil {
changes, err := source.ParseChangesAnnotation(v)
if err == nil {
p.Changes = changes
}
}

View File

@ -99,9 +99,13 @@ func TestTrackerSource(t *testing.T) {
Email: "user2@email.com",
},
},
Changes: []string{
"Added cool feature",
"Fixed minor bug",
Changes: []*hub.Change{
{
Description: "Added cool feature",
},
{
Description: "Fixed minor bug",
},
},
Recommendations: []*hub.Recommendation{
{

View File

@ -32,7 +32,7 @@
"react-codemirror2": "^7.2.1",
"react-color": "^2.19.3",
"react-dom": "^16.13.1",
"react-icons": "^3.11.0",
"react-icons": "^4.2.0",
"react-markdown": "^4.3.1",
"react-router-dom": "^5.2.0",
"react-router-scroll-memory": "^2.0.7",

View File

@ -191,7 +191,7 @@
"description": "fgdfg",
"url": "http://jksdhfkjfds",
"contentType": "dsafddadsg",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -164,7 +164,7 @@ describe('WebhookForm', () => {
expect(getByTestId('templateTextarea')).toHaveValue(mockWebhook.template!);
expect(getByText('Variables reference')).toBeInTheDocument();
expect(getByText(`{{ .Event.kind }}`)).toBeInTheDocument();
expect(getByText(`{{ .Event.Kind }}`)).toBeInTheDocument();
expect(getByText('Version of the new release.')).toBeInTheDocument();
expect(getByTestId('testWebhookBtn')).toBeInTheDocument();
@ -256,29 +256,29 @@ describe('WebhookForm', () => {
expect(getByTestId('templateTextarea')).toBeDisabled();
expect(getByTestId('templateTextarea')).toHaveValue(`{
"specversion" : "1.0",
"id" : "{{ .Event.id }}",
"id" : "{{ .Event.ID }}",
"source" : "https://artifacthub.io/cloudevents",
"type" : "io.artifacthub.{{ .Event.kind }}",
"type" : "io.artifacthub.{{ .Event.Kind }}",
"datacontenttype" : "application/json",
"data" : {
"package": {
"name": "{{ .Package.name }}",
"version": "{{ .Package.version }}",
"url": "{{ .Package.url }}",
"changes": [{{range $i, $e := .Package.changes}}{{if $i}}, {{end}}"{{.}}"{{end}}],
"containsSecurityUpdates": {{ .Package.containsSecurityUpdates }},
"prerelease": {{ .Package.prerelease }},
"name": "{{ .Package.Name }}",
"version": "{{ .Package.Version }}",
"url": "{{ .Package.URL }}",
"changes": [{{range $i, $e := .Package.Changes}}{{if $i}}, {{end}}"{{.Description}}"{{end}}],
"containsSecurityUpdates": {{ .Package.ContainsSecurityUpdates }},
"prerelease": {{ .Package.Prerelease }},
"repository": {
"kind": "{{ .Package.repository.kind }}",
"name": "{{ .Package.repository.name }}",
"publisher": "{{ .Package.repository.publisher }}"
"kind": "{{ .Package.Repository.Kind }}",
"name": "{{ .Package.Repository.Name }}",
"publisher": "{{ .Package.Repository.Publisher }}"
}
}
}
}`);
expect(getByText('Variables reference')).toBeInTheDocument();
expect(getByText(`{{ .Event.kind }}`)).toBeInTheDocument();
expect(getByText(`{{ .Event.Kind }}`)).toBeInTheDocument();
expect(getByText('Version of the new release.')).toBeInTheDocument();
expect(getByTestId('testWebhookBtn')).toBeInTheDocument();

View File

@ -43,22 +43,22 @@ const DEAFULT_PAYLOAD_KIND: PayloadKind = PayloadKind.default;
export const DEFAULT_PAYLOAD_TEMPLATE = `{
"specversion" : "1.0",
"id" : "{{ .Event.id }}",
"id" : "{{ .Event.ID }}",
"source" : "https://artifacthub.io/cloudevents",
"type" : "io.artifacthub.{{ .Event.kind }}",
"type" : "io.artifacthub.{{ .Event.Kind }}",
"datacontenttype" : "application/json",
"data" : {
"package": {
"name": "{{ .Package.name }}",
"version": "{{ .Package.version }}",
"url": "{{ .Package.url }}",
"changes": [{{range $i, $e := .Package.changes}}{{if $i}}, {{end}}"{{.}}"{{end}}],
"containsSecurityUpdates": {{ .Package.containsSecurityUpdates }},
"prerelease": {{ .Package.prerelease }},
"name": "{{ .Package.Name }}",
"version": "{{ .Package.Version }}",
"url": "{{ .Package.URL }}",
"changes": [{{range $i, $e := .Package.Changes}}{{if $i}}, {{end}}"{{.Description}}"{{end}}],
"containsSecurityUpdates": {{ .Package.ContainsSecurityUpdates }},
"prerelease": {{ .Package.Prerelease }},
"repository": {
"kind": "{{ .Package.repository.kind }}",
"name": "{{ .Package.repository.name }}",
"publisher": "{{ .Package.repository.publisher }}"
"kind": "{{ .Package.Repository.Kind }}",
"name": "{{ .Package.Repository.Name }}",
"publisher": "{{ .Package.Repository.Publisher }}"
}
}
}
@ -556,9 +556,9 @@ const WebhookForm = (props: Props) => {
{'{'}
<br />
<span className="ml-3">
{`"text": "Package`} <span className="font-weight-bold">{`{{ .Package.name }}`}</span> {`version`}{' '}
<span className="font-weight-bold">{`{{ .Package.version }}`}</span> released!{' '}
<span className="font-weight-bold">{`{{ .Package.url }}`}</span>
{`"text": "Package`} <span className="font-weight-bold">{`{{ .Package.Name }}`}</span> {`version`}{' '}
<span className="font-weight-bold">{`{{ .Package.Version }}`}</span> released!{' '}
<span className="font-weight-bold">{`{{ .Package.URL }}`}</span>
{`"`}
<br />
{'}'}
@ -633,13 +633,13 @@ const WebhookForm = (props: Props) => {
<tbody>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Event.id }}`}</span>
<span className="text-nowrap">{`{{ .Event.ID }}`}</span>
</th>
<td>Id of the event triggering the notification.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Event.kind }}`}</span>
<span className="text-nowrap">{`{{ .Event.Kind }}`}</span>
</th>
<td>
Kind of the event triggering notification. At the moment the only possible value is{' '}
@ -648,43 +648,81 @@ const WebhookForm = (props: Props) => {
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.name }}`}</span>
<span className="text-nowrap">{`{{ .Package.Name }}`}</span>
</th>
<td>Name of the package.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.version }}`}</span>
<span className="text-nowrap">{`{{ .Package.Version }}`}</span>
</th>
<td>Version of the new release.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.url }}`}</span>
<span className="text-nowrap">{`{{ .Package.URL }}`}</span>
</th>
<td>ArtifactHub URL of the package.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.changes }}`}</span>
<span className="text-nowrap">{`{{ .Package.Changes }}`}</span>
</th>
<td>List of strings describing the changes this package version introduces.</td>
<td>List of changes this package version introduces.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.containsSecurityUpdates }}`}</span>
<span className="text-nowrap">{`{{ .Package.Changes[i].Kind }}`}</span>
</th>
<td>
Kind of the change. Possible values are <span className="font-weight-bold">added</span>,{' '}
<span className="font-weight-bold">changed</span>,{' '}
<span className="font-weight-bold">deprecated</span>,{' '}
<span className="font-weight-bold">removed</span>,{' '}
<span className="font-weight-bold">fixed</span> and{' '}
<span className="font-weight-bold">security</span>. When the change kind is not provided, the
value will be empty.
</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.Changes[i].Description }}`}</span>
</th>
<td>Brief text explaining the change.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.Changes[i].Links }}`}</span>
</th>
<td>List of links related to the change.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.Changes[i].Links[i].Name }}`}</span>
</th>
<td>Name of the link.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.Changes[i].Links[i].URL }}`}</span>
</th>
<td>Url of the link.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.ContainsSecurityUpdates }}`}</span>
</th>
<td>Boolean flag that indicates whether this package contains security updates or not.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.prerelease }}`}</span>
<span className="text-nowrap">{`{{ .Package.Prerelease }}`}</span>
</th>
<td>Boolean flag that indicates whether this package version is a pre-release or not.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.kind }}`}</span>
<span className="text-nowrap">{`{{ .Package.Repository.Kind }}`}</span>
</th>
<td>
Kind of the repository associated with the notification. Possible values are{' '}
@ -695,13 +733,13 @@ const WebhookForm = (props: Props) => {
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.name }}`}</span>
<span className="text-nowrap">{`{{ .Package.Repository.Name }}`}</span>
</th>
<td>Name of the repository.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.publisher }}`}</span>
<span className="text-nowrap">{`{{ .Package.Repository.Publisher }}`}</span>
</th>
<td>
Publisher of the repository. If the owner is a user it'll be the user alias. If it's an

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": false,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -4,7 +4,7 @@
"description": "this is a test description",
"url": "http://jksdhfkjfds",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -5,7 +5,7 @@
"url": "http://jksdhfkjfds",
"secret": "secret",
"contentType": "application/json",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": false,
"eventKinds": [0],
"packages": [

View File

@ -6,7 +6,7 @@
"url": "https://hooks.com",
"secret": "sfsfdsg",
"contentType": "application/json",
"template": "{\n \"text\":\"Package {{ .Package.name }} version {{ .Package.version }} released! {{ .Package.url }}\"\n}",
"template": "{\n \"text\":\"Package {{ .Package.Name }} version {{ .Package.Version }} released! {{ .Package.URL }}\"\n}",
"active": false,
"eventKinds": [0],
"packages": [
@ -166,7 +166,7 @@
"description": "lkdjklfsd",
"url": "http://lksdjfkdl",
"contentType": "dfsdfggdfs",
"template": "{\n \"text\": \"Package {{ .Package.name }} version {{ .Package.version }} released! {{ .Package.url }}\"}\nslkdjfdlkslskdfjkldf jldksjg kljdflk gsdjfkl lgfdks\n}",
"template": "{\n \"text\": \"Package {{ .Package.Name }} version {{ .Package.Version }} released! {{ .Package.URL }}\"}\nslkdjfdlkslskdfjkldf jldksjg kljdflk gsdjfkl lgfdks\n}",
"active": false,
"eventKinds": [0],
"packages": [
@ -191,7 +191,7 @@
"description": "fgdfg",
"url": "http://jksdhfkjfds",
"contentType": "dsafddadsg",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -6,7 +6,7 @@
"url": "https://hooks.com",
"secret": "sfsfdsg",
"contentType": "application/json",
"template": "{\n \"text\":\"Package {{ .Package.name }} version {{ .Package.version }} released! {{ .Package.url }}\"\n}",
"template": "{\n \"text\":\"Package {{ .Package.Name }} version {{ .Package.Version }} released! {{ .Package.URL }}\"\n}",
"active": false,
"eventKinds": [0],
"packages": [
@ -166,7 +166,7 @@
"description": "lkdjklfsd",
"url": "http://lksdjfkdl",
"contentType": "dfsdfggdfs",
"template": "{\n \"text\": \"Package {{ .Package.name }} version {{ .Package.version }} released! {{ .Package.url }}\"}\nslkdjfdlkslskdfjkldf jldksjg kljdflk gsdjfkl lgfdks\n}",
"template": "{\n \"text\": \"Package {{ .Package.Name }} version {{ .Package.Version }} released! {{ .Package.URL }}\"}\nslkdjfdlkslskdfjkldf jldksjg kljdflk gsdjfkl lgfdks\n}",
"active": false,
"eventKinds": [0],
"packages": [
@ -191,7 +191,7 @@
"description": "fgdfg",
"url": "http://jksdhfkjfds",
"contentType": "dsafddadsg",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -6,7 +6,7 @@
"url": "https://hooks.com",
"secret": "sfsfdsg",
"contentType": "application/json",
"template": "{\n \"text\":\"Package {{ .Package.name }} version {{ .Package.version }} released! {{ .Package.url }}\"\n}",
"template": "{\n \"text\":\"Package {{ .Package.Name }} version {{ .Package.Version }} released! {{ .Package.URL }}\"\n}",
"active": false,
"eventKinds": [0],
"packages": [
@ -191,7 +191,7 @@
"description": "fgdfg",
"url": "http://jksdhfkjfds",
"contentType": "dsafddadsg",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.id }}\",\n \"kind\": {{ .Event.kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.kind }},\n \"name\": \"{{ .Package.name }}\",\n \"version\": \"{{ .Package.version }}\",\n \"publisher\": \"{{ .Package.publisher }}\",\n \"url\": \"{{ .Package.url }}\"\n }\n}",
"template": "{\n \"event\": {\n \"id\": \"{{ .Event.ID }}\",\n \"kind\": {{ .Event.Kind }}\n },\n \"package\": {\n \"kind\": {{ .Package.Kind }},\n \"name\": \"{{ .Package.Name }}\",\n \"version\": \"{{ .Package.Version }}\",\n \"publisher\": \"{{ .Package.Publisher }}\",\n \"url\": \"{{ .Package.URL }}\"\n }\n}",
"active": true,
"eventKinds": [0],
"packages": [

View File

@ -1,5 +1,4 @@
.list {
padding-inline-start: 20px;
font-size: 90%;
}
@ -21,6 +20,58 @@
color: var(--orange);
}
.linksWrapper {
margin-top: -2px;
}
.link {
font-size: 0.7rem;
text-decoration: underline;
}
.changeBadgeWrapper {
margin-top: 3px;
}
.changeBadge {
color: var(--white);
padding: 0 0.25rem;
width: 90px;
height: 15px;
line-height: 15px;
font-weight: 400;
font-size: 60%;
background-color: var(--color-black-50);
}
.addedChangeBadge {
background-color: #0594cb;
}
.changedChangeBadge {
background-color: #e0ae0b;
}
.deprecatedChangeBadge {
background-color: #6c757d;
}
.removedChangeBadge {
background-color: #f7860f;
}
.fixedChangeBadge {
background-color: #28a745;
}
.securityChangeBadge {
background-color: #df2a29;
}
.badgeIcon {
top: -1px;
}
@media only screen and (max-width: 767.98px) {
.title {
font-size: 1.25rem;
@ -34,6 +85,11 @@
font-size: 80%;
margin-top: 0.5rem;
}
.changeBadge {
width: 15px;
padding: 0;
}
}
@media only screen and (min-width: 576px) {

View File

@ -51,6 +51,8 @@ describe('ChangelogModal', () => {
expect(API.getChangelog).toHaveBeenCalledTimes(1);
expect(result.asFragment()).toMatchSnapshot();
});
expect(result.getByRole('dialog')).toBeInTheDocument();
});
describe('Render', () => {
@ -58,7 +60,7 @@ describe('ChangelogModal', () => {
const mockChangelog = getMockChangelog('2');
mocked(API).getChangelog.mockResolvedValue(mockChangelog);
const { getByTestId } = render(<ChangelogModal {...defaultProps} />);
const { getByTestId, getByRole } = render(<ChangelogModal {...defaultProps} />);
const btn = getByTestId('changelogBtn');
expect(btn).toBeInTheDocument();
@ -68,6 +70,8 @@ describe('ChangelogModal', () => {
expect(API.getChangelog).toHaveBeenCalledTimes(1);
expect(API.getChangelog).toHaveBeenCalledWith('id');
});
expect(getByRole('dialog')).toBeInTheDocument();
});
it('does not render component when repo kind is Krew, Falco or Helm plugin', async () => {
@ -79,7 +83,6 @@ describe('ChangelogModal', () => {
},
};
const { container } = render(<ChangelogModal {...props} />);
expect(container).toBeEmptyDOMElement();
});
@ -88,8 +91,6 @@ describe('ChangelogModal', () => {
const btn = getByTestId('changelogBtn');
expect(btn).toHaveClass('disabled');
expect(API.getChangelog).toHaveBeenCalledTimes(0);
});
it('opens modal', async () => {
@ -103,14 +104,15 @@ describe('ChangelogModal', () => {
await waitFor(() => {
expect(API.getChangelog).toHaveBeenCalledTimes(1);
expect(mockHistoryReplace).toHaveBeenCalledTimes(1);
expect(mockHistoryReplace).toHaveBeenCalledWith({
search: '?modal=changelog',
state: {
fromStarredPage: undefined,
searchUrlReferer: undefined,
},
});
});
expect(mockHistoryReplace).toHaveBeenCalledTimes(1);
expect(mockHistoryReplace).toHaveBeenCalledWith({
search: '?modal=changelog',
state: {
fromStarredPage: undefined,
searchUrlReferer: undefined,
},
});
expect(getByRole('dialog')).toBeInTheDocument();
@ -133,16 +135,17 @@ describe('ChangelogModal', () => {
const close = getByText('Close');
fireEvent.click(close);
waitFor(() => {
await waitFor(() => {
expect(queryByRole('dialog')).toBeNull();
expect(mockHistoryReplace).toHaveBeenCalledTimes(1);
expect(mockHistoryReplace).toHaveBeenCalledWith({
search: '',
state: {
fromStarredPage: undefined,
searchUrlReferer: undefined,
},
});
});
expect(mockHistoryReplace).toHaveBeenCalledTimes(2);
expect(mockHistoryReplace).toHaveBeenLastCalledWith({
search: '',
state: {
fromStarredPage: undefined,
searchUrlReferer: undefined,
},
});
});

View File

@ -2,16 +2,21 @@ import classnames from 'classnames';
import { isNull, isUndefined } from 'lodash';
import moment from 'moment';
import React, { useEffect, useState } from 'react';
import { BsDot } from 'react-icons/bs';
import { CgFileDocument } from 'react-icons/cg';
import { FaLink } from 'react-icons/fa';
import { FaLink, FaTrash, FaWrench } from 'react-icons/fa';
import { MdSecurity } from 'react-icons/md';
import { RiTimerFill } from 'react-icons/ri';
import { TiArrowSync, TiPlus } from 'react-icons/ti';
import { useHistory } from 'react-router-dom';
import semver from 'semver';
import { API } from '../../api';
import { ChangeLog, Repository, RepositoryKind, SearchFiltersURL } from '../../types';
import { Change, ChangeKind, ChangeLog, PackageLink, Repository, RepositoryKind, SearchFiltersURL } from '../../types';
import alertDispatcher from '../../utils/alertDispatcher';
import buildPackageURL from '../../utils/buildPackageURL';
import ElementWithTooltip from '../common/ElementWithTooltip';
import ExternalLink from '../common/ExternalLink';
import Modal from '../common/Modal';
import styles from './ChangelogModal.module.css';
@ -155,6 +160,12 @@ const ChangelogModal = (props: Props) => {
<div className="mx-0 mx-md-3 my-1 mw-100">
{changelog.map((item: ChangeLog) => {
if (isNull(item.changes) || isUndefined(item.changes)) return null;
const hasBadge = item.changes.some(
(change: Change) =>
change.hasOwnProperty('kind') && !isUndefined(change.kind) && change.kind.toString() !== ''
);
return (
<div key={`v_${item.version}`} data-testid="changelogBlock">
<div className="d-inline-block d-md-flex flex-row align-items-baseline border-bottom w-100 mb-3 pb-2">
@ -190,11 +201,83 @@ const ChangelogModal = (props: Props) => {
</div>
</div>
<ul className={`mb-4 ${styles.list}`}>
{item.changes.map((change: string, index: number) => (
<li key={`change_${item.version}_${index}`}>{change}</li>
<div className={`d-flex flex-column mb-4 ${styles.list}`}>
{item.changes.map((change: Change, index: number) => (
<div key={`change_${item.version}_${index}`} className="mb-1 w-100 d-flex flex-row">
<div className="d-flex align-items-start flex-row w-100">
{change.kind ? (
<div className={`position-relative ${styles.changeBadgeWrapper}`}>
<div
className={classnames(
'd-flex flex-row align-items-center justify-content-center text-uppercase badge badge-pill mr-2',
styles.changeBadge,
styles[`${change.kind.toString()}ChangeBadge`]
)}
>
<span className={`position-relative ${styles.badgeIcon}`}>
{(() => {
switch (change.kind) {
case ChangeKind.added:
return <TiPlus />;
case ChangeKind.changed:
return <TiArrowSync />;
case ChangeKind.removed:
return <FaTrash />;
case ChangeKind.fixed:
return <FaWrench />;
case ChangeKind.security:
return <MdSecurity />;
case ChangeKind.deprecated:
return <RiTimerFill />;
default:
return <>-</>;
}
})()}
</span>
<span className="d-none d-md-block ml-1">{change.kind.toString()}</span>
</div>
</div>
) : (
<>
{hasBadge ? (
<div className={`position-relative ${styles.changeBadgeWrapper}`}>
<div
className={classnames(
'd-flex flex-row align-items-center justify-content-center text-uppercase badge badge-pill mr-2',
styles.changeBadge
)}
>
-
</div>
</div>
) : (
<div className="mr-1 mr-md-2">
<BsDot />
</div>
)}
</>
)}
<div className="flex-grow-1">
<div>{change.description}</div>
{!isUndefined(change.links) && (
<div className={`d-flex flex-row ${styles.linksWrapper}`}>
{change.links.map((link: PackageLink, idx: number) => {
return (
<div key={`change_${index}_link${idx}`}>
<ExternalLink className={`text-muted ${styles.link}`} href={link.url}>
{link.name}
</ExternalLink>
{idx !== change.links!.length - 1 && <BsDot className="text-muted" />}
</div>
);
})}
</div>
)}
</div>
</div>
</div>
))}
</ul>
</div>
</div>
);
})}

View File

@ -3,106 +3,108 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.8.0",
"ts": 1604048487,
"changes": [
"Add JSON schema for Artifact Hub Helm chart",
"Some improvements in Artifact Hub Helm chart",
"Track Helm charts values schema",
"Add endpoint to get Helm charts values schema",
"Bump Trivy to 0.12.0",
"Display containers images in Helm packages",
"Remove internal requests limiter",
"Upgrade frontend dependencies to fix some security vulnerabilities",
"Add packages security report documentation",
"Some bugs fixes and improvements"
{ "description": "Add JSON schema for Artifact Hub Helm chart" },
{ "description": "Some improvements in Artifact Hub Helm chart" },
{ "description": "Track Helm charts values schema" },
{ "description": "Add endpoint to get Helm charts values schema" },
{ "description": "Bump Trivy to 0.12.0" },
{ "description": "Display containers images in Helm packages" },
{ "description": "Remove internal requests limiter" },
{ "description": "Upgrade frontend dependencies to fix some security vulnerabilities" },
{ "description": "Add packages security report documentation" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.3.0",
"ts": 1604048487,
"changes": [
"Added support for OLM operators repositories",
"Added support for Falco rules repositories",
"Added RSS feed for packages' new version releases",
"Packages now always belong to a repository",
"Reorganized some API routes (breaking changes)",
"Added a link to browse all packages and some sample searches to home page",
"Added CNCF Sandbox logo to home page",
"Some minor improvements in search page filters",
"Package creation time is now tracked and displayed",
"Some bugs fixes"
{ "description": "Added support for OLM operators repositories" },
{ "description": "Added support for Falco rules repositories" },
{ "description": "Added RSS feed for packages' new version releases" },
{ "description": "Packages now always belong to a repository" },
{ "description": "Reorganized some API routes (breaking changes)" },
{ "description": "Added a link to browse all packages and some sample searches to home page" },
{ "description": "Added CNCF Sandbox logo to home page" },
{ "description": "Some minor improvements in search page filters" },
{ "description": "Package creation time is now tracked and displayed" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.6.0",
"ts": 1604048487,
"changes": [
"Introduce fine grained authorization mechanism based on OPA policies",
"Allow enriching package information using Helm annotations",
"Allow entities to claim repositories ownership",
"Introduce official repository concept",
"Add verified publisher and official repository search filters",
"Artifact Hub repositories badges",
"Test Artifact Hub Helm chart",
"Improve package view on mobile devices",
"Add API endpoint to get repositories by kind",
"Some bugs fixes and improvements"
{ "description": "Introduce fine grained authorization mechanism based on OPA policies" },
{ "description": "Allow enriching package information using Helm annotations" },
{ "description": "Allow entities to claim repositories ownership" },
{ "description": "Introduce official repository concept" },
{ "description": "Add verified publisher and official repository search filters" },
{ "description": "Artifact Hub repositories badges" },
{ "description": "Test Artifact Hub Helm chart" },
{ "description": "Improve package view on mobile devices" },
{ "description": "Add API endpoint to get repositories by kind" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.4.0",
"ts": 1604048487,
"changes": [
"Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)",
"Trackers have been improved and consolidated into one",
"Search filtering experience in UI has been improved",
"Now it's possible to search by the name of the repository and the name of the owning organization or user",
"Added support to allow filtering packages by category",
"An operator flag has been added to the package entity, and it's possible to filter by it",
"Repositories URL is now exposed to users in several places in the UI",
"Some bugs fixes"
{ "description": "Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)" },
{ "description": "Trackers have been improved and consolidated into one" },
{ "description": "Search filtering experience in UI has been improved" },
{
"description": "Now it's possible to search by the name of the repository and the name of the owning organization or user"
},
{ "description": "Added support to allow filtering packages by category" },
{ "description": "An operator flag has been added to the package entity, and it's possible to filter by it" },
{ "description": "Repositories URL is now exposed to users in several places in the UI" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.7.0",
"ts": 1604048487,
"changes": [
"Introduce packages security report",
"Display packages' license in cards",
"Allow filtering packages by license and operator capabilities",
"Add support for some extra Helm and OLM annotations",
"Add repositories guide",
"Allow adding CRDs for operators in Helm packages",
"Display search tips and add some extra sample searches",
"Improve user experience in authorization configuration view",
"Some bugs fixes and improvements"
{ "description": "Introduce packages security report" },
{ "description": "Display packages' license in cards" },
{ "description": "Allow filtering packages by license and operator capabilities" },
{ "description": "Add support for some extra Helm and OLM annotations" },
{ "description": "Add repositories guide" },
{ "description": "Allow adding CRDs for operators in Helm packages" },
{ "description": "Display search tips and add some extra sample searches" },
{ "description": "Improve user experience in authorization configuration view" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.2.0",
"ts": 1604048487,
"changes": [
"API docs",
"Reorganize API routes",
"Some HTTP handlers improvements",
"Support for API keys",
"API rate limiting",
"Signed packages label (Helm provenance file)",
"Home page updated",
"Bug fixes"
{ "description": "API docs" },
{ "description": "Reorganize API routes" },
{ "description": "Some HTTP handlers improvements" },
{ "description": "Support for API keys" },
{ "description": "API rate limiting" },
{ "description": "Signed packages label (Helm provenance file)" },
{ "description": "Home page updated" },
{ "description": "Bug fixes" }
]
}
]

View File

@ -3,106 +3,108 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.8.0",
"ts": 1604048487,
"changes": [
"Add JSON schema for Artifact Hub Helm chart",
"Some improvements in Artifact Hub Helm chart",
"Track Helm charts values schema",
"Add endpoint to get Helm charts values schema",
"Bump Trivy to 0.12.0",
"Display containers images in Helm packages",
"Remove internal requests limiter",
"Upgrade frontend dependencies to fix some security vulnerabilities",
"Add packages security report documentation",
"Some bugs fixes and improvements"
{ "description": "Add JSON schema for Artifact Hub Helm chart" },
{ "description": "Some improvements in Artifact Hub Helm chart" },
{ "description": "Track Helm charts values schema" },
{ "description": "Add endpoint to get Helm charts values schema" },
{ "description": "Bump Trivy to 0.12.0" },
{ "description": "Display containers images in Helm packages" },
{ "description": "Remove internal requests limiter" },
{ "description": "Upgrade frontend dependencies to fix some security vulnerabilities" },
{ "description": "Add packages security report documentation" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.3.0",
"ts": 1604048487,
"changes": [
"Added support for OLM operators repositories",
"Added support for Falco rules repositories",
"Added RSS feed for packages' new version releases",
"Packages now always belong to a repository",
"Reorganized some API routes (breaking changes)",
"Added a link to browse all packages and some sample searches to home page",
"Added CNCF Sandbox logo to home page",
"Some minor improvements in search page filters",
"Package creation time is now tracked and displayed",
"Some bugs fixes"
{ "description": "Added support for OLM operators repositories" },
{ "description": "Added support for Falco rules repositories" },
{ "description": "Added RSS feed for packages' new version releases" },
{ "description": "Packages now always belong to a repository" },
{ "description": "Reorganized some API routes (breaking changes)" },
{ "description": "Added a link to browse all packages and some sample searches to home page" },
{ "description": "Added CNCF Sandbox logo to home page" },
{ "description": "Some minor improvements in search page filters" },
{ "description": "Package creation time is now tracked and displayed" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.6.0",
"ts": 1604048487,
"changes": [
"Introduce fine grained authorization mechanism based on OPA policies",
"Allow enriching package information using Helm annotations",
"Allow entities to claim repositories ownership",
"Introduce official repository concept",
"Add verified publisher and official repository search filters",
"Artifact Hub repositories badges",
"Test Artifact Hub Helm chart",
"Improve package view on mobile devices",
"Add API endpoint to get repositories by kind",
"Some bugs fixes and improvements"
{ "description": "Introduce fine grained authorization mechanism based on OPA policies" },
{ "description": "Allow enriching package information using Helm annotations" },
{ "description": "Allow entities to claim repositories ownership" },
{ "description": "Introduce official repository concept" },
{ "description": "Add verified publisher and official repository search filters" },
{ "description": "Artifact Hub repositories badges" },
{ "description": "Test Artifact Hub Helm chart" },
{ "description": "Improve package view on mobile devices" },
{ "description": "Add API endpoint to get repositories by kind" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.4.0",
"ts": 1604048487,
"changes": [
"Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)",
"Trackers have been improved and consolidated into one",
"Search filtering experience in UI has been improved",
"Now it's possible to search by the name of the repository and the name of the owning organization or user",
"Added support to allow filtering packages by category",
"An operator flag has been added to the package entity, and it's possible to filter by it",
"Repositories URL is now exposed to users in several places in the UI",
"Some bugs fixes"
{ "description": "Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)" },
{ "description": "Trackers have been improved and consolidated into one" },
{ "description": "Search filtering experience in UI has been improved" },
{
"description": "Now it's possible to search by the name of the repository and the name of the owning organization or user"
},
{ "description": "Added support to allow filtering packages by category" },
{ "description": "An operator flag has been added to the package entity, and it's possible to filter by it" },
{ "description": "Repositories URL is now exposed to users in several places in the UI" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.7.0",
"ts": 1604048487,
"changes": [
"Introduce packages security report",
"Display packages' license in cards",
"Allow filtering packages by license and operator capabilities",
"Add support for some extra Helm and OLM annotations",
"Add repositories guide",
"Allow adding CRDs for operators in Helm packages",
"Display search tips and add some extra sample searches",
"Improve user experience in authorization configuration view",
"Some bugs fixes and improvements"
{ "description": "Introduce packages security report" },
{ "description": "Display packages' license in cards" },
{ "description": "Allow filtering packages by license and operator capabilities" },
{ "description": "Add support for some extra Helm and OLM annotations" },
{ "description": "Add repositories guide" },
{ "description": "Allow adding CRDs for operators in Helm packages" },
{ "description": "Display search tips and add some extra sample searches" },
{ "description": "Improve user experience in authorization configuration view" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.2.0",
"ts": 1604048487,
"changes": [
"API docs",
"Reorganize API routes",
"Some HTTP handlers improvements",
"Support for API keys",
"API rate limiting",
"Signed packages label (Helm provenance file)",
"Home page updated",
"Bug fixes"
{ "description": "API docs" },
{ "description": "Reorganize API routes" },
{ "description": "Some HTTP handlers improvements" },
{ "description": "Support for API keys" },
{ "description": "API rate limiting" },
{ "description": "Signed packages label (Helm provenance file)" },
{ "description": "Home page updated" },
{ "description": "Bug fixes" }
]
}
]

View File

@ -3,106 +3,108 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.8.0",
"ts": 1604048487,
"changes": [
"Add JSON schema for Artifact Hub Helm chart",
"Some improvements in Artifact Hub Helm chart",
"Track Helm charts values schema",
"Add endpoint to get Helm charts values schema",
"Bump Trivy to 0.12.0",
"Display containers images in Helm packages",
"Remove internal requests limiter",
"Upgrade frontend dependencies to fix some security vulnerabilities",
"Add packages security report documentation",
"Some bugs fixes and improvements"
{ "description": "Add JSON schema for Artifact Hub Helm chart" },
{ "description": "Some improvements in Artifact Hub Helm chart" },
{ "description": "Track Helm charts values schema" },
{ "description": "Add endpoint to get Helm charts values schema" },
{ "description": "Bump Trivy to 0.12.0" },
{ "description": "Display containers images in Helm packages" },
{ "description": "Remove internal requests limiter" },
{ "description": "Upgrade frontend dependencies to fix some security vulnerabilities" },
{ "description": "Add packages security report documentation" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.3.0",
"ts": 1604048487,
"changes": [
"Added support for OLM operators repositories",
"Added support for Falco rules repositories",
"Added RSS feed for packages' new version releases",
"Packages now always belong to a repository",
"Reorganized some API routes (breaking changes)",
"Added a link to browse all packages and some sample searches to home page",
"Added CNCF Sandbox logo to home page",
"Some minor improvements in search page filters",
"Package creation time is now tracked and displayed",
"Some bugs fixes"
{ "description": "Added support for OLM operators repositories" },
{ "description": "Added support for Falco rules repositories" },
{ "description": "Added RSS feed for packages' new version releases" },
{ "description": "Packages now always belong to a repository" },
{ "description": "Reorganized some API routes (breaking changes)" },
{ "description": "Added a link to browse all packages and some sample searches to home page" },
{ "description": "Added CNCF Sandbox logo to home page" },
{ "description": "Some minor improvements in search page filters" },
{ "description": "Package creation time is now tracked and displayed" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.6.0",
"ts": 1604048487,
"changes": [
"Introduce fine grained authorization mechanism based on OPA policies",
"Allow enriching package information using Helm annotations",
"Allow entities to claim repositories ownership",
"Introduce official repository concept",
"Add verified publisher and official repository search filters",
"Artifact Hub repositories badges",
"Test Artifact Hub Helm chart",
"Improve package view on mobile devices",
"Add API endpoint to get repositories by kind",
"Some bugs fixes and improvements"
{ "description": "Introduce fine grained authorization mechanism based on OPA policies" },
{ "description": "Allow enriching package information using Helm annotations" },
{ "description": "Allow entities to claim repositories ownership" },
{ "description": "Introduce official repository concept" },
{ "description": "Add verified publisher and official repository search filters" },
{ "description": "Artifact Hub repositories badges" },
{ "description": "Test Artifact Hub Helm chart" },
{ "description": "Improve package view on mobile devices" },
{ "description": "Add API endpoint to get repositories by kind" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.4.0",
"ts": 1604048487,
"changes": [
"Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)",
"Trackers have been improved and consolidated into one",
"Search filtering experience in UI has been improved",
"Now it's possible to search by the name of the repository and the name of the owning organization or user",
"Added support to allow filtering packages by category",
"An operator flag has been added to the package entity, and it's possible to filter by it",
"Repositories URL is now exposed to users in several places in the UI",
"Some bugs fixes"
{ "description": "Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)" },
{ "description": "Trackers have been improved and consolidated into one" },
{ "description": "Search filtering experience in UI has been improved" },
{
"description": "Now it's possible to search by the name of the repository and the name of the owning organization or user"
},
{ "description": "Added support to allow filtering packages by category" },
{ "description": "An operator flag has been added to the package entity, and it's possible to filter by it" },
{ "description": "Repositories URL is now exposed to users in several places in the UI" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.7.0",
"ts": 1604048487,
"changes": [
"Introduce packages security report",
"Display packages' license in cards",
"Allow filtering packages by license and operator capabilities",
"Add support for some extra Helm and OLM annotations",
"Add repositories guide",
"Allow adding CRDs for operators in Helm packages",
"Display search tips and add some extra sample searches",
"Improve user experience in authorization configuration view",
"Some bugs fixes and improvements"
{ "description": "Introduce packages security report" },
{ "description": "Display packages' license in cards" },
{ "description": "Allow filtering packages by license and operator capabilities" },
{ "description": "Add support for some extra Helm and OLM annotations" },
{ "description": "Add repositories guide" },
{ "description": "Allow adding CRDs for operators in Helm packages" },
{ "description": "Display search tips and add some extra sample searches" },
{ "description": "Improve user experience in authorization configuration view" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.2.0",
"ts": 1604048487,
"changes": [
"API docs",
"Reorganize API routes",
"Some HTTP handlers improvements",
"Support for API keys",
"API rate limiting",
"Signed packages label (Helm provenance file)",
"Home page updated",
"Bug fixes"
{ "description": "API docs" },
{ "description": "Reorganize API routes" },
{ "description": "Some HTTP handlers improvements" },
{ "description": "Support for API keys" },
{ "description": "API rate limiting" },
{ "description": "Signed packages label (Helm provenance file)" },
{ "description": "Home page updated" },
{ "description": "Bug fixes" }
]
}
]

View File

@ -3,106 +3,108 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.8.0",
"ts": 1604048487,
"changes": [
"Add JSON schema for Artifact Hub Helm chart",
"Some improvements in Artifact Hub Helm chart",
"Track Helm charts values schema",
"Add endpoint to get Helm charts values schema",
"Bump Trivy to 0.12.0",
"Display containers images in Helm packages",
"Remove internal requests limiter",
"Upgrade frontend dependencies to fix some security vulnerabilities",
"Add packages security report documentation",
"Some bugs fixes and improvements"
{ "description": "Add JSON schema for Artifact Hub Helm chart" },
{ "description": "Some improvements in Artifact Hub Helm chart" },
{ "description": "Track Helm charts values schema" },
{ "description": "Add endpoint to get Helm charts values schema" },
{ "description": "Bump Trivy to 0.12.0" },
{ "description": "Display containers images in Helm packages" },
{ "description": "Remove internal requests limiter" },
{ "description": "Upgrade frontend dependencies to fix some security vulnerabilities" },
{ "description": "Add packages security report documentation" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.3.0",
"ts": 1604048487,
"changes": [
"Added support for OLM operators repositories",
"Added support for Falco rules repositories",
"Added RSS feed for packages' new version releases",
"Packages now always belong to a repository",
"Reorganized some API routes (breaking changes)",
"Added a link to browse all packages and some sample searches to home page",
"Added CNCF Sandbox logo to home page",
"Some minor improvements in search page filters",
"Package creation time is now tracked and displayed",
"Some bugs fixes"
{ "description": "Added support for OLM operators repositories" },
{ "description": "Added support for Falco rules repositories" },
{ "description": "Added RSS feed for packages' new version releases" },
{ "description": "Packages now always belong to a repository" },
{ "description": "Reorganized some API routes (breaking changes)" },
{ "description": "Added a link to browse all packages and some sample searches to home page" },
{ "description": "Added CNCF Sandbox logo to home page" },
{ "description": "Some minor improvements in search page filters" },
{ "description": "Package creation time is now tracked and displayed" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.6.0",
"ts": 1604048487,
"changes": [
"Introduce fine grained authorization mechanism based on OPA policies",
"Allow enriching package information using Helm annotations",
"Allow entities to claim repositories ownership",
"Introduce official repository concept",
"Add verified publisher and official repository search filters",
"Artifact Hub repositories badges",
"Test Artifact Hub Helm chart",
"Improve package view on mobile devices",
"Add API endpoint to get repositories by kind",
"Some bugs fixes and improvements"
{ "description": "Introduce fine grained authorization mechanism based on OPA policies" },
{ "description": "Allow enriching package information using Helm annotations" },
{ "description": "Allow entities to claim repositories ownership" },
{ "description": "Introduce official repository concept" },
{ "description": "Add verified publisher and official repository search filters" },
{ "description": "Artifact Hub repositories badges" },
{ "description": "Test Artifact Hub Helm chart" },
{ "description": "Improve package view on mobile devices" },
{ "description": "Add API endpoint to get repositories by kind" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.4.0",
"ts": 1604048487,
"changes": [
"Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)",
"Trackers have been improved and consolidated into one",
"Search filtering experience in UI has been improved",
"Now it's possible to search by the name of the repository and the name of the owning organization or user",
"Added support to allow filtering packages by category",
"An operator flag has been added to the package entity, and it's possible to filter by it",
"Repositories URL is now exposed to users in several places in the UI",
"Some bugs fixes"
{ "description": "Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)" },
{ "description": "Trackers have been improved and consolidated into one" },
{ "description": "Search filtering experience in UI has been improved" },
{
"description": "Now it's possible to search by the name of the repository and the name of the owning organization or user"
},
{ "description": "Added support to allow filtering packages by category" },
{ "description": "An operator flag has been added to the package entity, and it's possible to filter by it" },
{ "description": "Repositories URL is now exposed to users in several places in the UI" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.7.0",
"ts": 1604048487,
"changes": [
"Introduce packages security report",
"Display packages' license in cards",
"Allow filtering packages by license and operator capabilities",
"Add support for some extra Helm and OLM annotations",
"Add repositories guide",
"Allow adding CRDs for operators in Helm packages",
"Display search tips and add some extra sample searches",
"Improve user experience in authorization configuration view",
"Some bugs fixes and improvements"
{ "description": "Introduce packages security report" },
{ "description": "Display packages' license in cards" },
{ "description": "Allow filtering packages by license and operator capabilities" },
{ "description": "Add support for some extra Helm and OLM annotations" },
{ "description": "Add repositories guide" },
{ "description": "Allow adding CRDs for operators in Helm packages" },
{ "description": "Display search tips and add some extra sample searches" },
{ "description": "Improve user experience in authorization configuration view" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.2.0",
"ts": 1604048487,
"changes": [
"API docs",
"Reorganize API routes",
"Some HTTP handlers improvements",
"Support for API keys",
"API rate limiting",
"Signed packages label (Helm provenance file)",
"Home page updated",
"Bug fixes"
{ "description": "API docs" },
{ "description": "Reorganize API routes" },
{ "description": "Some HTTP handlers improvements" },
{ "description": "Support for API keys" },
{ "description": "API rate limiting" },
{ "description": "Signed packages label (Helm provenance file)" },
{ "description": "Home page updated" },
{ "description": "Bug fixes" }
]
}
]

View File

@ -3,106 +3,108 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.8.0",
"ts": 1604048487,
"changes": [
"Add JSON schema for Artifact Hub Helm chart",
"Some improvements in Artifact Hub Helm chart",
"Track Helm charts values schema",
"Add endpoint to get Helm charts values schema",
"Bump Trivy to 0.12.0",
"Display containers images in Helm packages",
"Remove internal requests limiter",
"Upgrade frontend dependencies to fix some security vulnerabilities",
"Add packages security report documentation",
"Some bugs fixes and improvements"
{ "description": "Add JSON schema for Artifact Hub Helm chart" },
{ "description": "Some improvements in Artifact Hub Helm chart" },
{ "description": "Track Helm charts values schema" },
{ "description": "Add endpoint to get Helm charts values schema" },
{ "description": "Bump Trivy to 0.12.0" },
{ "description": "Display containers images in Helm packages" },
{ "description": "Remove internal requests limiter" },
{ "description": "Upgrade frontend dependencies to fix some security vulnerabilities" },
{ "description": "Add packages security report documentation" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.3.0",
"ts": 1604048487,
"changes": [
"Added support for OLM operators repositories",
"Added support for Falco rules repositories",
"Added RSS feed for packages' new version releases",
"Packages now always belong to a repository",
"Reorganized some API routes (breaking changes)",
"Added a link to browse all packages and some sample searches to home page",
"Added CNCF Sandbox logo to home page",
"Some minor improvements in search page filters",
"Package creation time is now tracked and displayed",
"Some bugs fixes"
{ "description": "Added support for OLM operators repositories" },
{ "description": "Added support for Falco rules repositories" },
{ "description": "Added RSS feed for packages' new version releases" },
{ "description": "Packages now always belong to a repository" },
{ "description": "Reorganized some API routes (breaking changes)" },
{ "description": "Added a link to browse all packages and some sample searches to home page" },
{ "description": "Added CNCF Sandbox logo to home page" },
{ "description": "Some minor improvements in search page filters" },
{ "description": "Package creation time is now tracked and displayed" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.6.0",
"ts": 1604048487,
"changes": [
"Introduce fine grained authorization mechanism based on OPA policies",
"Allow enriching package information using Helm annotations",
"Allow entities to claim repositories ownership",
"Introduce official repository concept",
"Add verified publisher and official repository search filters",
"Artifact Hub repositories badges",
"Test Artifact Hub Helm chart",
"Improve package view on mobile devices",
"Add API endpoint to get repositories by kind",
"Some bugs fixes and improvements"
{ "description": "Introduce fine grained authorization mechanism based on OPA policies" },
{ "description": "Allow enriching package information using Helm annotations" },
{ "description": "Allow entities to claim repositories ownership" },
{ "description": "Introduce official repository concept" },
{ "description": "Add verified publisher and official repository search filters" },
{ "description": "Artifact Hub repositories badges" },
{ "description": "Test Artifact Hub Helm chart" },
{ "description": "Improve package view on mobile devices" },
{ "description": "Add API endpoint to get repositories by kind" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.4.0",
"ts": 1604048487,
"changes": [
"Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)",
"Trackers have been improved and consolidated into one",
"Search filtering experience in UI has been improved",
"Now it's possible to search by the name of the repository and the name of the owning organization or user",
"Added support to allow filtering packages by category",
"An operator flag has been added to the package entity, and it's possible to filter by it",
"Repositories URL is now exposed to users in several places in the UI",
"Some bugs fixes"
{ "description": "Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)" },
{ "description": "Trackers have been improved and consolidated into one" },
{ "description": "Search filtering experience in UI has been improved" },
{
"description": "Now it's possible to search by the name of the repository and the name of the owning organization or user"
},
{ "description": "Added support to allow filtering packages by category" },
{ "description": "An operator flag has been added to the package entity, and it's possible to filter by it" },
{ "description": "Repositories URL is now exposed to users in several places in the UI" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.7.0",
"ts": 1604048487,
"changes": [
"Introduce packages security report",
"Display packages' license in cards",
"Allow filtering packages by license and operator capabilities",
"Add support for some extra Helm and OLM annotations",
"Add repositories guide",
"Allow adding CRDs for operators in Helm packages",
"Display search tips and add some extra sample searches",
"Improve user experience in authorization configuration view",
"Some bugs fixes and improvements"
{ "description": "Introduce packages security report" },
{ "description": "Display packages' license in cards" },
{ "description": "Allow filtering packages by license and operator capabilities" },
{ "description": "Add support for some extra Helm and OLM annotations" },
{ "description": "Add repositories guide" },
{ "description": "Allow adding CRDs for operators in Helm packages" },
{ "description": "Display search tips and add some extra sample searches" },
{ "description": "Improve user experience in authorization configuration view" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.2.0",
"ts": 1604048487,
"changes": [
"API docs",
"Reorganize API routes",
"Some HTTP handlers improvements",
"Support for API keys",
"API rate limiting",
"Signed packages label (Helm provenance file)",
"Home page updated",
"Bug fixes"
{ "description": "API docs" },
{ "description": "Reorganize API routes" },
{ "description": "Some HTTP handlers improvements" },
{ "description": "Support for API keys" },
{ "description": "API rate limiting" },
{ "description": "Signed packages label (Helm provenance file)" },
{ "description": "Home page updated" },
{ "description": "Bug fixes" }
]
}
]

View File

@ -3,106 +3,108 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.8.0",
"ts": 1604048487,
"changes": [
"Add JSON schema for Artifact Hub Helm chart",
"Some improvements in Artifact Hub Helm chart",
"Track Helm charts values schema",
"Add endpoint to get Helm charts values schema",
"Bump Trivy to 0.12.0",
"Display containers images in Helm packages",
"Remove internal requests limiter",
"Upgrade frontend dependencies to fix some security vulnerabilities",
"Add packages security report documentation",
"Some bugs fixes and improvements"
{ "description": "Add JSON schema for Artifact Hub Helm chart" },
{ "description": "Some improvements in Artifact Hub Helm chart" },
{ "description": "Track Helm charts values schema" },
{ "description": "Add endpoint to get Helm charts values schema" },
{ "description": "Bump Trivy to 0.12.0" },
{ "description": "Display containers images in Helm packages" },
{ "description": "Remove internal requests limiter" },
{ "description": "Upgrade frontend dependencies to fix some security vulnerabilities" },
{ "description": "Add packages security report documentation" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.3.0",
"ts": 1604048487,
"changes": [
"Added support for OLM operators repositories",
"Added support for Falco rules repositories",
"Added RSS feed for packages' new version releases",
"Packages now always belong to a repository",
"Reorganized some API routes (breaking changes)",
"Added a link to browse all packages and some sample searches to home page",
"Added CNCF Sandbox logo to home page",
"Some minor improvements in search page filters",
"Package creation time is now tracked and displayed",
"Some bugs fixes"
{ "description": "Added support for OLM operators repositories" },
{ "description": "Added support for Falco rules repositories" },
{ "description": "Added RSS feed for packages' new version releases" },
{ "description": "Packages now always belong to a repository" },
{ "description": "Reorganized some API routes (breaking changes)" },
{ "description": "Added a link to browse all packages and some sample searches to home page" },
{ "description": "Added CNCF Sandbox logo to home page" },
{ "description": "Some minor improvements in search page filters" },
{ "description": "Package creation time is now tracked and displayed" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.6.0",
"ts": 1604048487,
"changes": [
"Introduce fine grained authorization mechanism based on OPA policies",
"Allow enriching package information using Helm annotations",
"Allow entities to claim repositories ownership",
"Introduce official repository concept",
"Add verified publisher and official repository search filters",
"Artifact Hub repositories badges",
"Test Artifact Hub Helm chart",
"Improve package view on mobile devices",
"Add API endpoint to get repositories by kind",
"Some bugs fixes and improvements"
{ "description": "Introduce fine grained authorization mechanism based on OPA policies" },
{ "description": "Allow enriching package information using Helm annotations" },
{ "description": "Allow entities to claim repositories ownership" },
{ "description": "Introduce official repository concept" },
{ "description": "Add verified publisher and official repository search filters" },
{ "description": "Artifact Hub repositories badges" },
{ "description": "Test Artifact Hub Helm chart" },
{ "description": "Improve package view on mobile devices" },
{ "description": "Add API endpoint to get repositories by kind" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.4.0",
"ts": 1604048487,
"changes": [
"Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)",
"Trackers have been improved and consolidated into one",
"Search filtering experience in UI has been improved",
"Now it's possible to search by the name of the repository and the name of the owning organization or user",
"Added support to allow filtering packages by category",
"An operator flag has been added to the package entity, and it's possible to filter by it",
"Repositories URL is now exposed to users in several places in the UI",
"Some bugs fixes"
{ "description": "Added support for OPA policies repositories (uses Artifact Hub metadata new spec draft)" },
{ "description": "Trackers have been improved and consolidated into one" },
{ "description": "Search filtering experience in UI has been improved" },
{
"description": "Now it's possible to search by the name of the repository and the name of the owning organization or user"
},
{ "description": "Added support to allow filtering packages by category" },
{ "description": "An operator flag has been added to the package entity, and it's possible to filter by it" },
{ "description": "Repositories URL is now exposed to users in several places in the UI" },
{ "description": "Some bugs fixes" }
]
},
{
"version": "0.7.0",
"ts": 1604048487,
"changes": [
"Introduce packages security report",
"Display packages' license in cards",
"Allow filtering packages by license and operator capabilities",
"Add support for some extra Helm and OLM annotations",
"Add repositories guide",
"Allow adding CRDs for operators in Helm packages",
"Display search tips and add some extra sample searches",
"Improve user experience in authorization configuration view",
"Some bugs fixes and improvements"
{ "description": "Introduce packages security report" },
{ "description": "Display packages' license in cards" },
{ "description": "Allow filtering packages by license and operator capabilities" },
{ "description": "Add support for some extra Helm and OLM annotations" },
{ "description": "Add repositories guide" },
{ "description": "Allow adding CRDs for operators in Helm packages" },
{ "description": "Display search tips and add some extra sample searches" },
{ "description": "Improve user experience in authorization configuration view" },
{ "description": "Some bugs fixes and improvements" }
]
},
{
"version": "0.2.0",
"ts": 1604048487,
"changes": [
"API docs",
"Reorganize API routes",
"Some HTTP handlers improvements",
"Support for API keys",
"API rate limiting",
"Signed packages label (Helm provenance file)",
"Home page updated",
"Bug fixes"
{ "description": "API docs" },
{ "description": "Reorganize API routes" },
{ "description": "Some HTTP handlers improvements" },
{ "description": "Support for API keys" },
{ "description": "API rate limiting" },
{ "description": "Signed packages label (Helm provenance file)" },
{ "description": "Home page updated" },
{ "description": "Bug fixes" }
]
}
]

View File

@ -3,15 +3,15 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{

View File

@ -3,15 +3,15 @@
"version": "0.5.0",
"ts": 1604048487,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{

View File

@ -4,15 +4,15 @@
"ts": 1604048487,
"containsSecurityUpdates": true,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{

View File

@ -5,15 +5,15 @@
"containsSecurityUpdates": false,
"prerelease": true,
"changes": [
"Introduce verified publisher concept",
"Add dark mode support",
"Improve search facets filtering",
"Notify repository owners of tracking errors",
"Track and list Helm charts dependencies",
"Display links to source in Helm packages",
"Add repositories kind filter to tracker",
"Add Monocular compatible search API",
"Some bugs fixes and improvements"
{ "description": "Introduce verified publisher concept" },
{ "description": "Add dark mode support" },
{ "description": "Improve search facets filtering" },
{ "description": "Notify repository owners of tracking errors" },
{ "description": "Track and list Helm charts dependencies" },
{ "description": "Display links to source in Helm packages" },
{ "description": "Add repositories kind filter to tracker" },
{ "description": "Add Monocular compatible search API" },
{ "description": "Some bugs fixes and improvements" }
]
},
{

View File

@ -24,6 +24,7 @@
--color-black-5: rgba(255, 255, 255, 0.05);
--color-black-15: rgba(255, 255, 255, 0.15);
--color-black-25: rgba(255, 255, 255, 0.25);
--color-black-50: rgba(255, 255, 255, 0.5);
--color-black-75: rgba(255, 255, 255, 0.75);
--color-black-90: rgba(255, 255, 255, 0.9);

View File

@ -24,6 +24,7 @@
--color-black-5: rgba(0, 0, 0, 0.05);
--color-black-15: rgba(0, 0, 0, 0.15);
--color-black-25: rgba(0, 0, 0, 0.25);
--color-black-50: rgba(0, 0, 0, 0.5);
--color-black-75: rgba(0, 0, 0, 0.75);
--color-black-90: rgba(0, 0, 0, 0.9);

View File

@ -562,12 +562,27 @@ export interface CVSSVectorOpt {
level: number;
}
export enum ChangeKind {
added = 'added',
changed = 'changed',
deprecated = 'deprecated',
removed = 'removed',
fixed = 'fixed',
security = 'security',
}
export interface Change {
kind?: ChangeKind;
description: string;
links?: PackageLink[];
}
export interface ChangeLog {
version: string;
ts: number;
prerelease: boolean;
containsSecurityUpdates: boolean;
changes?: string[] | null;
changes?: Change[];
}
export interface ActiveJSONSchemaValue {

View File

@ -9836,12 +9836,10 @@ react-error-overlay@^6.0.7:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.8.tgz#474ed11d04fc6bda3af643447d85e9127ed6b5de"
integrity sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw==
react-icons@^3.11.0:
version "3.11.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-3.11.0.tgz#2ca2903dfab8268ca18ebd8cc2e879921ec3b254"
integrity sha512-JRgiI/vdF6uyBgyZhVyYJUZAop95Sy4XDe/jmT3R/bKliFWpO/uZBwvSjWEdxwzec7SYbEPNPck0Kff2tUGM2Q==
dependencies:
camelcase "^5.0.0"
react-icons@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0"
integrity sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ==
react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6:
version "16.13.1"