Skip to content

Commit

Permalink
feat: add enterprise license for MrRobot@fSociety
Browse files Browse the repository at this point in the history
- add build system using GHA
  • Loading branch information
tuxity authored and github-actions[bot] committed Aug 28, 2024
1 parent 81c8b64 commit 61e0d2f
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 30 deletions.
158 changes: 158 additions & 0 deletions .github/workflows/server-ci-enterprise.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: Server CI Enterprise

on:
workflow_dispatch:
push:
branches:
- release-*
tags:
- v*

concurrency:
group: mattermost-enterprise-linux-${{ github.ref_name }}
cancel-in-progress: true

jobs:
build-server:
runs-on: ubuntu-latest
defaults:
run:
working-directory: server
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: webapp/package-lock.json

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: server/.go-version
cache-dependency-path: |
server/go.mod
server/public/go.sum
- name: Configure Enterprise edition
run: |
mkdir -p ../enterprise-dir/imports ../enterprise-dir/cloud/config
cp enterprise/placeholder.go ../enterprise-dir/imports/imports.go
cp enterprise/LICENSE ../enterprise-dir/ENTERPRISE-EDITION-LICENSE.txt
touch ../enterprise-dir/cloud/config/cloud_defaults.json
- name: Build
env:
BUILD_NUMBER: ${{ github.ref_name }}-${{ github.run_number }}
BUILD_ENTERPRISE_DIR: ../enterprise-dir
run: |
make config-reset
make build-cmd
make package
- name: Persist dist artifacts
uses: actions/upload-artifact@v4
with:
name: server-dist-artifact
path: server/dist/
retention-days: 14

