Merge pull request #1677 from aiyengar2/release-v2.6-v0.3.0-p1

[v0.3.0 charts-build-scripts] release-v2.6 PR 1: Modify Existing Scripts and Docs
pull/1678/head
Caleb Bron 2022-01-06 12:06:28 -07:00 committed by GitHub
commit 17164c68f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 650 additions and 172 deletions

25
.github/workflows/pull-request.yaml vendored Executable file
View File

@ -0,0 +1,25 @@
name: CI-pullrequest
on:
pull_request:
branches:
- dev-v2.6
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Checkout into branch
run: git checkout -b staging-pr-workflow
- name: Pull scripts
run: sudo make pull-scripts
- name: Pull in all relevant branches
run: git fetch origin release-v2.6
- name: Validate
run: sudo make validate

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
bin
*.DS_Store
.idea
.charts-build-scripts

View File

@ -1,10 +1,13 @@
pull-scripts:
./scripts/pull-scripts
TARGETS := prepare patch charts clean validate template
remove:
./scripts/remove-asset
TARGETS := prepare patch clean clean-cache charts list index unzip zip standardize validate template
$(TARGETS):
@ls ./bin/charts-build-scripts 1>/dev/null 2>/dev/null || ./scripts/pull-scripts
./bin/charts-build-scripts $@
@./scripts/pull-scripts
@./bin/charts-build-scripts $@
.PHONY: $(TARGETS)

176
README.md
View File

