Generate table of FF in documentation automatically from the definitions

parent ddb1860f
......@@ -371,6 +371,9 @@ prepare_release_checklist_issue: $(GOPATH_SETUP)
-issue-template-file ".gitlab/issue_templates/Release Checklist.md" \
$(opts)
update_feature_flags_docs: $(GOPATH_SETUP)
go run ./scripts/update-feature-flags-docs/main.go
development_setup:
test -d tmp/gitlab-test || git clone https://gitlab.com/gitlab-org/ci-cd/tests/gitlab-test.git tmp/gitlab-test
if prlctl --version ; then $(MAKE) -C tests/ubuntu parallels ; fi
......
......@@ -26,13 +26,19 @@ change hidden behind the feature flag disabled a corresponding environment varia
## Available feature flags
| Feature flag | Default value | Deprecated | To be removed with | Description |
|--------------------------------------|---------------|------------|--------------------|-------------|
| `FF_K8S_USE_ENTRYPOINT_OVER_COMMAND` | `true` | ✓ | 12.0 | Enables [the fix][mr-1010] for entrypoint configuration when `kubernetes` executor is used. |
| `FF_DOCKER_HELPER_IMAGE_V2` | `false` | ✓ | 12.0 | Enable the helper image to use the new commands when [helper_image](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersdocker-section) is specified. This will start using the new API that will be used in 12.0 and stop showing the warning message in the build log. |
| `FF_CMD_DISABLE_DELAYED_ERROR_LEVEL_EXPANSION` | `false` | ✓ | TBA | Disables [EnableDelayedExpansion](https://ss64.com/nt/delayedexpansion.html) for error checking for when using [Window Batch](https://docs.gitlab.com/runner/shells/#windows-batch) shell. |
| `FF_USE_LEGACY_GIT_CLEAN_STRATEGY` | `false` | ✓ | 12.0 | Enables the new strategy for `git clean` that moves the clean operation after checkout and enables support for `GIT_CLEAN_FLAGS` |
| `FF_USE_LEGACY_BUILDS_DIR_FOR_DOCKER` | `false` | ✓ | 13.0 | Enables the new strategy for Docker executor to cache the content of `/builds` directory instead of `/builds/group-org` |
[mr-1010]: https://gitlab.com/gitlab-org/gitlab-runner/merge_requests/1010
<!--
The list of feature flags is created automatically.
If you need to update it, call `make update_feature_flags_docs` in the
root directory of this project.
The flags are defined in `./helpers/feature_flags/flags.go` file.
-->
<!-- feature_flags_list_start -->
| Feature flag | Default value | Deprecated | To be removed with | Description |
|--------------|---------------|------------|--------------------|-------------|
| `FF_K8S_USE_ENTRYPOINT_OVER_COMMAND` | `true` | ✓ | 12.0 | Enables [the fix](https://gitlab.com/gitlab-org/gitlab-runner/merge_requests/1010) for entrypoint configuration when `kubernetes` executor is used |
| `FF_DOCKER_HELPER_IMAGE_V2` | `false` | ✓ | 12.0 | Enable the helper image to use the new commands when [helper_image](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnersdocker-section) is specified. This will start using the new API that will be used in 12.0 and stop showing the warning message in the build log |
| `FF_CMD_DISABLE_DELAYED_ERROR_LEVEL_EXPANSION` | `false` | ✗ | | Disables [EnableDelayedExpansion](https://ss64.com/nt/delayedexpansion.html) for error checking for when using [Window Batch](https://docs.gitlab.com/runner/shells/#windows-batch) shell |
| `FF_USE_LEGACY_GIT_CLEAN_STRATEGY` | `false` | ✓ | 12.0 | Enables the new strategy for `git clean` that moves the clean operation after checkout and enables support for `GIT_CLEAN_FLAGS` |
| `FF_USE_LEGACY_BUILDS_DIR_FOR_DOCKER` | `false` | ✓ | 13.0 | Enables the new strategy for Docker executor to cache the content of `/builds` directory instead of `/builds/group-org` |
<!-- feature_flags_list_end -->
......@@ -20,6 +20,11 @@ type FeatureFlag struct {
Description string
}
// REMEMBER to update the documentation after adding or removing a feature flag
//
// Please use `make update_feature_flags_docs` to make the update automatic and
// properly formatted. It will replace the existing table with the new one, computed
// basing on the values below
var flags = []FeatureFlag{
{
Name: FFK8sEntrypointOverCommand,
......
package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"strings"
"text/template"
"gitlab.com/gitlab-org/gitlab-runner/helpers/featureflags"
)
const (
docsFile = "./docs/configuration/feature-flags.md"
startPlaceholder = "<!-- feature_flags_list_start -->"
endPlaceholder = "<!-- feature_flags_list_end -->"
)
var ffTableTemplate = `{{ placeholder "start" }}
| Feature flag | Default value | Deprecated | To be removed with | Description |
|--------------|---------------|------------|--------------------|-------------|
{{ range $_, $flag := . -}}
| {{ $flag.Name | raw }} | {{ $flag.DefaultValue | raw }} | {{ $flag.Deprecated | tick }} | {{ $flag.ToBeRemovedWith }} | {{ $flag.Description }} |
{{ end -}}
{{ placeholder "end" }}
`
func main() {
fileContent := getFileContent()
tableContent := prepareTable()
newFileContent := replace(fileContent, tableContent)
saveFileContent(newFileContent)
}
func getFileContent() string {
data, err := ioutil.ReadFile(docsFile)
if err != nil {
panic(fmt.Sprintf("Error while reading file %q: %v", docsFile, err))
}
return string(data)
}
func prepareTable() string {
tpl := template.New("ffTable")
tpl.Funcs(template.FuncMap{
"placeholder": func(placeholderType string) string {
switch placeholderType {
case "start":
return startPlaceholder
case "end":
return endPlaceholder
default:
panic(fmt.Sprintf("Undefined placeholder type %q", placeholderType))
}
},
"raw": func(input string) string {
return fmt.Sprintf("`%s`", input)
},
"tick": func(input bool) string {
if input {
return "✓"
}
return "✗"
},
})
tpl, err := tpl.Parse(ffTableTemplate)
if err != nil {
panic(fmt.Sprintf("Error while parsing the template: %v", err))
}
buffer := new(bytes.Buffer)
err = tpl.Execute(buffer, featureflags.GetAll())
if err != nil {
panic(fmt.Sprintf("Error while executing the template: %v", err))
}
return buffer.String()
}
func replace(fileContent string, tableContent string) string {
replacer := newBlockLineReplacer(startPlaceholder, endPlaceholder, fileContent, tableContent)
newContent, err := replacer.Replace()
if err != nil {
panic(fmt.Sprintf("Error while replacing the content: %v", err))
}
return newContent
}
func saveFileContent(newFileContent string) {
err := ioutil.WriteFile(docsFile, []byte(newFileContent), 0644)
if err != nil {
panic(fmt.Sprintf("Error while writing new content for %q file: %v", docsFile, err))
}
}
type blockLineReplacer struct {
startLine string
endLine string
replaceContent string
input *bytes.Buffer
output *bytes.Buffer
startFound bool
endFound bool
}
func (r *blockLineReplacer) Replace() (string, error) {
for {
line, err := r.input.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
return "", fmt.Errorf("error while reading issue description: %v", err)
}
r.handleLine(line)
}
return r.output.String(), nil
}
func (r *blockLineReplacer) handleLine(line string) {
r.handleStart(line)
r.handleRewrite(line)
r.handleEnd(line)
}
func (r *blockLineReplacer) handleStart(line string) {
if r.startFound || !strings.Contains(line, r.startLine) {
return
}
r.startFound = true
}
func (r *blockLineReplacer) handleRewrite(line string) {
if r.startFound && !r.endFound {
return
}
r.output.WriteString(line)
}
func (r *blockLineReplacer) handleEnd(line string) {
if !strings.Contains(line, r.endLine) {
return
}
r.endFound = true
r.output.WriteString(r.replaceContent)
}
func newBlockLineReplacer(startLine string, endLine string, input string, replaceContent string) *blockLineReplacer {
return &blockLineReplacer{
startLine: startLine,
endLine: endLine,
input: bytes.NewBufferString(input),
output: new(bytes.Buffer),
replaceContent: replaceContent,
startFound: false,
endFound: false,
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment