Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
* upstream/main:
  Replace some `gt-` classes with `tw-` (go-gitea#29570)
  Enable/disable owner and repo projects independently (go-gitea#28805)
  Add an trailing slash to dashboard links (go-gitea#29555)
  Extend issue template yaml engine (go-gitea#29274)
  [skip ci] Updated licenses and gitignores
  Fix workflow trigger event IssueChangeXXX bug (go-gitea#29559)
  Fix 500 when pushing release to an empty repo (go-gitea#29554)
  Update js and py dependencies, bump python (go-gitea#29561)
  Filter Repositories by type (go-gitea#29231)
  • Loading branch information
zjjhot committed Mar 4, 2024
2 parents b476683 + a2e9001 commit b9e4a44
Show file tree
Hide file tree
Showing 93 changed files with 1,380 additions and 784 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/pull-compliance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"
- run: pip install poetry
- run: make deps-py
- run: make lint-templates
Expand All @@ -45,9 +45,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"
- run: pip install poetry
- run: make deps-py
- run: make lint-yaml
Expand Down
1 change: 1 addition & 0 deletions .stylelintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ rules:
"@stylistic/media-query-list-comma-newline-before": null
"@stylistic/media-query-list-comma-space-after": null
"@stylistic/media-query-list-comma-space-before": null
"@stylistic/named-grid-areas-alignment": null
"@stylistic/no-empty-first-line": null
"@stylistic/no-eol-whitespace": true
"@stylistic/no-extra-semicolons": true
Expand Down
52 changes: 37 additions & 15 deletions docs/content/usage/issue-pull-request-templates.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ body:
attributes:
value: |
Thanks for taking the time to fill out this bug report!
# some markdown that will only be visible once the issue has been created
- type: markdown
attributes:
value: |
This issue was created by an issue **template** :)
visible: [content]
- type: input
id: contact
attributes:
Expand Down Expand Up @@ -187,18 +193,25 @@ body:
options:
- label: I agree to follow this project's Code of Conduct
required: true
- label: I have also read the CONTRIBUTION.MD
required: true
visible: [form]
- label: This is a TODO only visible after issue creation
visible: [content]
```
### Markdown
You can use a `markdown` element to display Markdown in your form that provides extra context to the user, but is not submitted.
You can use a `markdown` element to display Markdown in your form that provides extra context to the user, but is not submitted by default.

Attributes:

| Key | Description | Required | Type | Default | Valid values |
|-------|--------------------------------------------------------------|----------|--------|---------|--------------|
| value | The text that is rendered. Markdown formatting is supported. | Required | String | - | - |

visible: Default is **[form]**

### Textarea

You can use a `textarea` element to add a multi-line text field to your form. Contributors can also attach files in `textarea` fields.
Expand All @@ -219,6 +232,8 @@ Validations:
|----------|------------------------------------------------------|----------|---------|---------|--------------|
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |

visible: Default is **[form, content]**

### Input

You can use an `input` element to add a single-line text field to your form.
Expand All @@ -240,6 +255,8 @@ Validations:
| is_number | Prevents form submission until element is filled with a number. | Optional | Boolean | false | - |
| regex | Prevents form submission until element is filled with a value that match the regular expression. | Optional | String | - | a [regular expression](https://en.wikipedia.org/wiki/Regular_expression) |

visible: Default is **[form, content]**

### Dropdown

You can use a `dropdown` element to add a dropdown menu in your form.
Expand All @@ -259,24 +276,29 @@ Validations:
|----------|------------------------------------------------------|----------|---------|---------|--------------|
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |

visible: Default is **[form, content]**

### Checkboxes

You can use the `checkboxes` element to add a set of checkboxes to your form.

Attributes:

| Key | Description | Required | Type | Default | Valid values |
|-------------|-------------------------------------------------------------------------------------------------------|----------|--------|--------------|--------------|
| ----------- | ----------------------------------------------------------------------------------------------------- | -------- | ------ | ------------ | ------------ |
| label | A brief description of the expected user input, which is displayed in the form. | Required | String | - | - |
| description | A description of the set of checkboxes, which is displayed in the form. Supports Markdown formatting. | Optional | String | Empty String | - |
| options | An array of checkboxes that the user can select. For syntax, see below. | Required | Array | - | - |

For each value in the options array, you can set the following keys.

| Key | Description | Required | Type | Default | Options |
|----------|------------------------------------------------------------------------------------------------------------------------------------------|----------|---------|---------|---------|
| label | The identifier for the option, which is displayed in the form. Markdown is supported for bold or italic text formatting, and hyperlinks. | Required | String | - | - |
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |
| Key | Description | Required | Type | Default | Options |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------|----------|--------------|---------|---------|
| label | The identifier for the option, which is displayed in the form. Markdown is supported for bold or italic text formatting, and hyperlinks. | Required | String | - | - |
| required | Prevents form submission until element is completed. | Optional | Boolean | false | - |
| visible | Whether a specific checkbox appears in the form only, in the created issue only, or both. Valid options are "form" and "content". | Optional | String array | false | - |

visible: Default is **[form, content]**

## Syntax for issue config

Expand All @@ -292,15 +314,15 @@ contact_links:

### Possible Options

| Key | Description | Type | Default |
|----------------------|-------------------------------------------------------------------------------------------------------|--------------------|----------------|
| blank_issues_enabled | If set to false, the User is forced to use a Template | Boolean | true |
| contact_links | Custom Links to show in the Choose Box | Contact Link Array | Empty Array |
| Key | Description | Type | Default |
|----------------------|-------------------------------------------------------|--------------------|-------------|
| blank_issues_enabled | If set to false, the User is forced to use a Template | Boolean | true |
| contact_links | Custom Links to show in the Choose Box | Contact Link Array | Empty Array |

### Contact Link

| Key | Description | Type | Required |
|----------------------|-------------------------------------------------------------------------------------------------------|---------|----------|
| name | the name of your link | String | true |
| url | The URL of your Link | String | true |
| about | A short description of your Link | String | true |
| Key | Description | Type | Required |
|-------|----------------------------------|--------|----------|
| name | the name of your link | String | true |
| url | The URL of your Link | String | true |
| about | A short description of your Link | String | true |
7 changes: 1 addition & 6 deletions models/fixtures/repo_unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@
id: 75
repo_id: 1
type: 8
config: "{\"ProjectsMode\":\"all\"}"
created_unix: 946684810

-
Expand Down Expand Up @@ -650,12 +651,6 @@
type: 2
created_unix: 946684810

-
id: 98
repo_id: 1
type: 8
created_unix: 946684810

-
id: 99
repo_id: 1
Expand Down
5 changes: 5 additions & 0 deletions models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ func (repo *Repository) MustGetUnit(ctx context.Context, tp unit.Type) *RepoUnit
Type: tp,
Config: new(ActionsConfig),
}
} else if tp == unit.TypeProjects {
return &RepoUnit{
Type: tp,
Config: new(ProjectsConfig),
}
}

return &RepoUnit{
Expand Down
56 changes: 55 additions & 1 deletion models/repo/repo_unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,53 @@ func (cfg *ActionsConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}

// ProjectsMode represents the projects enabled for a repository
type ProjectsMode string

const (
// ProjectsModeRepo allows only repo-level projects
ProjectsModeRepo ProjectsMode = "repo"
// ProjectsModeOwner allows only owner-level projects
ProjectsModeOwner ProjectsMode = "owner"
// ProjectsModeAll allows both kinds of projects
ProjectsModeAll ProjectsMode = "all"
// ProjectsModeNone doesn't allow projects
ProjectsModeNone ProjectsMode = "none"
)

// ProjectsConfig describes projects config
type ProjectsConfig struct {
ProjectsMode ProjectsMode
}

// FromDB fills up a ProjectsConfig from serialized format.
func (cfg *ProjectsConfig) FromDB(bs []byte) error {
return json.UnmarshalHandleDoubleEncode(bs, &cfg)
}

// ToDB exports a ProjectsConfig to a serialized format.
func (cfg *ProjectsConfig) ToDB() ([]byte, error) {
return json.Marshal(cfg)
}

func (cfg *ProjectsConfig) GetProjectsMode() ProjectsMode {
if cfg.ProjectsMode != "" {
return cfg.ProjectsMode
}

return ProjectsModeNone
}

func (cfg *ProjectsConfig) IsProjectsAllowed(m ProjectsMode) bool {
projectsMode := cfg.GetProjectsMode()

if m == ProjectsModeNone {
return true
}

return projectsMode == m || projectsMode == ProjectsModeAll
}

// BeforeSet is invoked from XORM before setting the value of a field of this object.
func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
switch colName {
Expand All @@ -217,7 +264,9 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
r.Config = new(IssuesConfig)
case unit.TypeActions:
r.Config = new(ActionsConfig)
case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, unit.TypePackages:
case unit.TypeProjects:
r.Config = new(ProjectsConfig)
case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypePackages:
fallthrough
default:
r.Config = new(UnitConfig)
Expand Down Expand Up @@ -265,6 +314,11 @@ func (r *RepoUnit) ActionsConfig() *ActionsConfig {
return r.Config.(*ActionsConfig)
}

// ProjectsConfig returns config for unit.ProjectsConfig
func (r *RepoUnit) ProjectsConfig() *ProjectsConfig {
return r.Config.(*ProjectsConfig)
}

func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
var tmpUnits []*RepoUnit
if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil {
Expand Down
69 changes: 62 additions & 7 deletions modules/issue/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,13 @@ func validateRequired(field *api.IssueFormField, idx int) error {
// The label is not required for a markdown or checkboxes field
return nil
}
return validateBoolItem(newErrorPosition(idx, field.Type), field.Validations, "required")
if err := validateBoolItem(newErrorPosition(idx, field.Type), field.Validations, "required"); err != nil {
return err
}
if required, _ := field.Validations["required"].(bool); required && !field.VisibleOnForm() {
return newErrorPosition(idx, field.Type).Errorf("can not require a hidden field")
}
return nil
}

func validateID(field *api.IssueFormField, idx int, ids container.Set[string]) error {
Expand Down Expand Up @@ -172,10 +178,38 @@ func validateOptions(field *api.IssueFormField, idx int) error {
return position.Errorf("'label' is required and should be a string")
}

if visibility, ok := opt["visible"]; ok {
visibilityList, ok := visibility.([]any)
if !ok {
return position.Errorf("'visible' should be list")
}
for _, visibleType := range visibilityList {
visibleType, ok := visibleType.(string)
if !ok || !(visibleType == "form" || visibleType == "content") {
return position.Errorf("'visible' list can only contain strings of 'form' and 'content'")
}
}
}

if required, ok := opt["required"]; ok {
if _, ok := required.(bool); !ok {
return position.Errorf("'required' should be a bool")
}

// validate if hidden field is required
if visibility, ok := opt["visible"]; ok {
visibilityList, _ := visibility.([]any)
isVisible := false
for _, v := range visibilityList {
if vv, _ := v.(string); vv == "form" {
isVisible = true
break
}
}
if !isVisible {
return position.Errorf("can not require a hidden checkbox")
}
}
}
}
}
Expand Down Expand Up @@ -238,7 +272,7 @@ func RenderToMarkdown(template *api.IssueTemplate, values url.Values) string {
IssueFormField: field,
Values: values,
}
if f.ID == "" {
if f.ID == "" || !f.VisibleInContent() {
continue
}
f.WriteTo(builder)
Expand All @@ -253,11 +287,6 @@ type valuedField struct {
}

func (f *valuedField) WriteTo(builder *strings.Builder) {
if f.Type == api.IssueFormFieldTypeMarkdown {
// markdown blocks do not appear in output
return
}

// write label
if !f.HideLabel() {
_, _ = fmt.Fprintf(builder, "### %s\n\n", f.Label())
Expand All @@ -269,6 +298,9 @@ func (f *valuedField) WriteTo(builder *strings.Builder) {
switch f.Type {
case api.IssueFormFieldTypeCheckboxes:
for _, option := range f.Options() {
if !option.VisibleInContent() {
continue
}
checked := " "
if option.IsChecked() {
checked = "x"
Expand Down Expand Up @@ -302,6 +334,10 @@ func (f *valuedField) WriteTo(builder *strings.Builder) {
} else {
_, _ = fmt.Fprintf(builder, "%s\n", value)
}
case api.IssueFormFieldTypeMarkdown:
if value, ok := f.Attributes["value"].(string); ok {
_, _ = fmt.Fprintf(builder, "%s\n", value)
}
}
_, _ = fmt.Fprintln(builder)
}
Expand All @@ -314,6 +350,9 @@ func (f *valuedField) Label() string {
}

func (f *valuedField) HideLabel() bool {
if f.Type == api.IssueFormFieldTypeMarkdown {
return true
}
if label, ok := f.Attributes["hide_label"].(bool); ok {
return label
}
Expand Down Expand Up @@ -385,6 +424,22 @@ func (o *valuedOption) IsChecked() bool {
return false
}

func (o *valuedOption) VisibleInContent() bool {
if o.field.Type == api.IssueFormFieldTypeCheckboxes {
if vs, ok := o.data.(map[string]any); ok {
if vl, ok := vs["visible"].([]any); ok {
for _, v := range vl {
if vv, _ := v.(string); vv == "content" {
return true
}
}
return false
}
}
}
return true
}

var minQuotesRegex = regexp.MustCompilePOSIX("^`{3,}")

// minQuotes return 3 or more back-quotes.
Expand Down
Loading

0 comments on commit b9e4a44

Please sign in to comment.