@ -1,89 +1,111 @@
## Live Branch
## Rancher Charts
This branch contains generated assets that have been officially released on charts.rancher.io.
This repository contains Helm charts served by Rancher Apps & Marketplace.
The following directory structure is expected:
```text
assets/
<package>/
<chart>-<packageVersion>.tgz
...
charts/
<package>
<chart>
<packageVersion>
# Unarchived Helm chart
### Branches
- `dev-2.X` branches contain charts that under active development, to be released in an upcoming Rancher release.
- `release-v2.X` branches contain charts that have already been developed, tested, and released on an existing Rancher release.
### Making Changes
Since this repository uses [`rancher/charts-build-scripts`](https://github.com/rancher/charts-build-scripts), making changes to this repository involves three steps:
1. Adding or modifying an existing `Package` tracked in the `packages/` directory. Usually involves `make prepare`, `make patch`, and `make clean`.
2. Running `make charts` to automatically generate assets used to serve a Helm repository (`charts/`, `assets/`, and `index.yaml`) based on the contents of `packages/`.
3. [CI] Running `make validate` to ensure that all generated assets are up-to-date and ready to be merged.
#### Versioning Charts
In this repository, all packages specify the `version` field in the `package.yaml`.
The versioning scheme roughly corresponds to the following rules (with exceptions):
- Major Version: represents the Rancher minor version these charts are being released to.
- Anything less than `100`: Rancher 2.5
- `100`: Rancher 2.6
- `101`: Rancher 2.7
- etc.
- Minor Version: represents a release line of a given chart within a Rancher minor version.
- Patch Version: represents a patch to a given release line of a chart within a Rancher minor version.
As a rule of thumb, you will only ever touch this version to **increment the patch version once per Rancher patch release**. Once it has been incremented, it should not be incremented again until the next Rancher patch release, even if the chart points to an upstream that has been modified.
For more information on how package versioning works, please see [`docs/developing.md`](docs/developing.md).
#### Rancher Version Annotations
In addition to modifying the chart version, the `catalog.cattle.io/rancher-version` annotation is required for user-facing charts which show up in Rancher UI; there is no need to add the annotation to CRD charts or internal charts (like fleet).
General guidelines when releasing a new version of a user-facing chart:
1. **Ensure the chart has the annotation `catalog.cattle.io/rancher-version` with an upper bound, such as `< 2.6.99-0`**. This indicates that a fresh install of the chart should be allowed in any version of Rancher at or below `2.6.99-0` line, but should not be freshly installable in Rancher `2.7.0+`.
2. If and only if a chart will **not** work in an older version of Rancher, you will need to **amend this annotation to also include a lower bound like `>= 2.6.2-0`**. e.g. `catalog.cattle.io/rancher-version: >= 2.6.2-0 < 2.6.99-0` indicates that this chart should only be freshly installable in Rancher `2.6.2+`, but should not be freshmy installable in `Rancher 2.7.0+`.
- If you do this, it is also recommended that you **modify the previously released chart to have `catalog.cattle.io/rancher-version: < 2.6.2-0`**. For instructions on how to modify existing charts, see [`docs/developing.md`](docs/developing.md).
#### Versioning FAQ
- Do we directly backport charts to previous Rancher minor versions (e.g. make `100.x.x` available in Rancher `2.5`)?
No, we do not. If a fix needs to go to both Rancher `2.5` and `v2.6`, we just release a new chart in each branch. Then, we forward-port the one released in the `release-v2.5` branch to `release-v2.6`.
If a fix that went into Rancher `2.6` needs to be backported to Rancher `2.5`, it will be the developer's responsibility to bump the chart version in `dev-v2.5`, copy back the changes, and release a **new** chart following the Rancher `2.5` versioning scheme to `release-v2.5`.
- If Rancher `2.5` releases Monitoring `14.5.100` and `16.6.0` and Rancher `2.6` releases Monitoring `100.0.0+up14.5.100` and `100.0.1+up16.6.0`, how do we prevent users from "downgrading" from `16.6.0` to `100.0.0+up14.5.100` on a `helm upgrade` after upgrading Rancher minor versions?
Currently, this is unavoidable. There is an expectation that users should look at the upstream annotation on the chart version (e.g. `+upX.Y.Z`), read the Rancher minor version release notes, or consult the chart's `README.md` or `app-README.md` before performing an upgrade on their applications after migrating to a new Rancher minor version.
We are still looking for a better way to mitigate this kind of risk.
- For Rancher version annotations, why we don't we need to add the lower bound all the time?
Each Rancher minor version has its dedicated chart release branch (e.g. `release-v2.5`, `release-v2.6`, etc.), so a chart designed for Rancher `2.6.x` will never be available or show up in Rancher `2.5.x`; therefore, we do not need to worry about setting a lower bound of `> 2.5.99-0` on all charts.
#### Supporting Images in Airgap
Currently, the scripts used to generate the `rancher-images.txt` (used for mirroring a private registry in a air-gapped Rancher setup) rely on `values.yaml` files in charts that nest all image repository and tags used by the Helm chart under `repository` and `tag` fields.
For example:
```yaml
image: org/repo:v0.0.0 # will not be picked up
hello:
world:
# will be picked up, even though it is nested under hello.world.*
repository: org/repo
tag: v0.0.0
os: windows # optional, takes in a comma-delimited list of supported OSs. By default, the OS is assumed to be "linux" but you can specify "windows" or "linux,windows" as well.
```
### Configuration
Therefore, any charts that are committed into this repository must nest references to Docker images in this format within each chart's `values.yaml`; if an upstream chart you are referencing does not follow this format, it is recommended that you refactor the chart's values.yaml to look like this:
This repository branch contains a `configuration.yaml` file that is used to specify how it interacts with other repository branches.
### Cutting a Release
In the Live branch, cutting a release requires you to copy the contents of the Staging branch into your Live Branch, which can be done with the following simple Bash script.
```bash
# Assuming that your upstream remote (e.g. https://github.com/rancher/charts.git) is named `upstream`
# Replace the following environment variables
STAGING_BRANCH=dev-v2.x
LIVE_BRANCH=release-v2.x
FORKED_BRANCH=release-v2.x.y
git fetch upstream
git checkout upstream/${LIVE_BRANCH} -b ${FORKED_BRANCH}
git branch -u origin/${FORKED_BRANCH}
git checkout upstream/${STAGING_BRANCH} -- charts assets index.yaml
git add charts assets index.yaml
git commit -m "Releasing chart"
git push --set-upstream origin ${FORKED_BRANCH}
# Create your pull request!
```yaml
images:
config_reloader:
repository: rancher/mirrored-jimmidyson-configmap-reload
tag: v0.4.0
fluentbit:
repository: rancher/mirrored-fluent-fluent-bit
tag: 1.7.9
fluentbit_debug:
repository: rancher/mirrored-fluent-fluent-bit
tag: 1.7.9-debug
fluentd:
repository: rancher/mirrored-banzaicloud-fluentd
tag: v1.12.4-alpine-1
nodeagent_fluentbit:
os: "windows"
repository: rancher/fluent-bit
tag: 1.7.4
```
Once complete, you should see the following:
- The `assets/` and `charts/` directories have been updated to match the Staging branch. All entires should be additions, not modifications.
- The `index.yaml`'s diff shows only adds additional entries and does not modify or remove existing ones.
### Links
No other changes are expected.
For more information on how to make changes to this repository, please see [`docs/developing.md`](docs/developing.md).
### Cutting an Out-Of-Band Chart Release
For more information on experimental features, please see [`docs/experimental.md`](docs/experimental.md).
Similar to the above steps, cutting an out-of-band chart release will involve porting over the new chart from the Staging branch via `git checkout`. However, you will need to manually regenerate the Helm index since you only want the index.yaml on the Live branch to be updated to include the single new chart.
For more information on commands that can be run in this repository, please see [`docs/makefile.md`](docs/makefile.md).
Use the following example Bash script to execute this change:
For more information on `Packages`, please see [`docs/packages.md`](docs/packages.md).
```bash
# Assuming that your upstream remote (e.g. https://github.com/rancher/charts.git) is named `upstream`
# Replace the following environment variables
STAGING_BRANCH=dev-v2.x
LIVE_BRANCH=release-v2.x
FORKED_BRANCH=release-v2.x.y
NEW_CHART_DIR=charts/rancher-monitoring/rancher-monitoring/X.Y.Z
NEW_ASSET_TGZ=assets/rancher-monitoring/rancher-monitoring-X.Y.Z.tgz
git fetch upstream
git checkout upstream/${LIVE_BRANCH} -b ${FORKED_BRANCH}
git branch -u origin/${FORKED_BRANCH}
git checkout upstream/${STAGING_BRANCH} -- ${NEW_CHART_DIR} ${NEW_ASSET_TGZ}
helm repo index --merge ./index.yaml --url assets assets; # FYI: This will generate new 'created' timestamps across *all charts*.
mv assets/index.yaml index.yaml
git add ${NEW_CHART_DIR} ${NEW_ASSET_TGZ} index.yaml
git commit -m "Releasing out-of-band chart"
git push --set-upstream origin ${FORKED_BRANCH}
# Create your pull request!
```
Once complete, you should see the following:
- The new chart should exist in `assets` and `charts`. Existing charts should not be modified.
- The `index.yaml`'s diff should show an additional entry for your new chart.
- The `index.yaml`'s diff should show modified `created` timestamps across all charts (due to the behavior of `helm repo index`).
No other changes are expected.
### Makefile
#### Basic Commands
`make pull-scripts`: Pulls in the version of the `charts-build-scripts` indicated in scripts.
`make validate`: Validates your current repository branch against all the repository branches indicated in your configuration.yaml
`make template`: Updates the current directory by applying the configuration.yaml on [upstream Go templates](https://github.com/rancher/charts-build-scripts/tree/master/templates/template) to pull in the most up-to-date docs, scripts, etc. from [rancher/charts-build-scripts](https://github.com/rancher/charts-build-scripts)
For more information on CI, please see [`docs/validation.md`](docs/validation.md).

View File

@ -1,3 +0,0 @@
## Assets
This folder contains Helm chart archives that are served from charts.rancher.io.

View File

@ -1,3 +0,0 @@
## Charts
This folder contains unarchived Helm charts that are served from charts.rancher.io.

View File

@ -1,4 +1,6 @@
template: live
helmRepo:
cname: charts.rancher.io
cname: charts.rancher.io
validate:
url: https://github.com/rancher/charts.git
branch: dev-v2.6

198
docs/developing.md Executable file
View File

@ -0,0 +1,198 @@
## Developer Workflow
### Introducing a new package
Introducing a new package usually requires two things: creating a directory under `packages` and filling in a `package.yaml`.
The following utility script can be used to create the necessary `package.yaml` file in the right location:
```shell
PACKAGE=<packageName> # can be nested, e.g. rancher-monitoring/rancher-windows-exporter is acceptable
mkdir -p packages/${PACKAGE}
touch packages/${PACKAGE}/package.yaml
```
Once the `packages/${PACKAGE}/package.yaml` file has been created, you will need to fill it in. A full explanation of the expected fields in the `package.yaml` can be found under [docs/packages.md](./packages.md); however, here are some simple common configurations you can use:
#### Local Chart
```yaml
url: local
# Depending on your organization, one of the following two fields might also need to be provided
# version: x.y.z
# packageVersion: 1
```
*Note: For local charts, you will also need to commit the Helm chart itself under `packages/${PACKAGE}/charts`.*
#### Upstream Chart From a Git Repository
```yaml
url: https://github.com/ORG/REPO.git
commit: xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX
subdirectory: charts/mychart # optional
# Depending on your organization, one of the following two fields might also need to be provided
# version: x.y.z
# packageVersion: 1
```
#### Upstream Chart From a Chart Archive
```yaml
url: https://github.com/ORG/REPO/releases/download/VERSION/CHART.tgz
subdirectory: charts/mychart # optional
# Depending on your organization, one of the following two fields might also need to be provided
# version: x.y.z
# packageVersion: 1
```
### Making Changes To Packages
As a developer making changes to a particular package, you will usually follow the following steps:
0. If you are working with a single `Package`, set `export PACKAGE=<packageName>`
- Note: This inform the scripts that you only want to make changes to a particular package. This will prevent the scripts from running commands on every package in this repository.
- Note: Starting v0.3.0 of the scripts, `PACKAGE` can refer to a nested structure, e.g. you can place packages under `packages/my-stuff/package-1` and `packages/my-stuff/package-2`. If you want to target all packages in this nested structure, set `PACKAGE=my-stuff`. If you want to target a specific package in this nested structure, set `PACKAGE=my-stuff/package-1`. It should be noted, however, that `make patch` will **only** work if you point to a specific package, so setting `PACKAGE=my-stuff` would cause it to fail.
1. If necessary, update the `version` or `packageVersion` field in the `package.yaml`. Then run `make charts` and commit the changes.
- Note: It is recommended that your commit message says something along the lines of `Bump ${PACKAGE} version to ${NEW_VERSION}`.
2. Run `make prepare`. This will produce a chart under `packages/${PACKAGE}/charts` that will serve as your working copy of the chart.
3. Make modifications **directly** to the working copy of the chart in `packages/${PACKAGE}/charts`.
- Note: **Do not modify `charts/${PACKAGE}/${CHART}/${VERSION}/` directly** since it will be overridden by changes to `packages/${PACKAGE}/charts`.
4. When you are happy with your changes, run `make patch`. This will automatically construct a `packages/${PACKAGE}/generated-changes` directory after assessing your current working directory in `packages/${PACKAGE}/charts`.
- Note: **You should never directly modify `packages/${PACKAGE}/generated-changes`** unless you are trying to change `packages/${PACKAGE}/generated-changes/dependencies` to update your chart dependencies. This directory is automatically constructed / destroyed by `make patch` to save the least amount of information necessary to reconstruct your working directory on a `make prepare`.
5. Run `make clean` to clean up your working directory. Then, commit your changes to Git with a commit message that indicates what you have changed.
- Note: **To avoid losing unsaved changes, do not run `make clean` unless you have already ran `make patch`.** `make clean` will delete the `packages/${PACKAGE}/charts` directory, so any modifications you made to the working copy of the chart will be lost.
6. To test your changes, run `make charts`. This will automatically create an `assets/${PACKAGE}/${CHART}-${VERSION}.tgz`, the `charts/${PACKAGE}/${CHART}/${VERSION}/` directory, and create or modify an existing `index.yaml`. Commit these changes to Git, usually with a commit titled `make charts`.
- Note: If you push the `make charts` commit to a repository, that repository would be a valid Helm repository to serve your chart.
If you need to make additional changes after testing, repeat steps 2-6.
If your repository is configured to use upstream validation (e.g. check if `validation.url` and `validation.branch` is specified in the root `configuration.yaml`), you will also need to add this new chart's name and version to the `release.yaml` or else you will fail CI. If you run `make validate` locally, it will automatically generate this file for you.
For more information on how to do this or why this is required, please see [`docs/validation.md`](docs/validation.md).
Otherwise, you are ready to make a PR!
### Rebasing An Existing Package
For forked charts only (e.g. any chart where the `package.yaml` does not have `url: local`), currently the scripts do not have good support for rebasing charts to a new upstream.
The reason why this is the case is that the patch files defined under `packages/${PACKAGE}/generated-changes/patch/*` are based on the old upstream, so when you change the URL it is unable to reconcile how to apply the patch.
Therefore, the best way to currently rebase is to follow the following workflow:
0. Set `PACKAGE=<packageName>` pointing to the specific package you want to work with.
1. If the chart has not been released yet, delete your existing charts, assets, and `index.yaml` entries corresponding to the chart you are rebasing by running `CHART=<chart> VERSION=<version> make remove` for each chart (e.g. if you have a chart that also packages a CRD chart, you will need to run `make remove` twice for the main chart and the CRD chart). Then, commit your changes to Git with a commit message that says "Remove charts/assets for ${CHART} ${VERSION}"
2. Without making any other changes, run `make prepare`. This will apply your existing patches on your existing upstream to produce `packages/${PACKAGE}/${workingDir}` (usually `packages/${PACKAGE}/charts`).
3. Modify the `package.yaml` to point to your new upstream.
4. Run `make patch`. This will destroy the current contents of `packages/${PACKAGE}/generated-changes` and reconstruct everything as if you were patching the new upstream with your **existing** chart.
5. Run `make clean`. Then, commit your changes to Git with a commit message that says "Rebase ${PACKAGE} from ${OLD_REF} to ${NEW_REF}"; this will make it easier for reviewers to see what you actually introduced in the next commit.
6. Follow the same developer workflow as defined under `Making Changes to Packages` to change the version, add back in changes introduced by upstream, and generate charts / assets.
Once these steps are compplete, you should have something similar to the following four commits:
1. "Remove charts/assets for ${CHART} ${VERSION}"
2. "Rebase ${PACKAGE} from ${OLD_REF} to ${NEW_REF}"
3. "Add changes from rebasing ${CHART} to ${NEW_VERSION}"
4. "make charts"
As a result, developers reviewing your chart can see changes made to `packages/` by reviewing changes between commit 2 and commit 3; they can also inspect changes introduced to `charts/` by viewing the overall diff on the PR, since the old assets will show as renamed / modified.
You are ready to make a PR!
### Versioning Packages
Generally, repositories that are using `charts-build-scripts` use one of the following two types of built-in versioning schemes for packages:
#### Version
This versioning scheme is used if `version` is specified in the `package.yaml`.
If a valid semver for `version` is provided, the final version of the chart will be the same as the `version` provided.
The only caveat is that **if** the main chart corresponds to some upstream chart whose chart version is not the same as the `version` provided, then the upstream version will be appended as a build annotation following the pattern `<version>+up<upstreamVersion>`.
*e.g. If `version` is 100.0.0 and the upstream chart's version is `1.2.3`, the final version will be `100.0.0+up1.2.3`.*
#### PackageVersion
This versioning scheme is used if `packageVersion` is specified in the `package.yaml`.
If a two-digit `packageVersion` is provided, the final version of the chart that is produced under the generated assets will be the same as the version specified by the main chart in the package, except the patch version of will be `int(originalPatchVersion * 100 + packageVersion)`.
Examples:
- If the main chart version is `1.2.3` and the packageVersion is `1`, the final chart version will be `1.2.301`.
- If the main chart version is `1.2.3` and the packageVersion is `56`, the final chart version will be `1.2.356`.
- If the main chart version is `2.1.0` and the packageVersion is `12`, the final chart version will be `2.1.12`.
- *Note: It is not `2.1.012` since a leading zero in the patch version is invalid semver.*
##### When should I update the packageVersion?
You should generally update the `packageVersion` **once per release**.
If the chart version you are currently modifying has already been released before, you should **bump the `packageVersion` by 1** to ensure you aren't modifying an already released chart.
*e.g. if chart version `1.2.301` is released, bumping the `packageVersion` to `2` will result in `1.2.302` being released next.*
If the chart version you are currently modifying has never been released before, you should **reset the `packageVersion` to 1**.
*e.g. if chart version `1.2.301` is released but you are currently working on releasing a package based on `1.3.0`, you should reset the `packageVersion` to `1` to release `1.3.1`.*
*Note: You should reset the packageVersion to 1 instead of 0 since the scripts will always introduce at least one change to the chart.*
### Updating Dependencies / Subcharts
The scripts used to maintain this repository natively supports managing dependencies / subcharts for Helm charts.
Subcharts can be added by creating a file under `packages/${PACKAGE}/generated-changes/dependencies/${SUBCHART}/dependency.yaml`.
The following utility script can be used to create the necessary `dependency.yaml` file in the right location:
```shell
PACKAGE=<packageName>
SUBCHART=<subchartName>
mkdir -p packages/${PACKAGE}/generated-changes/dependencies/${SUBCHART}
touch packages/${PACKAGE}/generated-changes/dependencies/${SUBCHART}/dependency.yaml
```
Once the `dependency.yaml` file has been created, you will need to fill it in. The `dependency.yaml` supports a **subset** of `package.yaml` fields (namely, those associated with `UpstreamOptions`; i.e. you can specify local charts, GitHub Repositories, or Chart Archives). More information on UpstreamOptions can be found in [docs/packages.md](./packages.md).
Once declared, `make prepare` will automatically pull in your dependency under `packages/${PACKAGE}/charts/charts` and add a corresponding entry to the `packages/${PACKAGE}/charts/Chart.yaml` (or `requirement.yaml`, for Helm charts using the older `apiVersion: v1`). You will also be able to patch your dependency from there as if it was part of the original main chart.
*Note: The name of your subchart, and the alias you can use to override settings of your subchart from the main chart, will be dependent on the name of the directory you place the `dependency.yaml` in. For example, if you created your `dependency.yaml` under `packages/mypackage/generated-changes/dependencies/mydep/dependency.yaml` and ran `PACKAGE=mypackage make prepare`, all subchart settings will be located under the main chart's `values.yaml` under `mydep.*` (e.g. `mydep.enabled`), even if the chart `mydep` points to is named something else.*
*Note: A common practice for managing dependencies via these scripts is to keep the actual patches on the dependency in a separate package and refer to it in your main chart. To take this approach, declare your dependency as a separate packages under `packages/${DEPENDENCY}` and simply specify `url: packages/${DEPENDENCY}` in the `dependency.yaml` of your main chart. Then, on a `make prepare`, it will prepare the dependency's package first and pull it in on trying to prepare the main chart. It should also be noted that it is the developer's responsibility to ensure that no cyclical dependencies are introduced in this fashion.*
*Note: if you manage a dependency as a separate package, it's often a good idea to set `doNotRelease: true` on that dependency package's `package.yaml` to indicate that the dependency should not be independently released. This prevents `make charts` from generating assets for the dependency, since it will already be packaged directly into your main chart.*
#### Known Issue: Managed Files
In any Helm chart managed by these scripts, we consider the `Chart.yaml` / `requirements.yaml` to be `Managed Files` since they are the only files that end up going through a three-way merge.
Specifically, the three-way merge occurs because there are three parties involved in applying changes on a `make prepare`:
1. The upstream chart source, which provides the base `Chart.yaml` / `requirements.yaml`
2. The scripts themselves, which make changes to support adding in dependencies based on those specified under `generated-changes/dependencies`.
3. The user, who commits patches to those files after running `make patch`
As a result, on updating dependencies for charts, these files are prone to having conflicts.
The only workaround for this issue is to delete the patch files manually (e.g. `rm packages/${PACKAGE}/generated-changes/patch/Chart.yaml.patch` and/or `rm packages/${PACKAGE}/generated-changes/patch/requirements.yaml.patch`), run `make prepare`, and redo the patches you added to these files manually.
### Making Changes to Released Charts
If a chart version that you want to make changes to has already been released (i.e. the chart already exists in `charts/`, `assets/` and `index.yaml` and the `Package` that was tracking that chart version has moved on to a future version), you will usually follow the following steps:
1. Make the change directly to the `charts/{chart}/{version}` files
2. Run `make zip` to automatically zip up `charts/{chart}/{version}` -> `assets/{chart}-{version}.tgz` and update the `index.yaml`. This might also introduce some changes to `charts/{chart}/{version}`, such as when you add an annotation to `charts/{chart}/{version}/Chart.yaml` that needs to be re-ordered alphabetically.
In addition, if your repository is configured to use upstream validation (e.g. check if `validation.url` and `validation.branch` is specified in the root `configuration.yaml`), you will also need to add this modified chart's name and version to the `release.yaml` or else you will fail CI. If you run `make validate` locally, it will automatically generate this file for you.
For more information on how to do this or why this is required, please see [`docs/validation.md`](docs/validation.md).
Otherwise, you are ready to make a PR!
### Troubleshooting
Open up an issue on [https://github.com/rancher/charts-build-scripts](https://github.com/rancher/charts-build-scripts).
#### Maintainers
- aiyengar2 (arvind.iyengar@suse.com)
- jiaqiluo (jiaqi.luo@suse.com)

38
docs/experimental.md Executable file
View File

@ -0,0 +1,38 @@
## Experimental: Caching
If you specify `export USE_CACHE=1` before running the scripts, a cache will be used that is located at `.charts-build-scripts/.cache`. This cache is only used on `make prepare`, `make patch`, and `make charts`; it is intentionally disabled on `make validate`.
This cache will be used to store references to anything that is pulled into the scripts (e.g. anything defined via `UpstreamOptions`, such as your upstream charts). If used, the speed of the above three commands may dramatically increase since it is no longer relying on making a network call to pull in your charts from the given cached upstream.
However, currently caching is only implemented for `UpstreamOptions` that point to a GitHub Repository at a particular commit, since that is an immutable reference (e.g. any amends to that commit would result in a brand-new commit hash).
If you would like to clean up your cache, either delete the `.charts-build-scripts/.cache` directory or run `make clean-cache`.
## Experimental: Using Manifest Upstreams (Instead of Helm Charts)
If your package.yaml points to an upstream that does not declare a Chart.yaml, the default behavior of the scripts is as follows:
1) Move all YAML files to `templates`
2) Create a dummy, hard-coded `Chart.yaml`:
```yaml
apiVersion: v2
appVersion: 0.1.0
description: A Helm chart for Kubernetes
name: my-helm-chart
type: application
version: 0.1.0
```
This will be applied on the upstream chart before applying `make patch`, which means that the `generated-changes/patch/Chart.yaml.patch` represents changes you introduce on top of this dummy, hard-coded `Chart.yaml`. As a result, you can proceed to make changes such as adding dependencies, adding annotations, etc.
Note: This feature is marked as experimental since it's unclear if there are any additional requirements necessary to support edge cases around pulling upstream manifests. Please open up an issue on [https://github.com/rancher/charts-build-scripts](https://github.com/rancher/charts-build-scripts) if you have any suggestions!
## Experimental: Performing only local or upstream validation
In order to make it easier to debug issues related to a failure in `make validate`, two command-line flags were introduced.
If you would like to perform local validation only (e.g. checking if `make charts` produces no changes), you can run `./bin/charts-build-scripts validate --local`.
If you would like to perform remote validation only (e.g. checking if all differences between your current repository and an upstream repository are tracked in the `release.yaml`), you can run `./bin/charts-build-scripts validate --upstream`.
Note: These options have **not** been exposed as environment variables since an average consumer of the scripts should rarely, if at all, have any reason for using these options.

47
docs/makefile.md Executable file
View File

@ -0,0 +1,47 @@
## Makefile
### Basic Commands
`make pull-scripts`: Pulls in the version of the `charts-build-scripts` indicated in scripts.
### Package Commands
`make prepare`: Pulls in your charts from upstream and creates a basic `generated-changes/` directory with your dependencies from upstream. By default, this prepares every `Package` in your repository but it can be scoped by providing `PACKAGE=<packagePrefix>`, where `packagePrefix` can either be 1) the exact folder in which a `package.yaml` resides in `packages/` or 2) a directory that contains multiple directories with `package.yaml` files; in the latter case, all packages in that prefix will be prepared. *If you are working with a local chart with no dependencies, this command does nothing.*
`make patch`: Updates your `generated-changes/` to reflect the difference between upstream and the current working directory of your branch (note: this command should only be run after `make prepare`). Unlike `make prepare`, `PACKAGE=<packagePrefix>` must point to an exact folder in which a `package.yaml` resides in `packages/`. *If you are working with a local chart with no dependencies, this command does nothing.*
`make clean`: Cleans up all the working directories of charts to get your repository ready for a PR. Supports `PACKAGE=<packagePrefix>` as defined above. *If you are working with a local chart with no dependencies, this command does nothing.*
`make charts`: Runs `make prepare` and then exports your charts to `assets/` and `charts/` and generates or updates your `index.yaml`. Supports `PACKAGE=<packagePrefix>` as defined above.
Please see [`docs/developing.md`](docs/developing.md) for more information on how to use these commands in a normal developer workflow.
### Assets, Chart, and Index Commands
`make index`: Reconstructs the `index.yaml` based on the existing charts. Used by `make charts` and `make validate` under the hood.
`make remove`: Removes the asset and chart associated with a provided chart version. Performs the equivalent of an `rm -rf` on the provided `CHART=<chart>` and `VERSION=<version>` entries and runs `make index`.
`make zip`: Reconstructs archives in the `assets` directory based on the current contents in `charts` and updates the `charts/` contents based on the packaged archive(s). Can be scoped to specific charts via specifying `CHART={chart}` or `CHART={chart}/{version}`. Runs `make index` after reconstruction.
Please see [`docs/developing.md`](docs/developing.md) for more information on how to use these commands to modify released charts.
### CI Commands
`make validate`: Checks whether all generated assets used to serve a Helm repository (`charts/`, `assets/`, and `index.yaml`) are up-to-date. If `validate.url` and `validate.branch` are provided in the configuration.yaml, it will also ensure that any additional changes introduced only modify chart or package versions specified in the `release.yaml`; otherwise it will output the expected `release.yaml` based on assets it detected changes in.
Please see [`docs/validation.md`](docs/validation.md) for more information on how CI is performed.
### Docs and Scripts Commands
`make template`: Updates the current directory by applying the configuration.yaml on [upstream Go templates](https://github.com/rancher/charts-build-scripts/tree/master/templates/template) to pull in the most up-to-date docs, scripts, etc. from [rancher/charts-build-scripts](https://github.com/rancher/charts-build-scripts).
### Advanced and Misc. Commands
`make list`: Prints the list of all packages tracked in the current repository and recognized by the scripts. `export PORCELAIN=1` allows you to specify that the output of this command should be script-friendly.
`make unzip`: Reconstructs all charts in the `charts` directory based on the current contents in `assets`. Can be scoped to specific charts via specifying `ASSET=<asset>` or `ASSET=<asset}>/<chart>-<version>.tgz`. Runs `make index` after reconstruction.
`make standardize`: Takes an arbitrary Helm repository (defined as any repository with a set of Helm charts under `charts/`) and standardizes it to the expected repository structure of these scripts.
`make clean-cache`: Deletes `.charts-build-scripts/.cache`. Only used if `export USE_CACHE=1` is set, which indicates that you are using the experimental caching feature introduced in v0.3.0 of the scripts. Please see [`docs/experimental.md`](docs/experimental.md) for more information.

76
docs/packages.md Executable file
View File

@ -0,0 +1,76 @@
## Packages
### What is a Package?
A Package represents a grouping of one or more Helm Charts. It is declared within `packages/<package>/package.yaml` with the following spec:
```text
version: # The version of the generated chart. This value will override the upstream chart's version. Mutually exclusive with packageVersion
packageVersion: 1 # The value range is from 1 to 99. Mutually exclusive with version
workingDir: # The directory within your package that will contain your working copy of the chart (e.g. charts)
url: # A URL pointing to an UpstreamConfiguration
subdirectory: # Optional field for a specific subdirectory for all upstreams
commit: # Optional field for a specific commit if your URL point to a Github Repository
doNotRelease: # Optional field to specify that this chart should not produce any generated changes on running `make charts`.
additionalCharts:
# These contain other charts that you would like to package alongside this chart
- workingDir: # same as above
upstreamOptions:
# Mutually exclusive with crdOptions
url: # same as above
subdirectory: # optional, same as above
commit: # optional, same as above
crdOptions:
# Mutually exclusive with upstreamOptions
templateDirectory: # A directory within packages/<package>/template that will contain a template for your CRD chart
crdDirectory: # Where to place your CRDs within a CRD chart (e.g. crds for default charts)
addCRDValidationToMainChart: # Whether to add additional validation to your main chart to check that the CRD chart is installed.
```
As seen in the spec above, every Package must have exactly one Chart designated as a main Chart (multiple main Charts are not supported at this time) and all other Charts will be considered AdditionalCharts.
#### UpstreamOptions
Charts or AdditionalCharts can provide UpstreamOptions with the following possible configurations:
- Chart Archive: provide the `url` and optionally `subdirectory`
- Github Repository: provide the `url` (e.g. `https://github.com/rancher/charts-build-scripts.git`) and optionally a `subdirectory` and a `commit`
- Package: provide a `url: packages/<package>` and the main Chart from that package can be pulled. You should ensure that a loop is not introduced.
- Local: provide `url: local` and the package will assume the contents of `workingDir` are exactly the chart you want to use.
#### [AdditionalCharts] CRDOptions
AdditionalCharts can provide CRDOptions instead of UpstreamOptions. These CRDOptions allow the scripts to automatically construct a CRD chart from your main Chart's contents based on the template provided.
A CRD Chart is a Helm Chart whose sole purpose is to install CRDs onto a cluster before the main Chart is installed.
You should not need a CRD chart if your main chart has the following qualities:
1) Your main chart does not install any CRDs.
2) Even if your main chart installs CRDs, it never installs resources of that kind as part of the release. In this case, CRDs can just remain in your `templates/` directory to be managed by Helm.
3) Neither option from above applies to you, but you do not need to facilitate automatically upgrading CRDs or providing a way for a user to cleanly delete CRDs via a second Helm release. In this case, the current Helm feature of having your CRDs placed in the `crds/` directory should work for you.
### Directory Structure
```text
packages/
<package>/
package.yaml # A file that represents your package's overall configuration
generated-changes/
additional-charts/
# Contains one directory per additional chart, keeping track of its dependencies and patches
<additionalChart>/
generated-changes/
# Same as above, but no more additionalCharts
dependencies/
# Contains one directory per dependency.
<dependency>
dependency.yaml # The UpstreamConfiguration of a particular dependency
exclude/
# Files that were excluded from upstream verbatim. Follows the same directory structure as the chart
overlay/
# Files that were overlaid onto upstream verbatim. Follows the same directory structure as the chart
patch/
# Files that were patches from upstream. Follows the same directory structure as the chart and contains Unified Unix Diffs
templates/
# Contains any templates. Currently only used by CRDOptions
```

