Skip to content
This repository has been archived by the owner on Jun 21, 2024. It is now read-only.

MM-21886 - Update matterbuild cutplugin command to split plugin binaries, sign and upload to s3 #17

Merged
merged 24 commits into from
Feb 11, 2020

Conversation

alifarooq0
Copy link
Contributor

@alifarooq0 alifarooq0 commented Jan 30, 2020

Summary

  1. Re-worked cutPlugin to use sftp as opposed to scp, as the go-scp client was not reliably fetching files from the remote-server (was writing extra bytes to the files)
  2. Split github plugin tar into platform specific tars (osx, linux, windows). Used bash commands to generate .tar.gz files, as using Golang's archive API wasn't achieving the same level of compression.
  3. Added a --force flag to cutPlugin that re-signs and uploads to github+s3. /matterbuild cutPlugin --tag v0.4.1 --repo mattermost-plugin-demo --force
  4. Added tests for plugin_release; (not many, but best i could).
  5. Updated Makefile to include run-server
  6. Added sane defaults to config.json for local development
  7. Added README.md that includes instructions on how to test/setup matterbuild slash command
  8. Tested the changes by hand as writing integration tests were out of scope for this. I started writing unit tests by mocking out some external dependencies, but github client isn't mockable at all 😭

NOTE Majority of the changes are from the vendor directory, therefore ignore vendor/* files :).

Ticket Link

Fixes https://mattermost.atlassian.net/browse/MM-21886

@alifarooq0 alifarooq0 changed the title Mm 21886 MM-21886 - Update matterbuild cut command to split plugin binaries, sign and upload to s3 Jan 30, 2020
@alifarooq0 alifarooq0 changed the title MM-21886 - Update matterbuild cut command to split plugin binaries, sign and upload to s3 MM-21886 - Update matterbuild cutplugin command to split plugin binaries, sign and upload to s3 Jan 30, 2020
@alifarooq0 alifarooq0 added the 2: Dev Review Requires review by a core committer label Jan 30, 2020
Comment on lines +67 to +68
"PluginSigningSSHUser": "---",
"PluginSigningSSHHost": "---",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preferably I want to set real values here so whoever wants to tests this locally doesn't have to figure out what goes here. Any concerns if I include the real plugin signing ssh host/username values here @DSchalla ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ali-farooq0 Users will have no access to the server in the future, so I don't see a particular benefit of sharing this in a public repository - The SSH access was meant as a temporary solution for users. What you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh good point. Alright will leave this the way it is then. Thanks @DSchalla!

Comment on lines +53 to +54
2. Get AWS [Vault](https://developers.mattermost.com/internal/infrastructure/vault/) credentials
3. Signed public certificate by Vault
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as below, can i include vault commands here that fetch the aws token and signed public cert?
@DSchalla

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above, thanks.

@alifarooq0
Copy link
Contributor Author

Adding @hanzei from toolkit's perspective.

@lieut-data lieut-data removed their request for review January 30, 2020 17:52
@jaydeland
Copy link
Contributor

@ali-farooq0
Do we need to track these binaries:
server/test/mattermost-plugin-demo-v0.4.1-linux-amd64.tar.gz
server/test/mattermost-plugin-demo-v0.4.1.tar.gz

@alifarooq0
Copy link
Contributor Author

@jaydeland Those are needed for the unit tests.

Copy link
Contributor

@jaydeland jaydeland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - I can't comment much on the go code

.vscode/settings.json Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
config.json Outdated Show resolved Hide resolved
if err != nil {
return err
return nil, fmt.Errorf("failed to get release by tag err=%w", err)
Copy link
Contributor

@metanerd metanerd Feb 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we use mlog here, or honestly, because I do not know, what is the de facto standard?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mlog to just log and not return an error? standard way is to use errors pkg or fmt.Errorf()
https://github.com/golang/go/wiki/CodeReviewComments#error-strings

LogInfo("Will sign the artifact")
sshClient, err := sshwrapper.DefaultSshApiSetup(Cfg.PluginSigningSSHHost, 22, Cfg.PluginSigningSSHUser, Cfg.PluginSigningSSHKeyPath)
func getPluginSigningSftpClient(cfg *MatterbuildConfig) (*sftp.Client, error) {
clientConfig, err := privateKey(cfg.PluginSigningSSHUser, cfg.PluginSigningSSHKeyPath, cfg.PluginSigningSSHPublicCertPath, ssh.InsecureIgnoreHostKey())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can help with adding the ssh key to the known_hosts file.

func uploadSignedArtifcatsToS3(fileToUpload []string, tempFolder string) error {
LogInfo("Uploading signed assets to S3")
// archiveContains returns filenames that matches a given string.
func archiveContains(filePath string, contains string) ([]string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we write a test for this or is it too much?

Copy link
Contributor

@metanerd metanerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So much work. It is very much appreciated 🙇‍♂️ ! Thank you so much!

@hanzei hanzei mentioned this pull request Feb 9, 2020
Copy link
Contributor

@hanzei hanzei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work 👍

refs, _, err := client.Git.GetRefs(ctx, owner, repository, fmt.Sprintf("tags/%s", tag))
if err != nil {
var gerr *github.ErrorResponse
if !errors.As(err, &gerr) || gerr.Response.StatusCode != http.StatusNotFound {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I find this hard to read and understand. Maybe an else would make it more clear:

if errors.As(err, &gerr) && gerr.Response.StatusCode == http.StatusNotFound {
	LogInfo("tag %s was not found, creating tag", tag)
} else {
	return errors.Wrapf(err, "failed to get github tag")
}

if err != nil {
LogError("Error opening the file. err=" + err.Error())
return err
// Couldn't achieve gzip level compressions with golang archive api, using shell cmds instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation. How many MBs are saved with using exec? I'm wondering if the cost is worth the risk.

LogInfo("Will download the github release asset")
url := strings.Split(assetURL, "/")
filename := url[len(url)-1]
func downloadAsset(ctx context.Context, asset *github.ReleaseAsset, folder string) (filePath string, err error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking: I think a godoc comment should make clear what the semantic of the return values is. Named return parameters ist offer to much possibilities for bug and bad readable code.

func cutPlugin(ctx context.Context, cfg *MatterbuildConfig, client *github.Client, owner, repositoryName, tag string) error {
pluginAsset, err := getPluginAsset(ctx, client, owner, repositoryName, tag)
if err != nil {
return errors.Wrapf(err, "failed to get plugin asset")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not block: Wrapf is not strictly needed. errors.Wrap is enough. Feel free to change it in the whole file if you want.

Suggested change
return errors.Wrapf(err, "failed to get plugin asset")
return errors.Wrap(err, "failed to get plugin asset")

@alifarooq0 alifarooq0 merged commit c50069c into master Feb 11, 2020
@alifarooq0 alifarooq0 deleted the MM-21886 branch February 11, 2020 12:50
@hanzei hanzei added 3: Reviews Complete All reviewers have approved the pull request and removed 2: Dev Review Requires review by a core committer labels Feb 15, 2020
jaydeland pushed a commit that referenced this pull request Apr 2, 2020
* updating vendor dir and mod files

* Rework cutplugin command to upload signed platform specific plugin tars to s3

* Confirmed tests are breaking build

* Updated waiting text message

* Fixed govet

* Making check-style happy

* Added govendor target

* Updated tag created message

* Include release link in the success message

* PR Feedback

* More PR feedback

* Creating github client once and passing it around

* Creating ctx once and passing it around

* inverted some conditions for better readability

* using errors.Is

* removing vscode settings file

* Making govet happy

* added PluginSigningSSHHostPublicKey

* Fixed Wrapf/Wrap

* Updated docs for downloadAsset

* Reversed gerr if check

* Using piping lib as opposed to bash

* Updating readme to include PluginSigningSSHHostPublicKey
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
3: Reviews Complete All reviewers have approved the pull request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants