Skip to content

Commit

Permalink
[MM-42190] Auto injecting, versioning and releasing (support marketpl…
Browse files Browse the repository at this point in the history
…ace) (#14)

* build changes: auto version number; generate manifests; gotestsum; etc.

* build and release on github, testing

* testing

* testing

* testing

* testing

* should be good

* debugging

* debugging

* debugging

* working now

* removed Enhancements; new `dist-ci` make cmd; gomod-check last
  • Loading branch information
cpoile authored Mar 4, 2022
1 parent efbab1d commit 4ac8eb9
Show file tree
Hide file tree
Showing 15 changed files with 226 additions and 139 deletions.
72 changes: 59 additions & 13 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ commands:
- run:
name: Check current version of NPM
command: npm -v

npm-dependencies:
description: "Get JavaScript dependencies"
steps:
Expand All @@ -44,6 +45,7 @@ commands:
key: v2-npm-{{ checksum "./webapp/package-lock.json" }}-{{ arch }}
paths:
- ./webapp/node_modules

install-golangci-lint:
description: Install golangci-lint
parameters:
Expand All @@ -60,7 +62,7 @@ commands:
steps:
- restore_cache:
name: Restore golangci-lint cache
keys: ['<< parameters.prefix >>-golangci-lint-{{ arch }}-<< parameters.version >>']
keys: [ '<< parameters.prefix >>-golangci-lint-{{ arch }}-<< parameters.version >>' ]
- run:
name: Install golangci-lint
command: |
Expand All @@ -71,17 +73,17 @@ commands:
- save_cache:
name: Save golangci-lint cache
key: '<< parameters.prefix >>-golangci-lint-{{ arch }}-<< parameters.version >>'
paths: [<< parameters.gobin >>/golangci-lint]
paths: [ << parameters.gobin >>/golangci-lint ]

aliases:
- &restore_cache
restore_cache:
key: go-mod-v1-{{ checksum "go.sum" }}
- &save_cache
save_cache:
key: go-mod-v1-{{ checksum "go.sum" }}
paths:
- "/home/circleci/go/pkg/mod"
- &restore_cache
restore_cache:
key: go-mod-v1-{{ checksum "go.sum" }}
- &save_cache
save_cache:
key: go-mod-v1-{{ checksum "go.sum" }}
paths:
- "/home/circleci/go/pkg/mod"

jobs:
lint:
Expand Down Expand Up @@ -133,13 +135,57 @@ jobs:
- npm-dependencies
- run:
name: Building Plugin Bundle
command: make dist
command: make dist-ci
- run:
name: Generating Release Notes
command: |
printf "Supported Mattermost Server Versions: **$(cat plugin.json | jq .min_server_version -r)+** \n## Commits\n" >> dist/release-notes.md
if [[ $(git tag -l | wc -l) -eq 1 ]]; then
git log --pretty='format:- %h %s' --abbrev-commit --no-decorate --no-color $(git rev-list --max-parents=0 HEAD) HEAD >> dist/release-notes.md
else
git log --pretty='format:- %h %s' --abbrev-commit --no-decorate --no-color $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..HEAD >> dist/release-notes.md
fi
- persist_to_workspace:
root: dist
paths:
- "*.tar.gz"
- "release-notes.md"
- store_artifacts:
path: dist

deploy-release-github:
docker:
- image: cibuilds/github:0.13
steps:
- attach_workspace:
at: dist
- run: 'mv dist/*.tar.gz dist/$CIRCLE_PROJECT_REPONAME-$CIRCLE_TAG.tar.gz'
- run:
name: "Publish Release on Github"
command: |
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -b "$(< ./dist/release-notes.md)" -c ${CIRCLE_SHA1} -n ${CIRCLE_TAG} -delete ${CIRCLE_TAG} dist/*.tar.gz
workflows:
version: 2
ci:
jobs:
- lint
- test
- build

- build:
context: mattermost-plugin-calls-production
filters:
tags:
only: /^v.*/
- deploy-release-github:
context: matterbuild-github-token
filters:
# ignore any commit on any branch by default
branches:
ignore: /.*/
# only act on version tags
tags:
only: /^v.*/
requires:
- lint
- test
- build
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,17 @@ dist/

# Vim
*.vim

# generated files
bin
dist
tests-e2e/node_modules
tests-e2e/cypress/screenshots
tests-e2e/cypress/videos
.eslintcache
report.xml

webapp/src/manifest.js
webapp/src/manifest.ts
server/manifest.go
server/data/
48 changes: 42 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ LDFLAGS += -X "main.rudderDataplaneURL=$(RUDDER_DATAPLANE_URL)"

export GO111MODULE=on

# We need to export GOBIN to allow it to be set
# for processes spawned from the Makefile
export GOBIN ?= $(PWD)/bin

# You can include assets this directory into the bundle. This can be e.g. used to include profile pictures.
ASSETS_DIR ?= assets

Expand Down Expand Up @@ -52,7 +56,7 @@ gomod-check:

## Runs eslint and golangci-lint
.PHONY: check-style
check-style: gomod-check golangci-lint webapp/node_modules
check-style: apply golangci-lint webapp/node_modules gomod-check
@echo Checking for style guide compliance

ifneq ($(HAS_WEBAPP),)
Expand Down Expand Up @@ -104,6 +108,19 @@ endif
endif
endif

## Builds the server on ci -- only build for linux-amd64 (for now)
.PHONY: server-ci
server-ci:
ifneq ($(HAS_SERVER),)
mkdir -p server/dist;
ifeq ($(MM_DEBUG),)
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -ldflags '$(LDFLAGS)' -trimpath -o dist/plugin-linux-amd64;
else
$(info DEBUG mode is on; to disable, unset MM_DEBUG)
cd server && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build $(GO_BUILD_FLAGS) -ldflags '$(LDFLAGS)' -gcflags "all=-N -l" -trimpath -o dist/plugin-linux-amd64;
endif
endif

## Ensures NPM dependencies are installed without having to run this all the time.
webapp/node_modules: $(wildcard webapp/package.json)
ifneq ($(HAS_WEBAPP),)
Expand All @@ -128,7 +145,7 @@ endif
bundle:
rm -rf dist/
mkdir -p dist/$(PLUGIN_ID)
cp $(MANIFEST_FILE) dist/$(PLUGIN_ID)/
./build/bin/manifest dist
ifneq ($(wildcard $(ASSETS_DIR)/.),)
cp -r $(ASSETS_DIR) dist/$(PLUGIN_ID)/
endif
Expand All @@ -151,6 +168,10 @@ endif
.PHONY: dist
dist: apply server webapp bundle

## Builds and bundles the plugin on ci.
.PHONY: dist-ci
dist-ci: apply server-ci webapp bundle

## Builds and installs the plugin to a server.
.PHONY: deploy
deploy: dist
Expand Down Expand Up @@ -210,22 +231,37 @@ detach: setup-attach
kill -9 $$DELVE_PID ; \
fi

## Ensure gotestsum is installed and available as a tool for testing.
gotestsum:
$(GO) install gotest.tools/[email protected]

## Runs any lints and unit tests defined for the server and webapp, if they exist.
.PHONY: test
test: webapp/node_modules
test: apply webapp/node_modules gotestsum
ifneq ($(HAS_SERVER),)
$(GO) test -v $(GO_TEST_FLAGS) ./server/...
$(GOBIN)/gotestsum -- -v $(GO_TEST_FLAGS) ./server/...
endif
ifneq ($(HAS_WEBAPP),)
cd webapp && $(NPM) run test;
endif
ifneq ($(wildcard ./build/sync/plan/.),)
cd ./build/sync && $(GO) test -v $(GO_TEST_FLAGS) ./...
cd ./build/sync && $(GOBIN)/gotestsum -- -v $(GO_TEST_FLAGS) ./...
endif

## Runs any lints and unit tests defined for the server and webapp, if they exist, optimized
## for a CI environment.
.PHONY: test-ci
test-ci: apply webapp/node_modules gotestsum
ifneq ($(HAS_SERVER),)
$(GOBIN)/gotestsum --format standard-verbose --junitfile report.xml -- ./...
endif
ifneq ($(HAS_WEBAPP),)
cd webapp && $(NPM) run test;
endif

## Creates a coverage report for the server code.
.PHONY: coverage
coverage: webapp/node_modules
coverage: apply webapp/node_modules
ifneq ($(HAS_SERVER),)
$(GO) test $(GO_TEST_FLAGS) -coverprofile=server/coverage.txt ./server/...
$(GO) tool cover -html=server/coverage.txt
Expand Down
80 changes: 80 additions & 0 deletions build/manifest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io/ioutil"
"os"
"strings"

"github.com/mattermost/mattermost-server/v6/model"
"github.com/pkg/errors"
Expand Down Expand Up @@ -35,6 +36,25 @@ func init() {
}
`

const pluginIDJSFileTemplate = `// This file is automatically generated. Do not modify it manually.
const manifest = JSON.parse(` + "`" + `
%s
` + "`" + `);
export default manifest;
export const id = manifest.id;
export const version = manifest.version;
export const pluginId = manifest.id;
`

// These build-time vars are read from shell commands and populated in ../setup.mk
var (
BuildHashShort string
BuildTagLatest string
BuildTagCurrent string
)

func main() {
if len(os.Args) <= 1 {
panic("no cmd specified")
Expand Down Expand Up @@ -68,6 +88,11 @@ func main() {
panic("failed to apply manifest: " + err.Error())
}

case "dist":
if err := distManifest(manifest); err != nil {
panic("failed to write manifest to dist directory: " + err.Error())
}

default:
panic("unrecognized command: " + cmd)
}
Expand All @@ -93,6 +118,27 @@ func findManifest() (*model.Manifest, error) {
return nil, errors.Wrap(err, "failed to parse manifest")
}

// Update the manifest based on the state of the current commit
// Use the first version we find (to prevent causing errors)
var version string
tags := strings.Fields(BuildTagCurrent)
for _, t := range tags {
if strings.HasPrefix(t, "v") {
version = t
break
}
}
if version == "" {
version = BuildTagLatest + "+" + BuildHashShort
}
if strings.HasPrefix(version, "v") {
version = version[1:]
}
manifest.Version = version

// Update the release notes url to point at the latest tag.
manifest.ReleaseNotesURL = manifest.HomepageURL + "releases/tag/" + BuildTagLatest

return &manifest, nil
}

Expand Down Expand Up @@ -126,5 +172,39 @@ func applyManifest(manifest *model.Manifest) error {
}
}

if manifest.HasWebapp() {
// generate JSON representation of Manifest.
// JSON is very similar and compatible with JS's object literals. so, what we do here
// is actually JS code generation.
manifestBytes, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return err
}
manifestStr := string(manifestBytes)

// write generated code to file by using JS file template.
if err := ioutil.WriteFile(
"webapp/src/manifest.ts",
[]byte(fmt.Sprintf(pluginIDJSFileTemplate, manifestStr)),
0600,
); err != nil {
return errors.Wrap(err, "failed to open webapp/src/manifest.ts")
}
}

return nil
}

// distManifest writes the manifest file to the dist directory
func distManifest(manifest *model.Manifest) error {
manifestBytes, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return err
}

if err := ioutil.WriteFile(fmt.Sprintf("dist/%s/plugin.json", manifest.Id), manifestBytes, 0600); err != nil {
return errors.Wrap(err, "failed to write plugin.json")
}

return nil
}
7 changes: 6 additions & 1 deletion build/setup.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ ifeq ($(GO),)
$(error "go is not available: see https://golang.org/doc/install")
endif

# Gather build variables to inject into the manifest tool
BUILD_HASH_SHORT = $(shell git rev-parse --short HEAD)
BUILD_TAG_LATEST = $(shell git describe --tags --match 'v*' --abbrev=0)
BUILD_TAG_CURRENT = $(shell git tag --points-at HEAD)

# Ensure that the build tools are compiled. Go's caching makes this quick.
$(shell cd build/manifest && $(GO) build -o ../bin/manifest)
$(shell cd build/manifest && $(GO) build -ldflags '-X "main.BuildHashShort=$(BUILD_HASH_SHORT)" -X "main.BuildTagLatest=$(BUILD_TAG_LATEST)" -X "main.BuildTagCurrent=$(BUILD_TAG_CURRENT)"' -o ../bin/manifest)

# Ensure that the deployment tools are compiled. Go's caching makes this quick.
$(shell cd build/pluginctl && $(GO) build -o ../bin/pluginctl)
Expand Down
1 change: 0 additions & 1 deletion plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"id": "com.mattermost.calls",
"name": "Calls",
"description": "Integrates real-time voice communication in Mattermost",
"version": "0.3.0",
"min_server_version": "6.3.0",
"server": {
"executables": {
Expand Down
Loading

0 comments on commit 4ac8eb9

Please sign in to comment.