Package and Publish a Release
Two scripts drive a release of apache/skywalking-helm. They are the procedure; this page explains
what they do and what is left for a human.
| Script | Covers |
|---|---|
tools/releasing/release.sh |
everything up to and including the call for vote — build, verify, tag, upload to svn, print the vote mail |
tools/releasing/release-passed.sh |
everything after the vote passes — promote the artifacts, create the GitHub release, print the ANNOUNCE mail |
release.sh reads the version out of chart/skywalking/Chart.yaml; release-passed.sh takes it as
its first argument. Both accept --dry-run. Both call the Makefile, whose per-target detail is in
Makefile reference at the end — reference, not procedure.
What gets released
Two artifacts are signed, uploaded and voted on — the source tarball and the packaged chart.
That is settled by precedent: every version under
dist/release/skywalking/helm/
carries six files.
| Where | Artifact | For chart 5.0.0 |
|---|---|---|
| dist.apache.org | source tarball, .asc, .sha512 |
skywalking-helm-5.0.0-src.tgz |
| dist.apache.org | packaged chart, .asc, .sha512 |
skywalking-helm-5.0.0.tgz |
| Docker Hub (OCI) | the chart users install — a convenience binary, pushed after the vote | oci://registry-1.docker.io/apache/skywalking-helm:5.0.0 |
| ghcr.io (OCI) | 0.0.0-<sha> snapshot of every master commit — not a release |
oci://ghcr.io/apache/skywalking-helm/skywalking-helm:0.0.0-<sha> |
The dist path for this project is skywalking/helm/. The skywalking/kubernetes/ directory on dist
is a leftover from the repository’s old name (skywalking-kubernetes) and still holds 4.7.0;
nothing new goes there.
The Git tag is v$VERSION (v5.0.0). Every other coordinate is the plain $VERSION (5.0.0).
VERSION and CHART_NAME are read out of chart/skywalking/Chart.yaml by the Makefile and are
never passed as arguments — see The version is read, never passed.
1. Prepare
Everything here lands in one “Ready to release $VERSION” PR against master. Do not push to
master directly — that is the project’s rule, not something the tooling stops you doing. The
.asf.yaml ruleset on the default branch restricts deletion and force-push only, so a direct push
would succeed.
Milestones
Issues are disabled on this repository, so a release spans two milestones:
apache/skywalking-helmmilestones — the PRs of this release (5.0.0).apache/skywalkingmilestones — the user-facing issues, filed there underHelm - $VERSION.
Close everything finished in both; move the rest to the next milestone, creating it if needed.
Changelog
docs/changes/changes.md must have a finished section for $VERSION,
headed ## $VERSION, covering breaking changes, features and fixes. This is what the vote mail and
the ANNOUNCE mail link to.
Version bump
# chart/skywalking/Chart.yaml
version: 5.0.0
Then sweep the prose. The chart version is quoted in helm install examples across nearly the whole
docs tree — at 5.0.0 that is 19 files under README.md and docs/, not a handful. Do not work
from a remembered list; let grep produce it:
grep -rln '4\.9\.0' README.md docs/ # the version you are leaving behind
grep -rn -- '--version' README.md docs/ | grep -v '4\.9\.0\|5\.0\.0' # stragglers on other pins
Neither comes back empty, so read the hits rather than counting them. The first keeps the deliberate
historical references — Upgrading documents the 4.9.0 → 5.0.0 bump,
Where to Get the Chart records that 4.9.0 never reached Docker Hub,
and this page cites the dist layout.
The second command is there because not every occurrence is literal: docs/install/quick-start.md
passes the chart version through a SKYWALKING_RELEASE_VERSION shell variable, and
docs/install/chart-sources.md also carries --version for the subchart pins (3.3.1 and
friends), which must not be bumped along with the chart. Image tags quoted in the docs
(oap.image.tag, ui.image.tag, banyandb.image.tag) must match
Version Compatibility — which itself carries the chart
version in its own install example, so it is part of the sweep, not the reference standing outside
it.
Dependency versions
Every dependency version has to resolve before you can build. BanyanDB Helm is released by
apache/skywalking-banyandb-helm and pushed
to the same Docker Hub OCI namespace, so ask the registry:
helm show chart oci://registry-1.docker.io/apache/skywalking-banyandb-helm --version 0.7.0
An Error: ... not found means it is not published there. Cross-check the source release exists too:
https://dist.apache.org/repos/dist/release/skywalking/banyandb-helm/.
Audit every dependency before tagging:
grep '^ version:' chart/skywalking/Chart.yaml
The dependency versions are the indented version: lines; the chart’s own version: starts at
column 0. Do not anchor the search to the - name: line above it — two entries carry an alias: in
between, including the BanyanDB one.
Checklist before running the scripts
version:inchart/skywalking/Chart.yamlbumped, and the docs sweep done.dependencies:inchart/skywalking/Chart.yamlall resolve.docs/changes/changes.mdhas a finished## $VERSIONsection.- E2E tests green on the release commit.
- Both milestones tidy.
- The “Ready to release $VERSION” PR merged.
2. Add your GPG public key to Apache svn
- Log in to id.apache.org and submit your key fingerprint.
- Append your GPG public key to the SkyWalking KEYS file — PMC members only; ask a PMC member otherwise. Do not overwrite the existing content, append at the end.
The build signs with gpg --batch --yes, which will not prompt: the release key must be the default
secret key in your keyring, with its passphrase available through the agent.
gpg --list-secret-keys --keyid-format=long
3. Build, verify, tag, upload and call the vote — release.sh
Run it from your own checkout. Linux and macOS both work — the build was verified end to end on each.
bash tools/releasing/release.sh --dry-run # everything except the four writes
bash tools/releasing/release.sh
You do not need a clean tree, because the script does not build from your tree. It clones
apache/skywalking-helm fresh into tools/releasing/skywalking-helm/ and does everything there.
That is not tidiness: make release-src archives the working tree, not HEAD, so releasing from
a working copy ships whatever untracked files happen to be sitting in it — editor state, an agent
directory, a half-finished values file. Cloning removes the question. Your checkout is only read,
for the default version.
Note that ignoring such a directory does not protect you — tar does not read .gitignore, so
a gitignored directory is silently archived. That is why the clone is excluded in the Makefile and
verify_artifacts inspects the finished tarball.
It asks for both versions before doing anything, defaulting from your checkout’s Chart.yaml:
=== Versions ===
release version: 5.1.0 (from your checkout's chart/skywalking/Chart.yaml)
next dev version: 5.2.0
Are these correct? [y/N]
Answer anything but y to type them in. Both must be plain MAJOR.MINOR.PATCH — they end up in a
git tag, an svn path and a branch name, and refusing anything else keeps shell metacharacters out of
all three.
--dry-run still clones, builds, signs and verifies, and still runs the svn checkout and the
next-version commit. It skips exactly four things: the tag push, the svn commit, the branch push and
the PR.
The order matters
| Stage | What it does |
|---|---|
resolve_versions |
asks for the release and next-dev versions, defaulting from your Chart.yaml |
preflight |
refuses to start (see below) |
clone_repo |
fresh clone into tools/releasing/skywalking-helm/; everything below runs there |
build |
make clean then make release — six files in the clone |
verify_artifacts |
signature, checksum, a real render, and an inspection of the source tarball |
tag |
git tag -a v$VERSION and git push origin v$VERSION |
upload_to_svn |
sparse checkout of dist/dev/skywalking, then svn add + svn commit |
prepare_next_version |
rotates the changelog, bumps the chart, opens the next-version PR |
vote_mail |
prints the mail, with the real checksums and commit hash filled in |
clone_repo also refuses to continue unless master’s Chart.yaml already says the release version.
This project tags master as it stands, so if the version is not already there then master is not
ready — and setting it inside the clone would tag a commit that exists nowhere else.
The tag is pushed after the build and the artifact checks, deliberately. A tag pushed first
survives a failed build, and preflight then refuses to re-run because v$VERSION exists — so the
irreversible step comes last, and a failure leaves nothing on the remote to clean up.
Preflight refuses to start when:
- any of
helm,gpg,shasum,svn,git,make,tar,awkis missing. All of them are reported in one message — finding them one at a time costs one failed run per package; helmis older than 3.8. The chart ships only as an OCI artifact, andhelm pushto anoci://registry arrived in 3.8. Helm 4 is accepted:Chart.yamlisapiVersion: v2, which both majors read;gpgholds no secret key.make releasesigns withgpg --batch, so without one the run would fail after building and packaging everything;ghis not authenticated. It opens the next-version PR at the very end, so an unauthenticatedghwould otherwise surface only after the vote candidate is already staged;dist/dev/skywalkingcannot be read — a network problem, or svn credentials that are not set up;v$VERSIONalready exists on the remote, ordist/dev/skywalking/helm/$VERSIONalready does. The second catches a re-run after a partial upload, which would otherwise only surface atsvn commit— after the build, the signing and the tag push.
The point of the capability checks is when they fail. A missing signing key or unusable svn credentials are both perfectly capable of stopping a release half-way through, with a tag already on the remote; preflight is the only place where stopping is free.
verify_artifacts checks, for each of the two artifacts, that the file and its .asc and .sha512
are present, that gpg --batch --verify passes and that shasum -a 512 -c passes. It then runs
helm template over the packaged chart and requires at least one rendered kind: — a chart that
lints but renders nothing is a valid chart. That render uses oap.storageType=elasticsearch with
elasticsearch.enabled left at its default true, so it exercises the ECK path. Finally it lists
the source tarball and fails if it contains the build clone, a .tgz, a charts/ directory or a
Chart.lock.
The next-version PR
prepare_next_version runs after the candidate is staged, on a bump-to-$NEXT branch of the clone:
chart/skywalking/Chart.yamlmoves to the next dev version — withsed, notyq, becauseyqrewrites the whole document and turns a one-line bump into a fifty-line reindent;docs/changes/changes.mdbecomesdocs/changes/changes-$VERSION.md, and a fresh changelog is rendered fromdocs/changes/changes.tpl;docs/menu.ymlgains the released version, inserted directly afterCurrent Versionso the in-progress changelog keeps the top of the menu and released versions stay newest-first.
Merge it once the vote thread is open. It cannot affect the artifacts under vote — those were built from the tag, before this branch existed.
Send the vote mail
The script prints the mail and stops; it sends nothing. Copy it, check the checksums and the commit
hash it filled in, and send it to dev@skywalking.apache.org from your Apache address. Confirm the
six files are visible at https://dist.apache.org/repos/dist/dev/skywalking/helm/$VERSION/ first.
Voting stays open for at least 72 hours.
4. Vote check
What a voter runs. Everything happens in a scratch directory, from the staged URL, never from the release manager’s working copy.
export VERSION=5.0.0
curl -O "https://dist.apache.org/repos/dist/dev/skywalking/helm/$VERSION/skywalking-helm-$VERSION-src.tgz{,.asc,.sha512}"
curl -O "https://dist.apache.org/repos/dist/dev/skywalking/helm/$VERSION/skywalking-helm-$VERSION.tgz{,.asc,.sha512}"
-
Both artifacts are present, each with
.ascand.sha512— six files. -
Signatures.
curl https://downloads.apache.org/skywalking/KEYS -o KEYS && gpg --import KEYS gpg --batch --verify skywalking-helm-$VERSION-src.tgz.asc skywalking-helm-$VERSION-src.tgz gpg --batch --verify skywalking-helm-$VERSION.tgz.asc skywalking-helm-$VERSION.tgz -
Checksums.
shasum -a 512 -c skywalking-helm-$VERSION-src.tgz.sha512 shasum -a 512 -c skywalking-helm-$VERSION.tgz.sha512 -
LICENSEandNOTICEare inside both tarballs — the chart tarball gets them frommake prepare, which copies them in from the repository root just before packaging.tar tzf skywalking-helm-$VERSION-src.tgz | grep -E '\./(LICENSE|NOTICE)$' tar tzf skywalking-helm-$VERSION.tgz | grep -E 'skywalking-helm/(LICENSE|NOTICE)$' -
Build from source. Extract the source tarball and package it; this needs network access, because
helm dep upfetches the subcharts.mkdir src && tar xzf skywalking-helm-$VERSION-src.tgz -C src ( cd src && make package ) # keep the build in a subshell — see belowDo not expect the resulting
.tgzto checksum-match the voted one —helm packagerecords file timestamps. Compare the file listing and the rendered output instead.Stay out of
src/for the steps below.make packagewrites its ownskywalking-helm-$VERSION.tgzintosrc/, with exactly the name of the artifact you downloaded. If youcd srcand stay there, steps 6 and 7 silently inspect your local rebuild instead of the artifact under vote — and a rebuild passes even when the staged tarball is wrong. Run them from the scratch directory, where the downloaded file is. -
The chart renders — both storage paths.
helm lintandhelm templateboth succeed on a chart that renders nothing, so look at the output, not the exit code. This chart has three required values, and no default backend:oap.storageTypeisnullinvalues.yaml.BanyanDB is opt-in, and turning it on means turning Elasticsearch off:
helm template sw skywalking-helm-$VERSION.tgz \ --set oap.image.tag=11.0.0 \ --set oap.storageType=banyandb \ --set ui.image.tag=horizon-1.0.0 \ --set elasticsearch.enabled=false \ --set banyandb.enabled=true \ --set banyandb.image.tag=0.11.0 > render-banyandb.yaml grep -c '^kind:' render-banyandb.yaml # non-zero; 15 for 5.0.0 grep -q '^kind: Deployment$' render-banyandb.yamlElasticsearch is the default, and that is the render most users get.
elasticsearch.enabledistrueinvalues.yaml, so do not carry--set elasticsearch.enabled=falseover from the first command — with it you get the first render minus BanyanDB (11 resources at5.0.0) and no ECK resource whatsoever, which is what the storage-type flag alone buys you:helm template sw skywalking-helm-$VERSION.tgz \ --set oap.image.tag=11.0.0 \ --set oap.storageType=elasticsearch \ --set ui.image.tag=horizon-1.0.0 > render-es.yaml grep -c '^kind:' render-es.yaml # non-zero; 34 for 5.0.0 grep -q '^kind: Elasticsearch$' render-es.yaml # the ECK cluster CR grep -q 'charts/eck-operator/templates/statefulset.yaml' render-es.yaml grep -q 'sw-elasticsearch-es-http:9200' render-es.yaml # OAP wired to the ECK serviceThe
^kind: Elasticsearch$anchor matters:kind: Elasticsearchalso appears indented inside the operator’s CRD schemas, so an unanchored grep passes on a render that contains no cluster. The three greps together are what “exercises ECK” means — the operator subchart, theElasticsearchresource it reconciles, and the OAP deployment pointing at the-es-httpservice that ECK creates for it. -
The chart is stamped with the release version. The subcharts are vendored into the tarball, so their versions are readable without a registry:
tar xzOf skywalking-helm-$VERSION.tgz skywalking-helm/Chart.yaml | grep -E '^version:' tar tzf skywalking-helm-$VERSION.tgz | grep -E '^skywalking-helm/charts/[^/]+/Chart.yaml$' tar xzOf skywalking-helm-$VERSION.tgz skywalking-helm/Chart.yaml | grep -E '^ version:'version:must be$VERSION. The third command prints the dependency versions actually baked into the package — four entries at5.0.0, one per vendored subchart the second command lists. Note thathelm packagere-serializesChart.yaml: keys come out alphabetized and the Apache header is gone from that one file inside the chart tarball. That is helm’s doing and is not a defect; the license-header check belongs to the source tarball. -
License headers across the source tarball (license-eye), and a functional smoke test if you have a cluster handy — Quick Start.
The chart on Docker Hub is not part of the vote. It does not exist yet at this point.
Vote result rules:
-
PMC votes are +1 binding, everyone else +1 non-binding.
-
Vote passes with at least 3 binding +1 and more +1 than -1, within 72 hours.
-
Send the closing mail, listing the voters by name.
[RESULT][VOTE] Release Apache SkyWalking Helm version $VERSION 3 days passed, we've got ($NUMBER) +1 bindings: xxx xxx xxx ... (list names) I'll continue the release process.
5. Publish — release-passed.sh
PMC members only. Run it once the vote thread has three binding +1 and no -1.
bash tools/releasing/release-passed.sh 5.0.0 --dry-run
bash tools/releasing/release-passed.sh 5.0.0
The version is the argument here — this script never reads Chart.yaml, so it can publish a
release from a checkout that has already moved on.
Every step is irreversible on shared infrastructure, so each asks first, and declining aborts the
run — with the one exception marked below. That is deliberate: the steps are ordered and
dependent, and saying no to the svn promotion and then carrying on would create a GitHub release,
and publish the chart, for artifacts still sitting in the dev area. --dry-run takes every prompt
as a no without aborting, so it walks the whole plan and does none of it.
| Stage | Prompt | Declining |
|---|---|---|
resolve_version |
confirm the version to publish | — |
preflight |
— | fails if svn / gh / git are missing, if gh is not authenticated, if dist/release/skywalking cannot be read, or if dist/dev/skywalking/helm/$VERSION does not exist |
promote_artifacts |
svn mv from dist/dev to dist/release |
aborts |
remove_previous |
remove everything under release/helm/ other than $VERSION |
skips and continues — the one exception |
github_release |
gh release create — this is what publishes the chart |
aborts |
announce_mail |
— | prints the mail, sends nothing |
remaining |
— | prints what is left by hand |
gh auth status is checked in preflight rather than left to github_release, because
github_release runs after promote_artifacts — and an svn mv into dist/release cannot be
taken back. An unauthenticated gh has to stop the run before that, or not at all.
remove_previous is the exception because skipping it is survivable: dist/release is meant to
hold only the current version, but a stale sibling breaks nothing. Declining prints
remove them by hand before announcing, and the run continues. It lists what is there and asks
rather than guessing a pattern, because that directory is not uniformly laid out — today 4.9.0 is
a version directory while 4.8.0 sits as six loose files at the top level of helm/.
Old releases stay available from archive.apache.org; nothing extra to do for that. Wait for the mirrors before announcing:
curl -sI "https://downloads.apache.org/skywalking/helm/$VERSION/skywalking-helm-$VERSION-src.tgz" | head -1
The GitHub release is what publishes the chart
.github/workflows/publish-helm.yaml listens for release: types: [released], so
github_release is the step that puts the chart on Docker Hub; make publish is the
manual fallback only. The script runs:
gh release create "v$VERSION" --repo apache/skywalking-helm --verify-tag \
--title "$VERSION" --notes "See .../blob/v$VERSION/docs/changes/changes.md"
--verify-tag is load-bearing: without it gh creates a missing tag from the default branch
head, which is not necessarily the commit the PMC voted on. The release is a full release, never a
draft or pre-release — the released event fires when a release is published as a full release (or
when an existing pre-release is converted into one), and never for drafts. If the release already
exists the script says so and moves on.
Before it pushes anything the workflow runs three hard guards, under a repository guard
(github.repository == 'apache/skywalking-helm', so forks never publish):
| Check | Trips when | Effect |
|---|---|---|
| Tag shape | the release tag is not vMAJOR.MINOR.PATCH |
Fails the job. The tag is attacker-influenceable text that reaches a shell; only one shape is ever released. |
| Credentials | DOCKERHUB_USER / DOCKERHUB_TOKEN are not available to the repository |
Fails the job. They are ASF org secrets; failing early beats an opaque unauthorized from the registry. |
| Version matches the tag | version: in chart/skywalking/Chart.yaml ≠ the tag minus its leading v |
Fails the job. Publishing 5.0.0 from a v5.1.0 tag would be silent and unfixable once the tag is immutable. |
It packages with make package (not bare helm package, so NOTICE and LICENSE are in the
chart), re-checks that both files are inside the tarball, and pushes to
oci://registry-1.docker.io/apache, where helm push appends the chart name — landing at
apache/skywalking-helm:$VERSION.
Watch it and verify the result — this is not ceremony. Docker Hub currently holds
apache/skywalking-helm tags 4.3.0 through 4.8.0 only: 4.9.0 was released but never reached
the registry, which is the gap this workflow exists to close. Confirm yours landed:
gh run list --workflow publish-helm.yaml --repo apache/skywalking-helm --limit 3
helm show chart oci://registry-1.docker.io/apache/skywalking-helm --version "$VERSION"
A FetchReference ... not found means the chart is not there, whatever the workflow’s exit status
said.
Pushes to master keep doing what they always did — a 0.0.0-<sha> snapshot to
oci://ghcr.io/apache/skywalking-helm/skywalking-helm, documented in
Where to Get the Chart.
What the script leaves for you
It prints this list at the end; the detail is here.
- Website, in apache/skywalking-website:
data/releases.yml— under SkyWalking Kubernetes Helm, replace the version block with$VERSION: thesrclink throughhttps://www.apache.org/dyn/closer.cgi/skywalking/helm/$VERSION/…and theasc/sha512links throughhttps://downloads.apache.org/skywalking/helm/$VERSION/…. Set the release date.data/docs.yml— the Kubernetes Helm entry. It still points at tags of the oldskywalking-kubernetesrepository; once the docs published fromdocs/menu.ymlare wired into the site, add a version entry the wayskywalking-swckdoes it —version: v$VERSION,link: /docs/skywalking-helm/v$VERSION/readme/,commitId: <tag sha>— and updateLatest.
- The ANNOUNCE mail the script printed, to
dev@skywalking.apache.organdannounce@apache.org, from your Apache address, with the vote thread permalink filled in from lists.apache.org. - Milestones — close
$VERSIONhere andHelm - $VERSIONonapache/skywalking, and open the next pair. - The next development version — bump
version:inchart/skywalking/Chart.yaml.
make publish — the manual fallback
publish: package
helm push ${CHART_NAME}-${VERSION}.tgz oci://registry-1.docker.io/apache
It re-packages from your working tree and pushes to Docker Hub. Reach for it only when Actions is
unavailable or the release workflow is broken — the GitHub release created by release-passed.sh is
the normal path.
It has none of the workflow’s guards:
- It does not check the chart version against any tag; it publishes whatever
Chart.yamlsays. - It does not check credentials first; you get the registry’s
unauthorizedinstead. - It builds from your working copy, not from the tag — uncommitted local edits get published, and nothing ties the pushed chart to the voted artifact.
If you must use it: helm registry login registry-1.docker.io first (write access to the apache
Docker Hub organization is required), run it from a pristine checkout of v$VERSION, and only after
the vote has passed and the artifacts have moved to dist/release. Verify with
helm show chart oci://registry-1.docker.io/apache/skywalking-helm --version $VERSION.
Makefile reference
The scripts in 3 and 5 call these targets. Nothing below is a step to run by hand during a release.
The version is read, never passed
CHART_DIR = chart/skywalking
VERSION = $(shell cat ${CHART_DIR}/Chart.yaml | grep '^version: ' | awk '{print $$2}')
CHART_NAME = $(shell cat ${CHART_DIR}/Chart.yaml | grep '^name: ' | awk '{print $$2}')
RELEASE_SRC = ${CHART_NAME}-${VERSION}-src
make release VERSION=… does not do what it looks like: a command-line assignment overrides the make
variable but not the file helm package writes — that name comes from Chart.yaml — so the
chart-package signing step and publish go looking for a tarball that does not exist (the source
tarball is built under the overridden name, so only the chart half breaks). Bumping a release means
editing the version: line in chart/skywalking/Chart.yaml and committing it. CHART_NAME comes
from the chart’s name: field (skywalking-helm), not from the directory name (skywalking), so at
chart version 5.0.0 the artifacts are skywalking-helm-5.0.0.tgz and
skywalking-helm-5.0.0-src.tgz.
chart/skywalking is the only chart in this repository, and CHART_DIR has only ever pointed at it,
so a release packages, signs and publishes exactly one chart.
TMPDIR defaults to /tmp and is the only variable declared with ?=, i.e. the only one meant to be
overridden (make release TMPDIR=/var/tmp). The recipe shell is /bin/bash -eo pipefail.
Targets at a glance
| Target | Depends on | Produces |
|---|---|---|
prepare |
— | NOTICE + LICENSE copied into chart/skywalking/ |
package |
prepare |
skywalking-helm-<version>.tgz |
clean |
— | nothing; deletes artifacts and resolved dependencies |
release-src |
clean |
skywalking-helm-<version>-src.tgz |
release |
release-src, package |
both tarballs, each with .asc and .sha512 |
publish |
package |
the chart pushed to Docker Hub as an OCI artifact |
Do not use make -j: release-src starts by wiping the tree that package writes into.
prepare — the NOTICE/LICENSE copy dance
prepare:
cp -R NOTICE ${CHART_DIR}/NOTICE
cp -R LICENSE ${CHART_DIR}/LICENSE
NOTICE and LICENSE live at the repository root, but an Apache release artifact has to carry them
inside the distributed tarball. helm package only picks up files under the chart directory, so
they are copied in immediately before packaging and deleted immediately after — the working tree
never keeps a second copy, and neither file is tracked under chart/skywalking/.
If a make package run dies partway through, those two copies are left behind. make clean removes
them.
package
package: prepare
helm dep up ${CHART_DIR}
helm package ${CHART_DIR}
rm -rf ${CHART_DIR}/NOTICE
rm -rf ${CHART_DIR}/LICENSE
helm dep up resolves every entry in the dependencies: block of Chart.yaml — eck-operator,
eck-elasticsearch, postgresql, skywalking-banyandb-helm — downloading each into
chart/skywalking/charts/ and writing chart/skywalking/Chart.lock. Both are gitignored. helm package then rolls the chart directory, its vendored subcharts, and the just-copied NOTICE and
LICENSE into skywalking-helm-<version>.tgz in the repository root, and the two copies are removed.
The subcharts are baked into the package. Whatever helm dep up resolved at package time is what
users get.
clean
Deletes, in one rm invocation:
$(TMPDIR)/skywalking-helm-<version>-src.tgzbin/chart/skywalking/NOTICE,chart/skywalking/LICENSEchart/skywalking/Chart.lock,chart/skywalking/charts/skywalking-helm-<version>.tgzand its.asc/.sha512skywalking-helm-<version>-src.tgzand its.asc/.sha512
One rm -rf with one list of operands. It used to repeat rm -rf on each backslash-continued line,
which — there being no && between them — left those tokens sitting in the argument list of a single
rm whose only flag was -f. GNU rm permutes arguments, so on Linux the trailing -rf still
applied and -f swallowed the stray rm operands, and the target did what it read like. BSD rm —
macOS — stops option parsing at the first operand, so -r never took effect: it failed with
rm: bin/: is a directory, left bin/ and chart/skywalking/charts/ behind, and exited 1, which
aborted make clean, make release-src and make release. The recipe is one rm -rf again and
survives BSD rm. release.sh carried a Linux-only guard for as long as that recipe was broken;
with the recipe fixed the guard was obsolete, and it has been removed.
If you touch it, keep it a single rm -rf and re-read the whole thing rather than one line.
Because clean wipes charts/ and Chart.lock, the next package re-resolves dependencies from
scratch.
release-src
release-src: clean
tar -zcvf $(TMPDIR)/$(RELEASE_SRC).tgz \
--exclude bin --exclude .git --exclude .idea \
--exclude .gitignore --exclude .DS_Store --exclude .github \
. && \
mv $(TMPDIR)/$(RELEASE_SRC).tgz .
It archives the whole working directory — hence the clean prerequisite, which removes charts/,
Chart.lock and this version’s .tgz files before the tar runs. The tar is built in $(TMPDIR) and
only then moved into the repository root, so the archive never contains itself.
clean only knows the current $(VERSION): it deletes skywalking-helm-5.0.0*.tgz*, not
skywalking-helm-4.9.0.tgz. A tarball left over from a previous release is not excluded by the tar
either (the exclude list has no *.tgz), so it would ship as a binary inside the ASF source
release. release.sh preflight refuses to start when one is present, which is the check that catches
this.
tar . takes the working tree, not HEAD — which is why preflight also refuses a dirty tree. Run
from a pristine checkout of the release commit: any untracked scratch file that is not in the exclude
list ships inside the ASF source release.
release
release: release-src package
gpg --batch --yes --armor --detach-sig $(RELEASE_SRC).tgz
shasum -a 512 $(RELEASE_SRC).tgz > $(RELEASE_SRC).tgz.sha512
gpg --batch --yes --armor --detach-sig $(CHART_NAME)-$(VERSION).tgz
shasum -a 512 $(CHART_NAME)-$(VERSION).tgz > $(CHART_NAME)-$(VERSION).tgz.sha512
The full sequence, in order: clean → release-src → prepare → package → sign and checksum.
Both artifacts are signed and checksummed, leaving six files in the repository root:
skywalking-helm-5.0.0-src.tgz
skywalking-helm-5.0.0-src.tgz.asc
skywalking-helm-5.0.0-src.tgz.sha512
skywalking-helm-5.0.0.tgz
skywalking-helm-5.0.0.tgz.asc
skywalking-helm-5.0.0.tgz.sha512
Signing is armored and detached, and --batch --yes means GPG will not prompt.