47
docs/validation.md Executable file
View File

@ -0,0 +1,47 @@
## Repository Validation / CI
In order to provide a way for CI to ensure that the current state of a repository is valid and all necessary commits that produce generated changes have been run by developers, `make validate` runs a series of checks on a clean Git repository.
Specifically, the workflow used by `make validate` does the following:
1. Ensure Git is clean; if not, fail.
2. Run `make charts`; if Git is no longer clean, fail and leave behind the assets.
3. **Only if `validate.url` and `validate.branch` are provided in the `configuration.yaml`**, pull in the specified Git repository, standardize the repository, and check each asset:
- For any assets that exist in upstream, check if it is modified or does not exist in local. If so, copy it over, unzip it, and fail.
- For any assets that exist in local but not in upstream, check if it corresponds to an entry in the `release.yaml`; if not, fail.
4. Run `make unzip`; if Git is no longer clean, fail.
### What is the release.yaml?
The `release.yaml` is only specified if `validate.url` and `validate.branch` are provided in the repository's `configuration.yaml`. It is created automatically if you run `make validate`, which will produce a list of assets that have been modified based on your upstream repository.
When a GitHub repository is provided for this repository to validate against, the scripts ensure that any changes introduced to the current repository make **no additions, modifications, or deletions** to the upstream repository's `charts/`, `assets/`, or `index.yaml`.
**However, if this were the case always, we would not be able add charts or make modifications to existing charts!**
Therefore, to signal to the scripts that you are adding a new chart to upstream, making a modification to an existing chart, or removing a chart, you will need to specify the versions under `${CHART}`.
For example:
```yaml
<chart>:
- <version>
- <version>
- <version>
- ...
rancher-monitoring:
- 100.0.0+up16.6.0
rancher-monitoring-crd:
- 100.0.0+up16.6.0
fleet:
- 100.0.0+up0.3.6
fleet-agent:
- 100.0.0+up0.3.6
fleet-crd:
- 100.0.0+up0.3.6
longhorn:
- 100.0.0+up1.1.2
- 100.0.0+up1.2.0
longhorn-crd:
- 100.0.0+up1.1.2
- 100.0.0+up1.2.0
```