- name: Create GitHub Release
uses: actions/github-script@v7
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
env:
TAG_NAME: ${{ github.ref_name }}
RELEASE_NAME: ${{ github.ref_name }}
BODY: "Full Changelog: https://github.com/${{ github.repository }}/commits/${{ github.ref_name }}"
ASSETS: >-
server/dist/mattermost-enterprise-linux-amd64.tar.gz,
server/dist/mattermost-enterprise-linux-arm64.tar.gz,
server/dist/mattermost-enterprise-osx-amd64.tar.gz,
server/dist/mattermost-enterprise-osx-arm64.tar.gz,
server/dist/mattermost-enterprise-windows-amd64.zip
with:
script: |
const fs = require('fs');
const path = require('path');
const { TAG_NAME, RELEASE_NAME, BODY, ASSETS } = process.env;
const assets = ASSETS.split(',');
let uploadUrl = '';
try {
const response = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: TAG_NAME,
name: RELEASE_NAME,
body: BODY,
draft: false,
prerelease: false,
});
console.log(`Release created: ${response.data.html_url}`);
uploadUrl = response.data.upload_url;
} catch (error) {
if (error.response && error.response.status === 422) {
core.warning(`Release already exists for tag ${TAG_NAME}. Skipping release creation and asset uploads.`);
return;
} else {
core.setFailed(`Error creating release: ${error.message}`);
return;
}
}
if (uploadUrl) {
for (const asset of assets) {
const assetPath = path.join(process.env.GITHUB_WORKSPACE, asset.trim());
const contentType = asset.endsWith('.zip') ? 'application/zip' : 'application/gzip';
const filename = path.basename(assetPath);
console.log(`Uploading asset: ${filename}`);
try {
const uploadResponse = await github.rest.repos.uploadReleaseAsset({
url: uploadUrl,
headers: {
'content-type': contentType,
'content-length': fs.statSync(assetPath).size
},
name: filename,
data: fs.readFileSync(assetPath),
});
console.log(`Asset uploaded: ${uploadResponse.data.browser_download_url}`);
} catch (uploadError) {
core.error(`Error uploading asset: ${filename}, ${uploadError.message}`);
}
}
}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker image
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/tuxity/mattermost-enterprise-edition
flavor: |
latest=false
tags: |
type=semver,pattern={{version}},value=${{ github.ref_name }}
type=raw,value=latest,enable=${{ !startsWith(github.ref, 'refs/tags/v') }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: server/build
build-contexts:
dist=server/dist
build-args:
MM_PACKAGE=file:///tmp/mattermost-enterprise-linux-amd64.tar.gz
platforms: linux/amd64
push: ${{ startsWith(github.ref, 'refs/tags/v') }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
2 changes: 1 addition & 1 deletion server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ ifneq ($(IGNORE_GO_WORK_IF_EXISTS),true)
$(GO) work use .
$(GO) work use ./public
ifeq ($(BUILD_ENTERPRISE_READY),true)
$(GO) work use ../../enterprise
$(GO) work use $(BUILD_ENTERPRISE_DIR)
endif
endif

Expand Down
2 changes: 2 additions & 0 deletions server/build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ ARG PGID=2000
# i.e. https://releases.mattermost.com/9.7.1/mattermost-9.7.1-linux-amd64.tar.gz
ARG MM_PACKAGE="https://latest.mattermost.com/mattermost-enterprise-linux"

COPY --from=dist mattermost-* /tmp

# # Install needed packages and indirect dependencies
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
Expand Down
83 changes: 54 additions & 29 deletions server/channels/app/platform/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import (

"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/shared/mlog"
"github.com/mattermost/mattermost/server/public/shared/request"

//"github.com/mattermost/mattermost/server/public/shared/request"
"github.com/mattermost/mattermost/server/v8/channels/jobs"
"github.com/mattermost/mattermost/server/v8/channels/store/sqlstore"

//"github.com/mattermost/mattermost/server/v8/channels/store/sqlstore"
"github.com/mattermost/mattermost/server/v8/channels/utils"
"github.com/mattermost/mattermost/server/v8/einterfaces"
)
Expand Down Expand Up @@ -47,7 +49,7 @@ func (ps *PlatformService) License() *model.License {
}

func (ps *PlatformService) LoadLicense() {
c := request.EmptyContext(ps.logger)
//c := request.EmptyContext(ps.logger)

// ENV var overrides all other sources of license.
licenseStr := os.Getenv(LicenseEnv)
Expand Down Expand Up @@ -80,37 +82,60 @@ func (ps *PlatformService) LoadLicense() {
return
}

licenseId := ""
props, nErr := ps.Store.System().Get()
if nErr == nil {
licenseId = props[model.SystemActiveLicenseId]
}
/*
licenseId := ""
props, nErr := ps.Store.System().Get()
if nErr == nil {
licenseId = props[model.SystemActiveLicenseId]
}
if !model.IsValidId(licenseId) {
// Lets attempt to load the file from disk since it was missing from the DB
license, licenseBytes, err := utils.GetAndValidateLicenseFileFromDisk(*ps.Config().ServiceSettings.LicenseFileLocation)
if err != nil {
ps.logger.Warn("Failed to get license from disk", mlog.Err(err))
} else {
if _, err := ps.SaveLicense(licenseBytes); err != nil {
ps.logger.Error("Failed to save license key loaded from disk.", mlog.Err(err))
if !model.IsValidId(licenseId) {
// Lets attempt to load the file from disk since it was missing from the DB
license, licenseBytes, err := utils.GetAndValidateLicenseFileFromDisk(*ps.Config().ServiceSettings.LicenseFileLocation)
if err != nil {
ps.logger.Warn("Failed to get license from disk", mlog.Err(err))
} else {
licenseId = license.Id
if _, err := ps.SaveLicense(licenseBytes); err != nil {
ps.logger.Error("Failed to save license key loaded from disk.", mlog.Err(err))
} else {
licenseId = license.Id
}
}
}
}

record, nErr := ps.Store.License().Get(sqlstore.RequestContextWithMaster(c), licenseId)
if nErr != nil {
ps.logger.Warn("License key from https://mattermost.com required to unlock enterprise features.", mlog.Err(nErr))
ps.SetLicense(nil)
return
}
err := ps.ValidateAndSetLicenseBytes([]byte(record.Bytes))
if err != nil {
ps.logger.Info("License key is invalid.")
}
record, nErr := ps.Store.License().Get(sqlstore.RequestContextWithMaster(c), licenseId)
if nErr != nil {
ps.logger.Warn("License key from https://mattermost.com required to unlock enterprise features.", mlog.Err(nErr))
ps.SetLicense(nil)
return
}
*/

f := model.Features{}
f.SetDefaults()
*f.Users = 9999
*f.Elasticsearch = false

ps.SetLicense(&model.License{
Id: model.NewId(),
IssuedAt: 0,
ExpiresAt: 4102491600000, // 1st january 2100 in ms
Customer: &model.Customer{
Name: "Mr Robot",
Email: "mrrobot@fsociety.com",
Company: "fsociety",
},
Features: &f,
SkuName: "Enterprise",
SkuShortName: model.LicenseShortSkuEnterprise,
})

/*
err := ps.ValidateAndSetLicenseBytes([]byte(record.Bytes))
if err != nil {
ps.logger.Info("License key is invalid.")
}
*/

ps.logger.Info("License key is valid, unlocking enterprise features.")
}
Expand Down
2 changes: 2 additions & 0 deletions server/enterprise/external_imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package enterprise

/*
import (
// Needed to ensure the init() method in the EE gets run
_ "github.com/mattermost/enterprise/account_migration"
Expand Down Expand Up @@ -45,3 +46,4 @@ import (
// Needed to ensure the init() method in the EE gets run
_ "github.com/mattermost/enterprise/outgoing_oauth_connections"
)
*/

0 comments on commit 61e0d2f

Please sign in to comment.