diff --git a/build/azure-pipelines.release.yml b/build/azure-pipelines.release.yml
index bc275f42b..7118d2151 100644
--- a/build/azure-pipelines.release.yml
+++ b/build/azure-pipelines.release.yml
@@ -1,7 +1,12 @@
trigger:
- branches:
+ tags:
include:
- - refs/tags/v*
+ - "v*"
+ exclude:
+ # We tag a release for canary-v1 or latest-v1 because of how we host our binaries with GitHub releases.
+ # Do not trigger another release when we create these tags during the release process, preventing an infinite recursion of release builds.
+ - "latest*"
+ - "canary*"
# Do not run on pull requests
pr: none
diff --git a/docs/content/project/version-strategy/index.md b/docs/content/project/version-strategy/index.md
index 2711823e8..0d6b160d7 100644
--- a/docs/content/project/version-strategy/index.md
+++ b/docs/content/project/version-strategy/index.md
@@ -38,6 +38,6 @@ Porter v1 will include a number of breaking changes that we are grouping togethe
The final release from the v1 branch will be v1.0.0.
* The release/v1 branch will be merged into main, and then the v1.0.0 release is cut.
* The latest and canary builds continue to be based on builds of the main branch only.
- We may provide v1-latest and v1-canary builds at a later date.
+ We may provide latest-v1 and canary-v1 builds at a later date.
[semver v2]: https://semver.org/spec/v2.0.0.html
diff --git a/mage/git.go b/mage/git.go
index b8115ac58..e92644c2c 100644
--- a/mage/git.go
+++ b/mage/git.go
@@ -31,6 +31,11 @@ type GitMetadata struct {
IsTaggedRelease bool
}
+func (m GitMetadata) ShouldPublishPermalink() bool {
+ // For now don't publish canary-v1 or latest-v1 to keep things simpler
+ return m.Permalink == "canary" || m.Permalink == "latest"
+}
+
// LoadMetadata populates the status of the current working copy: current version, tag and permalink
func LoadMetadata() GitMetadata {
loadMetadata.Do(func() {
@@ -96,21 +101,21 @@ func getBranchName() string {
func getPermalink() (string, bool) {
// Use latest for tagged commits
taggedRelease := false
- permalinkSuffix := "canary"
+ permalinkPrefix := "canary"
err := shx.RunS("git", "describe", "--tags", "--match=v*", "--exact")
if err == nil {
- permalinkSuffix = "latest"
+ permalinkPrefix = "latest"
taggedRelease = true
}
// Get the current branch name, or the name of the branch we tagged from
branch := getBranchName()
- // Build a permalink such as "canary", "latest", "v1-latest", etc
+ // Build a permalink such as "canary", "latest", "latest-v1", or "canary-v1"
switch branch {
case "main":
- return permalinkSuffix, taggedRelease
+ return permalinkPrefix, taggedRelease
default:
- return fmt.Sprintf("%s-%s", strings.TrimPrefix(branch, "release/"), permalinkSuffix), taggedRelease
+ return fmt.Sprintf("%s-%s", permalinkPrefix, strings.TrimPrefix(branch, "release/")), taggedRelease
}
}
diff --git a/mage/releases/publish.go b/mage/releases/publish.go
index 170843ec3..2afedd4b3 100644
--- a/mage/releases/publish.go
+++ b/mage/releases/publish.go
@@ -6,6 +6,7 @@ import (
"log"
"os"
"path/filepath"
+ "strings"
"get.porter.sh/porter/mage"
"get.porter.sh/porter/mage/tools"
@@ -95,15 +96,19 @@ func publishPackage(pkgType string, name string) {
remote := fmt.Sprintf("https://%s.git", repo)
versionDir := filepath.Join("bin", pkgType+"s", name, info.Version)
- // Move the permalink tag. The existing release automatically points to the tag.
- must.RunV("git", "tag", info.Permalink, info.Version+"^{}", "-f")
- must.RunV("git", "push", "-f", remote, info.Permalink)
-
// Create or update GitHub release for the permalink (canary/latest) with the version's binaries
- AddFilesToRelease(repo, info.Permalink, versionDir)
+ if info.ShouldPublishPermalink() {
+ // Move the permalink tag. The existing release automatically points to the tag.
+ must.RunV("git", "tag", info.Permalink, info.Version+"^{}", "-f")
+ must.RunV("git", "push", "-f", remote, info.Permalink)
+
+ AddFilesToRelease(repo, info.Permalink, versionDir)
+ } else {
+ fmt.Println("Skipping publish package for permalink", info.Permalink)
+ }
+ // Create GitHub release for the exact version (v1.2.3) and attach assets
if info.IsTaggedRelease {
- // Create GitHub release for the exact version (v1.2.3) and attach assets
AddFilesToRelease(repo, info.Version, versionDir)
}
}
@@ -116,12 +121,16 @@ func PublishMixin(mixin string) {
// Publish a plugin's binaries.
func PublishPlugin(plugin string) {
publishPackage("plugin", plugin)
-
}
func publishPackageFeed(pkgType string, name string) {
info := mage.LoadMetadata()
+ if !info.ShouldPublishPermalink() {
+ fmt.Println("Skipping publish package feed for permalink", info.Permalink)
+ return
+ }
+
// Clone the packages repository
if _, err := os.Stat(packagesRepo); !os.IsNotExist(err) {
os.RemoveAll(packagesRepo)
@@ -168,20 +177,20 @@ func GeneratePluginFeed() {
// AddFilesToRelease uploads the files in the specified directory to a GitHub release.
// If the release does not exist already, it will be created with empty release notes.
-func AddFilesToRelease(repo string, version string, dir string) {
+func AddFilesToRelease(repo string, tag string, dir string) {
files := listFiles(dir)
// Mark canary releases as a draft
draft := ""
- if version == "canary" {
+ if strings.HasPrefix(tag, "canary") {
draft = "-p"
}
- if releaseExists(repo, version) {
- must.Command("gh", "release", "upload", "--clobber", "-R", repo, version).
+ if releaseExists(repo, tag) {
+ must.Command("gh", "release", "upload", "--clobber", "-R", repo, tag).
Args(files...).RunV()
} else {
- must.Command("gh", "release", "create", "-R", repo, "-t", version, "--notes=", draft, version).
+ must.Command("gh", "release", "create", "-R", repo, "-t", tag, "--notes=", draft, tag).
CollapseArgs().Args(files...).RunV()
}
}
diff --git a/magefile.go b/magefile.go
index e2d23e8e1..5ed0d1d52 100644
--- a/magefile.go
+++ b/magefile.go
@@ -148,24 +148,86 @@ func getDualPublish() bool {
func BuildImages() {
info := mage.LoadMetadata()
+ registry := getRegistry()
- must.Command("./scripts/build-images.sh").Env("VERSION="+info.Version, "PERMALINK="+info.Permalink, "REGISTRY="+getRegistry()).RunV()
+ buildImages(registry, info)
if getDualPublish() {
- must.Command("./scripts/build-images.sh").Env("VERSION="+info.Version, "PERMALINK="+info.Permalink, "REGISTRY=ghcr.io/getporter").RunV()
+ buildImages("ghcr.io/getporter", info)
}
}
+func buildImages(registry string, info mage.GitMetadata) {
+ var g errgroup.Group
+
+ g.Go(func() error {
+ img := fmt.Sprintf("%s/porter:%s", registry, info.Version)
+ err := shx.RunV("docker", "build", "-t", img, "-f", "build/images/client/Dockerfile", ".")
+ if err != nil {
+ return err
+ }
+
+ err = shx.Run("docker", "tag", img, fmt.Sprintf("%s/porter:%s", registry, info.Permalink))
+ if err != nil {
+ return err
+ }
+
+ // porter-agent does a FROM porter so they can't go in parallel
+ img = fmt.Sprintf("%s/porter-agent:%s", registry, info.Version)
+ err = shx.RunV("docker", "build", "-t", img, "--build-arg", "PORTER_VERSION="+info.Version, "--build-arg", "REGISTRY="+registry, "-f", "build/images/agent/Dockerfile", "build/images/agent")
+ if err != nil {
+ return err
+ }
+
+ return shx.Run("docker", "tag", img, fmt.Sprintf("%s/porter-agent:%s", registry, info.Permalink))
+ })
+
+ g.Go(func() error {
+ img := fmt.Sprintf("%s/workshop:%s", registry, info.Version)
+ err := shx.RunV("docker", "build", "-t", img, "-f", "build/images/workshop/Dockerfile", ".")
+ if err != nil {
+ return err
+ }
+
+ return shx.Run("docker", "tag", img, fmt.Sprintf("%s/workshop:%s", registry, info.Permalink))
+ })
+
+ mgx.Must(g.Wait())
+}
+
func PublishImages() {
mg.Deps(BuildImages)
info := mage.LoadMetadata()
- must.Command("./scripts/publish-images.sh").Env("VERSION="+info.Version, "PERMALINK="+info.Permalink, "REGISTRY="+getRegistry()).RunV()
+ pushImagesTo(getRegistry(), info)
if getDualPublish() {
- must.Command("./scripts/publish-images.sh").Env("VERSION="+info.Version, "PERMALINK="+info.Permalink, "REGISTRY=ghcr.io/getporter").RunV()
+ pushImagesTo("ghcr.io/getporter", info)
}
}
+// Only push tagged versions, canary and latest
+func pushImagesTo(registry string, info mage.GitMetadata) {
+ if info.IsTaggedRelease {
+ pushImages(registry, info.Version)
+ }
+
+ if info.ShouldPublishPermalink() {
+ pushImages(registry, info.Permalink)
+ } else {
+ fmt.Println("Skipping image publish for permalink", info.Permalink)
+ }
+}
+
+func pushImages(registry string, tag string) {
+ pushImage(fmt.Sprintf("%s/porter:%s", registry, tag))
+ pushImage(fmt.Sprintf("%s/porter-agent:%s", registry, tag))
+ pushImage(fmt.Sprintf("%s/workshop:%s", registry, tag))
+}
+
+func pushImage(img string) {
+ must.RunV("docker", "push", img)
+}
+
// Publish the porter binaries and install scripts.
func PublishPorter() {
mg.Deps(tools.EnsureGitHubClient, releases.ConfigureGitBot)
@@ -183,13 +245,17 @@ func PublishPorter() {
}
remote := fmt.Sprintf("https://%s.git", repo)
- // Move the permalink tag. The existing release automatically points to the tag.
- must.RunV("git", "tag", info.Permalink, info.Version+"^{}", "-f")
- must.RunV("git", "push", "-f", remote, info.Permalink)
-
// Create or update GitHub release for the permalink (canary/latest) with the version's assets (porter binaries, exec binaries and install scripts)
- releases.AddFilesToRelease(repo, info.Permalink, porterVersionDir)
- releases.AddFilesToRelease(repo, info.Permalink, execVersionDir)
+ if info.ShouldPublishPermalink() {
+ // Move the permalink tag. The existing release automatically points to the tag.
+ must.RunV("git", "tag", info.Permalink, info.Version+"^{}", "-f")
+ must.RunV("git", "push", "-f", remote, info.Permalink)
+
+ releases.AddFilesToRelease(repo, info.Permalink, porterVersionDir)
+ releases.AddFilesToRelease(repo, info.Permalink, execVersionDir)
+ } else {
+ fmt.Println("Skipping publish binaries for permalink", info.Permalink)
+ }
if info.IsTaggedRelease {
// Create GitHub release for the exact version (v1.2.3) and attach assets
diff --git a/pkg/pkgmgmt/feed/generate.go b/pkg/pkgmgmt/feed/generate.go
index dc9397187..5a44aee95 100644
--- a/pkg/pkgmgmt/feed/generate.go
+++ b/pkg/pkgmgmt/feed/generate.go
@@ -5,7 +5,6 @@ import (
"os"
"regexp"
"sort"
- "strings"
"time"
"get.porter.sh/porter/pkg/context"
@@ -127,8 +126,8 @@ var versionRegex = regexp.MustCompile(`\d+-g[a-z0-9]+`)
// As a safety measure, skip versions that shouldn't be put in the feed, we only want canary and tagged releases.
func shouldPublishVersion(version string) bool {
- if strings.HasSuffix(version, "canary") {
- // Publish canary permalinks
+ // Publish canary permalinks, for now ignore canary-v1
+ if version == "canary" {
return true
}
diff --git a/pkg/pkgmgmt/feed/generate_test.go b/pkg/pkgmgmt/feed/generate_test.go
index e02a469e8..b2c52c554 100644
--- a/pkg/pkgmgmt/feed/generate_test.go
+++ b/pkg/pkgmgmt/feed/generate_test.go
@@ -63,12 +63,9 @@ func TestGenerate(t *testing.T) {
tc.FileSystem.Create("bin/latest/helm-linux-amd64")
tc.FileSystem.Create("bin/latest/helm-windows-amd64.exe")
- tc.FileSystem.Create("bin/v2-latest/helm-darwin-amd64")
- tc.FileSystem.Create("bin/v2-latest/helm-linux-amd64")
- tc.FileSystem.Create("bin/v2-latest/helm-windows-amd64.exe")
- tc.FileSystem.Chtimes("bin/v2-latest/helm-darwin-amd64", up4, up4)
- tc.FileSystem.Chtimes("bin/v2-latest/helm-linux-amd64", up4, up4)
- tc.FileSystem.Chtimes("bin/v2-latest/helm-windows-amd64.exe", up4, up4)
+ tc.FileSystem.Create("bin/canary-v1/exec-darwin-amd64")
+ tc.FileSystem.Create("bin/canary-v1/exec-linux-amd64")
+ tc.FileSystem.Create("bin/canary-v1/exec-windows-amd64.exe")
opts := GenerateOptions{
AtomFile: "atom.xml",
@@ -230,13 +227,6 @@ func TestGenerate_RegenerateDoesNotCreateDuplicates(t *testing.T) {
tc.FileSystem.Chtimes("bin/canary/exec-linux-amd64", up10, up10)
tc.FileSystem.Chtimes("bin/canary/exec-windows-amd64.exe", up10, up10)
- tc.FileSystem.Create("bin/v2-latest/helm-darwin-amd64")
- tc.FileSystem.Create("bin/v2-latest/helm-linux-amd64")
- tc.FileSystem.Create("bin/v2-latest/helm-windows-amd64.exe")
- tc.FileSystem.Chtimes("bin/v2-latest/helm-darwin-amd64", up4, up4)
- tc.FileSystem.Chtimes("bin/v2-latest/helm-linux-amd64", up4, up4)
- tc.FileSystem.Chtimes("bin/v2-latest/helm-windows-amd64.exe", up4, up4)
-
opts := GenerateOptions{
AtomFile: "atom.xml",
SearchDirectory: "bin",
diff --git a/pkg/pkgmgmt/feed/testdata/atom-existing.xml b/pkg/pkgmgmt/feed/testdata/atom-existing.xml
index c7f8facc3..643e5203d 100644
--- a/pkg/pkgmgmt/feed/testdata/atom-existing.xml
+++ b/pkg/pkgmgmt/feed/testdata/atom-existing.xml
@@ -8,17 +8,6 @@
https://porter.sh/mixins
-
-
- https://cdn.porter.sh/mixins/v2-latest/helm
- helm @ v2-latest
- 2013-02-4T00:00:00Z
-
- v2-latest
-
-
-
-
https://cdn.porter.sh/mixins/canary/exec
exec @ canary
diff --git a/pkg/pkgmgmt/feed/testdata/atom.xml b/pkg/pkgmgmt/feed/testdata/atom.xml
index b9d7ca474..af35a4363 100644
--- a/pkg/pkgmgmt/feed/testdata/atom.xml
+++ b/pkg/pkgmgmt/feed/testdata/atom.xml
@@ -19,16 +19,6 @@
-
- https://cdn.porter.sh/mixins/v2-latest/helm
- helm @ v2-latest
- 2013-02-04T00:00:00Z
-
- v2-latest
-
-
-
-
https://cdn.porter.sh/mixins/v1.2.4/helm
helm @ v1.2.4
diff --git a/scripts/build-images.sh b/scripts/build-images.sh
deleted file mode 100755
index 0d692a683..000000000
--- a/scripts/build-images.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-
-# REGISTRY, PERMALINK and VERSION must be set before calling this script
-# It is intended to only be executed by make publish
-
-docker build -t $REGISTRY/porter:$VERSION -f build/images/client/Dockerfile .
-docker build -t $REGISTRY/porter-agent:$VERSION --build-arg PORTER_VERSION=$VERSION --build-arg REGISTRY=$REGISTRY -f build/images/agent/Dockerfile build/images/agent
-docker build -t $REGISTRY/workshop:$VERSION -f build/images/workshop/Dockerfile .
-
-docker tag $REGISTRY/porter:$VERSION $REGISTRY/porter:$PERMALINK
-docker tag $REGISTRY/porter-agent:$VERSION $REGISTRY/porter-agent:$PERMALINK
-docker tag $REGISTRY/workshop:$VERSION $REGISTRY/workshop:$PERMALINK
diff --git a/scripts/publish-images.sh b/scripts/publish-images.sh
deleted file mode 100755
index 2bd1975d7..000000000
--- a/scripts/publish-images.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-
-# REGISTRY, PERMALINK and VERSION must be set before calling this script
-# It is intended to only be executed by make publish
-
-if [[ "$PERMALINK" == *latest ]]; then
- docker push $REGISTRY/porter:$VERSION
- docker push $REGISTRY/porter-agent:$VERSION
- docker push $REGISTRY/workshop:$VERSION
-
- docker push $REGISTRY/porter:$PERMALINK
- docker push $REGISTRY/porter-agent:$PERMALINK
- docker push $REGISTRY/workshop:$PERMALINK
-else
- docker push $REGISTRY/porter:$PERMALINK
- docker push $REGISTRY/porter-agent:$PERMALINK
- docker push $REGISTRY/workshop:$PERMALINK
-fi