mirror of https://github.com/portainer/portainer
feat(buildinfo): ability to see build info [EE-2552] (#7107)
* feat(buildinfo): ability to see build info [EE-2252] * handle dark theme * feat: add build info to status version * feat: include ldflags in azure pipeline * echo shell commands in azure build * clean up main log * allow tests to pass * use data from backend * allow clicking off modal to dismiss * add placeholder versions * refactor * update button class * fix modal displaying behind elements Co-authored-by: Dmitry Salakhov <to@dimasalakhov.com>pull/7152/head
parent
f5e774c89d
commit
a0d349e0b3
|
@ -0,0 +1,9 @@
|
||||||
|
package build
|
||||||
|
|
||||||
|
// Variables to be set during the build time
|
||||||
|
var BuildNumber string
|
||||||
|
var ImageTag string
|
||||||
|
var NodejsVersion string
|
||||||
|
var YarnVersion string
|
||||||
|
var WebpackVersion string
|
||||||
|
var GoVersion string
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/portainer/libhelm"
|
"github.com/portainer/libhelm"
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
"github.com/portainer/portainer/api/apikey"
|
"github.com/portainer/portainer/api/apikey"
|
||||||
|
"github.com/portainer/portainer/api/build"
|
||||||
"github.com/portainer/portainer/api/chisel"
|
"github.com/portainer/portainer/api/chisel"
|
||||||
"github.com/portainer/portainer/api/cli"
|
"github.com/portainer/portainer/api/cli"
|
||||||
"github.com/portainer/portainer/api/crypto"
|
"github.com/portainer/portainer/api/crypto"
|
||||||
|
@ -743,7 +744,15 @@ func main() {
|
||||||
|
|
||||||
for {
|
for {
|
||||||
server := buildServer(flags)
|
server := buildServer(flags)
|
||||||
logrus.Printf("[INFO] [cmd,main] Starting Portainer version %s\n", portainer.APIVersion)
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"Version": portainer.APIVersion,
|
||||||
|
"BuildNumber": build.BuildNumber,
|
||||||
|
"ImageTag": build.ImageTag,
|
||||||
|
"NodejsVersion": build.NodejsVersion,
|
||||||
|
"YarnVersion": build.YarnVersion,
|
||||||
|
"WebpackVersion": build.WebpackVersion,
|
||||||
|
"GoVersion": build.GoVersion},
|
||||||
|
).Print("[INFO] [cmd,main] Starting Portainer")
|
||||||
err := server.Start()
|
err := server.Start()
|
||||||
logrus.Printf("[INFO] [cmd,main] Http server exited: %v\n", err)
|
logrus.Printf("[INFO] [cmd,main] Http server exited: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ func NewHandler(bouncer *security.RequestBouncer, status *portainer.Status, demo
|
||||||
h.Handle("/status",
|
h.Handle("/status",
|
||||||
bouncer.PublicAccess(httperror.LoggerHandler(h.statusInspect))).Methods(http.MethodGet)
|
bouncer.PublicAccess(httperror.LoggerHandler(h.statusInspect))).Methods(http.MethodGet)
|
||||||
h.Handle("/status/version",
|
h.Handle("/status/version",
|
||||||
bouncer.AuthenticatedAccess(http.HandlerFunc(h.statusInspectVersion))).Methods(http.MethodGet)
|
bouncer.AuthenticatedAccess(http.HandlerFunc(h.version))).Methods(http.MethodGet)
|
||||||
|
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
package status
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/coreos/go-semver/semver"
|
|
||||||
|
|
||||||
portainer "github.com/portainer/portainer/api"
|
|
||||||
"github.com/portainer/portainer/api/http/client"
|
|
||||||
|
|
||||||
"github.com/portainer/libhttp/response"
|
|
||||||
)
|
|
||||||
|
|
||||||
type inspectVersionResponse struct {
|
|
||||||
// Whether portainer has an update available
|
|
||||||
UpdateAvailable bool `json:"UpdateAvailable" example:"false"`
|
|
||||||
// The latest version available
|
|
||||||
LatestVersion string `json:"LatestVersion" example:"2.0.0"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type githubData struct {
|
|
||||||
TagName string `json:"tag_name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// @id StatusInspectVersion
|
|
||||||
// @summary Check for portainer updates
|
|
||||||
// @description Check if portainer has an update available
|
|
||||||
// @description **Access policy**: authenticated
|
|
||||||
// @security ApiKeyAuth
|
|
||||||
// @security jwt
|
|
||||||
// @tags status
|
|
||||||
// @produce json
|
|
||||||
// @success 200 {object} inspectVersionResponse "Success"
|
|
||||||
// @router /status/version [get]
|
|
||||||
func (handler *Handler) statusInspectVersion(w http.ResponseWriter, r *http.Request) {
|
|
||||||
motd, err := client.Get(portainer.VersionCheckURL, 5)
|
|
||||||
if err != nil {
|
|
||||||
response.JSON(w, &inspectVersionResponse{UpdateAvailable: false})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var data githubData
|
|
||||||
err = json.Unmarshal(motd, &data)
|
|
||||||
if err != nil {
|
|
||||||
response.JSON(w, &inspectVersionResponse{UpdateAvailable: false})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := inspectVersionResponse{
|
|
||||||
UpdateAvailable: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
currentVersion := semver.New(portainer.APIVersion)
|
|
||||||
latestVersion := semver.New(data.TagName)
|
|
||||||
if currentVersion.LessThan(*latestVersion) {
|
|
||||||
resp.UpdateAvailable = true
|
|
||||||
resp.LatestVersion = data.TagName
|
|
||||||
}
|
|
||||||
|
|
||||||
response.JSON(w, &resp)
|
|
||||||
}
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
package status
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/coreos/go-semver/semver"
|
||||||
|
|
||||||
|
portainer "github.com/portainer/portainer/api"
|
||||||
|
"github.com/portainer/portainer/api/build"
|
||||||
|
"github.com/portainer/portainer/api/http/client"
|
||||||
|
|
||||||
|
"github.com/portainer/libhttp/response"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type versionResponse struct {
|
||||||
|
// Whether portainer has an update available
|
||||||
|
UpdateAvailable bool `json:"UpdateAvailable" example:"false"`
|
||||||
|
// The latest version available
|
||||||
|
LatestVersion string `json:"LatestVersion" example:"2.0.0"`
|
||||||
|
|
||||||
|
ServerVersion string
|
||||||
|
DatabaseVersion string
|
||||||
|
Build BuildInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type BuildInfo struct {
|
||||||
|
BuildNumber string
|
||||||
|
ImageTag string
|
||||||
|
NodejsVersion string
|
||||||
|
YarnVersion string
|
||||||
|
WebpackVersion string
|
||||||
|
GoVersion string
|
||||||
|
}
|
||||||
|
|
||||||
|
// @id Version
|
||||||
|
// @summary Check for portainer updates
|
||||||
|
// @description Check if portainer has an update available
|
||||||
|
// @description **Access policy**: authenticated
|
||||||
|
// @security ApiKeyAuth
|
||||||
|
// @security jwt
|
||||||
|
// @tags status
|
||||||
|
// @produce json
|
||||||
|
// @success 200 {object} versionResponse "Success"
|
||||||
|
// @router /status/version [get]
|
||||||
|
func (handler *Handler) version(w http.ResponseWriter, r *http.Request) {
|
||||||
|
result := &versionResponse{
|
||||||
|
ServerVersion: portainer.APIVersion,
|
||||||
|
DatabaseVersion: strconv.Itoa(portainer.DBVersion),
|
||||||
|
Build: BuildInfo{
|
||||||
|
BuildNumber: build.BuildNumber,
|
||||||
|
ImageTag: build.ImageTag,
|
||||||
|
NodejsVersion: build.NodejsVersion,
|
||||||
|
YarnVersion: build.YarnVersion,
|
||||||
|
WebpackVersion: build.WebpackVersion,
|
||||||
|
GoVersion: build.GoVersion,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
latestVersion := getLatestVersion()
|
||||||
|
if hasNewerVersion(portainer.APIVersion, latestVersion) {
|
||||||
|
result.UpdateAvailable = true
|
||||||
|
result.LatestVersion = latestVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
response.JSON(w, &result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLatestVersion() string {
|
||||||
|
motd, err := client.Get(portainer.VersionCheckURL, 5)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Debug("couldn't fetch latest Portainer release version")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var data struct {
|
||||||
|
TagName string `json:"tag_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(motd, &data)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Debug("couldn't parse latest Portainer version")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.TagName
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasNewerVersion(currentVersion, latestVersion string) bool {
|
||||||
|
currentVersionSemver, err := semver.NewVersion(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
log.WithField("version", currentVersion).Debug("current Portainer version isn't a semver")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
latestVersionSemver, err := semver.NewVersion(latestVersion)
|
||||||
|
if err != nil {
|
||||||
|
log.WithField("version", latestVersion).Debug("latest Portainer version isn't a semver")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentVersionSemver.LessThan(*latestVersionSemver)
|
||||||
|
}
|
|
@ -25,9 +25,7 @@ export async function getStatus() {
|
||||||
try {
|
try {
|
||||||
const { data } = await axios.get<StatusResponse>(buildUrl());
|
const { data } = await axios.get<StatusResponse>(buildUrl());
|
||||||
|
|
||||||
if (process.env.PORTAINER_EDITION !== 'CE') {
|
data.Edition = 'Community Edition';
|
||||||
data.Edition = 'Business Edition';
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -46,6 +44,16 @@ export interface VersionResponse {
|
||||||
UpdateAvailable: boolean;
|
UpdateAvailable: boolean;
|
||||||
// The latest version available
|
// The latest version available
|
||||||
LatestVersion: string;
|
LatestVersion: string;
|
||||||
|
ServerVersion: string;
|
||||||
|
DatabaseVersion: string;
|
||||||
|
Build: {
|
||||||
|
BuildNumber: string;
|
||||||
|
ImageTag: string;
|
||||||
|
NodejsVersion: string;
|
||||||
|
YarnVersion: string;
|
||||||
|
WebpackVersion: string;
|
||||||
|
GoVersion: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getVersionStatus() {
|
export async function getVersionStatus() {
|
||||||
|
|
|
@ -1,3 +1,42 @@
|
||||||
:global(#page-wrapper:not(.open)) .root {
|
:global(#page-wrapper:not(.open)) .root {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionInfo {
|
||||||
|
margin: 5px 15px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionInfo table {
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.versionInfo td {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolsList {
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #d3d3d3;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: rgba(211, 211, 211, 0.2);
|
||||||
|
width: max-width;
|
||||||
|
font-family: Arial;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolsList span {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools span {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,44 +1,150 @@
|
||||||
|
import { useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import { Database, Hash, Server, Tag, Tool } from 'react-feather';
|
||||||
|
import { DialogOverlay } from '@reach/dialog';
|
||||||
|
|
||||||
import { getStatus } from '@/portainer/services/api/status.service';
|
import {
|
||||||
|
getStatus,
|
||||||
|
getVersionStatus,
|
||||||
|
} from '@/portainer/services/api/status.service';
|
||||||
|
|
||||||
|
import { Button } from '@@/buttons';
|
||||||
|
|
||||||
import { UpdateNotification } from './UpdateNotifications';
|
import { UpdateNotification } from './UpdateNotifications';
|
||||||
import styles from './Footer.module.css';
|
import styles from './Footer.module.css';
|
||||||
|
import '@reach/dialog/styles.css';
|
||||||
|
|
||||||
export function Footer() {
|
export function Footer() {
|
||||||
|
const [showBuildInfo, setShowBuildInfo] = useState(false);
|
||||||
const statusQuery = useStatus();
|
const statusQuery = useStatus();
|
||||||
|
const versionQuery = useVersionStatus();
|
||||||
|
|
||||||
if (!statusQuery.data) {
|
if (!statusQuery.data || !versionQuery.data) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { Edition, Version } = statusQuery.data;
|
const { Edition, Version } = statusQuery.data;
|
||||||
|
const { ServerVersion, DatabaseVersion, Build } = versionQuery.data;
|
||||||
|
|
||||||
|
function toggleModal() {
|
||||||
|
setShowBuildInfo(!showBuildInfo);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx(styles.root, 'text-center')}>
|
<>
|
||||||
{process.env.PORTAINER_EDITION === 'CE' && <UpdateNotification />}
|
<DialogOverlay className={styles.dialog} isOpen={showBuildInfo}>
|
||||||
<div className="text-xs space-x-1 text-gray-5 be:text-gray-6">
|
<div className="modal-dialog">
|
||||||
<span>©</span>
|
<div className="modal-content">
|
||||||
<span>Portainer {Edition}</span>
|
<div className="modal-header">
|
||||||
|
<button type="button" className="close" onClick={toggleModal}>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
<h5 className="modal-title">Portainer {Edition}</h5>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className={styles.versionInfo}>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span className="inline-flex items-center">
|
||||||
|
<Server size="13" className="space-right" />
|
||||||
|
Server Version: {ServerVersion}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span className="inline-flex items-center">
|
||||||
|
<Database size="13" className="space-right" />
|
||||||
|
Database Version: {DatabaseVersion}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span className="inline-flex items-center">
|
||||||
|
<Hash size="13" className="space-right" />
|
||||||
|
CI Build Number: {Build.BuildNumber}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>
|
||||||
|
<Tag size="13" className="space-right" />
|
||||||
|
Image Tag: {Build.ImageTag}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className={styles.toolsList}>
|
||||||
|
<span className="inline-flex items-center">
|
||||||
|
<Tool size="13" className="space-right" />
|
||||||
|
Compilation tools:
|
||||||
|
</span>
|
||||||
|
|
||||||
<span data-cy="portainerSidebar-versionNumber">{Version}</span>
|
<div className={styles.tools}>
|
||||||
|
<span className="text-muted small">
|
||||||
|
Nodejs v{Build.NodejsVersion}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted small">
|
||||||
|
Yarn v{Build.YarnVersion}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted small">
|
||||||
|
Webpack v{Build.WebpackVersion}
|
||||||
|
</span>
|
||||||
|
<span className="text-muted small">
|
||||||
|
Go v{Build.GoVersion}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<Button className="bootbox-accept" onClick={toggleModal}>
|
||||||
|
Ok
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogOverlay>
|
||||||
|
|
||||||
{process.env.PORTAINER_EDITION === 'CE' && (
|
<div className={clsx(styles.root, 'text-center')}>
|
||||||
<a
|
{process.env.PORTAINER_EDITION === 'CE' && <UpdateNotification />}
|
||||||
href="https://www.portainer.io/install-BE-now"
|
<div className="text-xs space-x-1 text-gray-5 be:text-gray-6">
|
||||||
className="text-blue-6 font-medium"
|
<span>©</span>
|
||||||
target="_blank"
|
<span>Portainer {Edition}</span>
|
||||||
rel="noreferrer"
|
|
||||||
|
<span
|
||||||
|
data-cy="portainerSidebar-versionNumber"
|
||||||
|
onClick={toggleModal}
|
||||||
|
// Accessibility requirements for a clickable span
|
||||||
|
onKeyPress={toggleModal}
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
Upgrade
|
{Version}
|
||||||
</a>
|
</span>
|
||||||
)}
|
|
||||||
|
{process.env.PORTAINER_EDITION === 'CE' && (
|
||||||
|
<a
|
||||||
|
href="https://www.portainer.io/install-BE-now"
|
||||||
|
className="text-blue-6 font-medium"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
Upgrade
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useStatus() {
|
function useStatus() {
|
||||||
return useQuery(['status'], () => getStatus());
|
return useQuery(['status'], () => getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useVersionStatus() {
|
||||||
|
return useQuery(['version'], () => getVersionStatus());
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,14 @@ set -x
|
||||||
|
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
|
|
||||||
|
# populate tool versions
|
||||||
|
BUILDNUMBER="N/A"
|
||||||
|
CONTAINER_IMAGE_TAG="N/A"
|
||||||
|
NODE_VERSION="0"
|
||||||
|
YARN_VERSION="0"
|
||||||
|
WEBPACK_VERSION="0"
|
||||||
|
GO_VERSION="0"
|
||||||
|
|
||||||
cd api
|
cd api
|
||||||
# the go get adds 8 seconds
|
# the go get adds 8 seconds
|
||||||
go get -t -d -v ./...
|
go get -t -d -v ./...
|
||||||
|
@ -9,6 +17,12 @@ go get -t -d -v ./...
|
||||||
# the build takes 2 seconds
|
# the build takes 2 seconds
|
||||||
GOOS=$1 GOARCH=$2 CGO_ENABLED=0 go build \
|
GOOS=$1 GOARCH=$2 CGO_ENABLED=0 go build \
|
||||||
--installsuffix cgo \
|
--installsuffix cgo \
|
||||||
--ldflags '-s' \
|
--ldflags "-s \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.BuildNumber=${BUILDNUMBER}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.ImageTag=${CONTAINER_IMAGE_TAG}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.NodejsVersion=${NODE_VERSION}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.YarnVersion=${YARN_VERSION}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.WebpackVersion=${WEBPACK_VERSION}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.GoVersion=${GO_VERSION}'" \
|
||||||
-o "../dist/portainer" \
|
-o "../dist/portainer" \
|
||||||
./cmd/portainer/
|
./cmd/portainer/
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
set -x
|
||||||
|
|
||||||
PLATFORM=$1
|
PLATFORM=$1
|
||||||
ARCH=$2
|
ARCH=$2
|
||||||
|
@ -15,7 +16,13 @@ cp -R api ${GOPATH}/src/github.com/portainer/portainer/api
|
||||||
cd 'api/cmd/portainer'
|
cd 'api/cmd/portainer'
|
||||||
|
|
||||||
go get -t -d -v ./...
|
go get -t -d -v ./...
|
||||||
GOOS=${PLATFORM} GOARCH=${ARCH} CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags '-s'
|
GOOS=${PLATFORM} GOARCH=${ARCH} CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags "-s \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.BuildNumber=${BUILDNUMBER}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.ImageTag=${CONTAINER_IMAGE_TAG}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.NodejsVersion=${NODE_VERSION}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.YarnVersion=${YARN_VERSION}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.WebpackVersion=${WEBPACK_VERSION}' \
|
||||||
|
-X 'github.com/portainer/portainer/api/build.GoVersion=${GO_VERSION}'"
|
||||||
|
|
||||||
if [ "${PLATFORM}" == 'windows' ]; then
|
if [ "${PLATFORM}" == 'windows' ]; then
|
||||||
mv "$BUILD_SOURCESDIRECTORY/api/cmd/portainer/${binary}.exe" "$BUILD_SOURCESDIRECTORY/dist/portainer.exe"
|
mv "$BUILD_SOURCESDIRECTORY/api/cmd/portainer/${binary}.exe" "$BUILD_SOURCESDIRECTORY/dist/portainer.exe"
|
||||||
|
|
Loading…
Reference in New Issue