45
scripts/package-ci Executable file
View File

@ -0,0 +1,45 @@
#!/bin/bash
cd $(dirname $0)
cd ..
if [ -n "$(git status --porcelain)" ]; then
echo "Git needs to be clean to run this script"
exit 1
fi
ORIG_PACKAGE=${PACKAGE}
FAILED_PACKAGES=()
for package in $(PORCELAIN=1 make list); do
export PACKAGE="${package#packages\/}"
# Do developer workflow
if ! make prepare > /dev/null 2>&1; then
FAILED_PACKAGES+=("- ${PACKAGE} failed at prepare")
elif ! make patch > /dev/null 2>&1; then
FAILED_PACKAGES+=("- ${PACKAGE} failed at patch")
elif ! make clean > /dev/null 2>&1; then
FAILED_PACKAGES+=("- ${PACKAGE} failed at clean")
elif [ -n "$(git status --porcelain)" ]; then
FAILED_PACKAGES+=("- ${PACKAGE} generated additional changes: $(git status --porcelain | xargs)")
elif ! make charts > /dev/null 2>&1; then
FAILED_PACKAGES+=("- ${PACKAGE} failed at charts")
else
echo "${PACKAGE} passed ci"
fi
git clean -df > /dev/null 2>&1
git checkout -- . > /dev/null 2>&1
done
echo ""
if [ ${#FAILED_PACKAGES[@]} -ne 0 ]; then
echo "Failed to pass ci for the following packages:"
printf '%s\n' "${FAILED_PACKAGES[@]}"
else
echo "All packages pass ci!"
fi
export PACKAGE=${ORIG_PACKAGE}
unset ORIG_PACKAGE

View File

@ -5,19 +5,42 @@ cd $(dirname $0)
source ./version
if ls ../bin/charts-build-scripts 1>/dev/null 2>/dev/null; then
CURRENT_SCRIPT_VERSION=$(../bin/charts-build-scripts --version | cut -d' ' -f3)
if [[ "${CURRENT_SCRIPT_VERSION}" == "${CHARTS_BUILD_SCRIPT_VERSION}" ]]; then
exit 0
fi
fi
echo "Pulling in charts-build-scripts version ${CHARTS_BUILD_SCRIPTS_REPO}@${CHARTS_BUILD_SCRIPT_VERSION}"
rm -rf ../bin
cd ..
rm -rf charts-build-scripts
git clone --depth 1 --branch $CHARTS_BUILD_SCRIPT_VERSION $CHARTS_BUILD_SCRIPTS_REPO 2>/dev/null
mkdir -p bin
ARCH=$(go version | cut -d' ' -f4 | cut -d'/' -f1)
if [[ ${ARCH} == "linux" ]]; then
BINARY_NAME=charts-build-scripts
else
BINARY_NAME=charts-build-scripts-${ARCH}
fi
curl -s -L ${CHARTS_BUILD_SCRIPTS_REPO%.git}/releases/download/${CHARTS_BUILD_SCRIPT_VERSION}/${BINARY_NAME} --output bin/charts-build-scripts
if ! [[ -f bin/charts-build-scripts ]] || [[ $(cat bin/charts-build-scripts) == "Not Found" ]]; then
rm bin/charts-build-scripts;
# Fall back to old process
echo "Building binary locally..."
rm -rf charts-build-scripts
git clone --depth 1 --branch $CHARTS_BUILD_SCRIPT_VERSION $CHARTS_BUILD_SCRIPTS_REPO 2>/dev/null
cd charts-build-scripts
./scripts/build
mv bin ../bin
cd ..
cd charts-build-scripts
VERSION_OVERRIDE=${CHARTS_BUILD_SCRIPT_VERSION} ./scripts/build
mv bin ..
cd ..
rm -rf charts-build-scripts
else
echo "${BINARY_NAME} => ./bin/charts-build-scripts"
fi
rm -rf charts-build-scripts
chmod +x ./bin/charts-build-scripts
./bin/charts-build-scripts --version
./bin/charts-build-scripts --version

View File

@ -1,74 +0,0 @@
#!/bin/bash
set -e
# Note: These scripts are only intended to migrate from the original build scripts to charts-build-scripts v0.1.x
# A separate migration process is required for v0.2.x
cd $(dirname $0)
if [[ -z ${BRANCH} ]]; then
branch=$(git rev-parse --abbrev-ref HEAD)
else
echo "Using branch ${BRANCH}"
branch=${BRANCH}
fi
if [[ -z ${REPOSITORY} ]]; then
echo "Need to provide REPOSITORY as environment variable"
exit 1
fi
cd ..
# Setup
rm -rf ./repository
mkdir -p ./repository
cd repository
# Pull in branch
echo "Pulling in ${REPOSITORY}@${branch}"
git clone --depth 1 --branch ${branch} ${REPOSITORY} . > /dev/null 2>&1
if ! (test -d assets && test -d charts); then
echo "There are no charts or assets in this repository"
cd ..
rm -rf ./repository
exit 1
fi
# Copy assets and charts into the new format
for package_assets in assets/*; do
cp -R ${package_assets} ../assets
package_name=$(basename -- ${package_assets})
for asset in ${package_assets}/*; do
if [[ ${asset} =~ .*\.tgz ]]; then
# Parse structure
asset_name=$(basename -- ${asset%.*})
chart_name=$(echo ${asset_name} | rev | cut -d- -f2- | rev)
chart_name=$(echo ${chart_name} | sed -r 's/-[[:digit:]\.]+$//')
chart_version=${asset_name#${chart_name}-}
# Fix chart version for rc version
# e.g. 0.0.0-rc100 -> 0.0.000-rc1 to keep the drop release candidate version logic simple
if [[ ${chart_version} =~ [0-9]{2}$ ]] && [[ ${chart_version} =~ -rc ]]; then
actual_version=${chart_version%-*}
package_version=${chart_version: -2}
chart_version_without_package_version=${chart_version%${package_version}}
rc_version=${chart_version_without_package_version#${actual_version}}
chart_version=${actual_version}${package_version}${rc_version}
fi
# Dump archives as charts
chart_path=../charts/${package_name}/${chart_name}/${chart_version}
echo "Unarchiving ${asset} to ${chart_path}"
mkdir -p ${chart_path}
tar xvzf ${asset} -C ${chart_path} --strip-components=1 > /dev/null 2>&1
fi
done
done
# Go back
cd ..
helm repo index --merge ./assets/index.yaml --url assets assets
mv ./assets/index.yaml ./index.yaml
rm -rf ./repository

31
scripts/remove-asset Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
set -e
cd $(dirname $0)
cd ..
if [[ -z ${CHART} ]] || [[ -z ${VERSION} ]]; then
echo "Usage: CHART=<chart> VERSION=<version> make remove"
exit 1
fi
if [[ -d charts/${CHART}/${VERSION} ]] && [[ -f assets/${CHART}/${CHART}-${VERSION}.tgz ]]; then
rm -rf charts/${CHART}/${VERSION}
rm -rf assets/${CHART}/${CHART}-${VERSION}.tgz
else
[[ -d charts/${CHART}/${VERSION} ]] || echo "Could not find charts/${CHART}/${VERSION}"
[[ -f assets/${CHART}/${CHART}-${VERSION}.tgz ]] || echo "Could not find assets/${CHART}/${CHART}-${VERSION}.tgz"
echo "No action was taken."
exit 1
fi
# Prune empty directories
set +e
rmdir charts/${CHART} >/dev/null 2>&1
rmdir charts >/dev/null 2>&1
rmdir assets/${CHART} >/dev/null 2>&1
rmdir assets >/dev/null 2>&1
set -e
make index

View File

@ -2,4 +2,4 @@
set -e
CHARTS_BUILD_SCRIPTS_REPO=https://github.com/rancher/charts-build-scripts.git
CHARTS_BUILD_SCRIPT_VERSION=v0.2.0
CHARTS_BUILD_SCRIPT_VERSION=v0.3.1