diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..fa2de5e5 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## Launch Checklist + + + + + - [ ] Briefly describe the changes in this PR. + - [ ] Link to related issues. + - [ ] Include before/after visuals or gifs if this PR includes visual changes. + - [ ] Write tests for all new functionality. + - [ ] Add an entry to `CHANGELOG.md` under the `## main` section. + diff --git a/.github/workflows/ci-desktop.yml b/.github/workflows/ci-desktop.yml deleted file mode 100644 index eb25689b..00000000 --- a/.github/workflows/ci-desktop.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: ci-desktop - -on: [ push ] - -jobs: - build: - - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./desktop - - steps: - - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: 1.18 - - - name: Make - run: make - - - name: Test --help - run: ./bin/linux/maputnik --help - - - name: Test --version - run: ./bin/linux/maputnik --version - - - name: Get style - run: wget https://maputnik.github.io/osm-liberty/style.json - - - name: Test --watch - run: ./bin/linux/maputnik --watch --file style.json & sleep 5; kill $! - - - name: Artifacts/linux - uses: actions/upload-artifact@v3 - with: - name: maputnik-linux - path: ./desktop/bin/linux/ - - - name: Artifacts/darwin - uses: actions/upload-artifact@v3 - with: - name: maputnik-darwin - path: ./desktop/bin/darwin/ - - - name: Artifacts/windows - uses: actions/upload-artifact@v3 - with: - name: maputnik-windows - path: ./desktop/bin/windows/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3492bcc2..49e0e500 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,45 +54,39 @@ jobs: - run: npm ci - run: npm run build - name: artifacts/maputnik - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik path: dist # Build and upload desktop CLI artifacts - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: ^1.19.x + go-version: ^1.23.x + cache-dependency-path: desktop/go.sum id: go - - name: Check out code into the Go module directory - uses: actions/checkout@v4 - with: - repository: maputnik/desktop - ref: master - path: ./src/github.com/maputnik/desktop/ - - - name: Make - run: cd src/github.com/maputnik/desktop/ && make + - name: Build desktop artifacts + run: npm run build-desktop - name: Artifacts/linux - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik-linux - path: ./src/github.com/maputnik/desktop/bin/linux/ + path: ./desktop/bin/linux/ - name: Artifacts/darwin - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik-darwin - path: ./src/github.com/maputnik/desktop/bin/darwin/ + path: ./desktop/bin/darwin/ - name: Artifacts/windows - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik-windows - path: ./src/github.com/maputnik/desktop/bin/windows/ + path: ./desktop/bin/windows/ e2e-tests: name: "E2E tests using ${{ matrix.browser }}" diff --git a/.github/workflows/create-bump-version-pr.yml b/.github/workflows/create-bump-version-pr.yml new file mode 100644 index 00000000..468b5b1f --- /dev/null +++ b/.github/workflows/create-bump-version-pr.yml @@ -0,0 +1,39 @@ +name: Create bump version PR + +on: + workflow_dispatch: + inputs: + version: + description: Version to change to. + required: true + type: string + +jobs: + bump-version-pr: + name: Bump version PR + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Bump version + run: | + npm version --commit-hooks false --git-tag-version false ${{ inputs.version }} + ./build/bump-version-changelog.js ${{ inputs.version }} + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 + with: + commit-message: Bump version to ${{ inputs.version }} + branch: bump-version-to-${{ inputs.version }} + title: Bump version to ${{ inputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..3449477c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,104 @@ +name: Release + +on: + push: + branches: [main] + workflow_dispatch: + +jobs: + release-check: + name: Check if version changed + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Check if version has been updated + id: check + uses: EndBug/version-check@v2 + + outputs: + publish: ${{ steps.check.outputs.changed }} + + release: + name: Release + needs: release-check + if: ${{ needs.release-check.outputs.publish == 'true' }} + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" + + - name: Set up Go for desktop build + uses: actions/setup-go@v5 + with: + go-version: ^1.23.x + cache-dependency-path: desktop/go.sum + id: go + + - name: Get version + id: package-version + uses: martinbeentjes/npm-get-version-action@v1.3.1 + + - name: Install + run: npm ci + + - name: Build + run: | + npm run build + npm run build-desktop + + - name: Tag commit and push + id: tag_version + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + custom_tag: ${{ steps.package-version.outputs.current-version }} + + - name: Create Archives + run: | + zip -r dist dist + zip -r desktop desktop/bin/ + + - name: Build Release Notes + id: release_notes + run: | + RELEASE_NOTES_PATH="${PWD}/release_notes.txt" + ./build/release-notes.js > ${RELEASE_NOTES_PATH} + echo "release_notes=${RELEASE_NOTES_PATH}" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + id: create_regular_release + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag: ${{ steps.tag_version.outputs.new_tag }} + name: ${{ steps.tag_version.outputs.new_tag }} + bodyFile: ${{ steps.release_notes.outputs.release_notes }} + artifacts: "dist.zip,desktop.zip" + allowUpdates: true + draft: false + prerelease: false + diff --git a/.gitignore b/.gitignore index d465cc0c..7fef4e63 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,6 @@ node_modules public /errorShots /old -/build /cypress/screenshots /dist/ +/desktop/version.go diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..e21613ad --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +## main + +### ✨ Features and improvements +- Add GitHub workflows for releasing new versions +- Update desktop build to pull from this repo (#922) +- _...Add new stuff here..._ + +### 🐞 Bug fixes +- _...Add new stuff here..._ + +## 2.0.0 +- Update MapLibre to version 4 (#872) + +## 1.7.0 +- See release notes at https://maputnik.github.io/blog/2020/04/23/release-v1.7.0 + diff --git a/README.md b/README.md index cc7bae53..9970de51 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,16 @@ You can also see the tests as they run or select which suites to run by executin npm run cy:open ``` +## Release process + +1. Review [`CHANGELOG.md`](/CHANGELOG.md) + - Double-check that all changes included in the release are appropriately documented. + - To-be-released changes should be under the "main" header. + - Commit any final changes to the changelog. +2. Run [Create bump version PR](https://github.com/maplibre/maputnik/actions/workflows/create-bump-version-pr.yml) by manual workflow dispatch and set the version number in the input. This will create a PR that changes the changelog and `package.json` file to review and merge. +3. Once merged, an automatic process will kick in and creates a GitHub release and uploads release assets. + + ## Sponsors Thanks to the supporters of the **[Kickstarter campaign](https://www.kickstarter.com/projects/174808720/maputnik-visual-map-editor-for-mapbox-gl)**. This project would not be possible without these commercial and individual sponsors. diff --git a/build/README.md b/build/README.md new file mode 100644 index 00000000..9cf562fc --- /dev/null +++ b/build/README.md @@ -0,0 +1,11 @@ +# Build Scripts + +This folder holds common build scripts used by some of the Github workflows. + +The scripts are borrowed from [maplibre/maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js/tree/bc70bc559cea5c987fa1b79fd44766cef68bbe28/build). + +## Generate Release Notes + +`bump-version-changelog.js` Used to update the changelog with the current notes, and set up a space for new notes + +`release-notes.js` Used to generate release notes when releasing a new version diff --git a/build/bump-version-changelog.js b/build/bump-version-changelog.js new file mode 100644 index 00000000..1c9795b8 --- /dev/null +++ b/build/bump-version-changelog.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +/** + * This script updates the changelog.md file with the version given in the arguments + * It replaces ## main with ## + * Removes _...Add new stuff here..._ + * And adds on top a ## main with add stuff here. + * + * Copied from maplibre/maplibre-gl-js + * https://github.com/maplibre/maplibre-gl-js/blob/bc70bc559cea5c987fa1b79fd44766cef68bbe28/build/release-notes.js + */ + +import * as fs from 'fs'; + +const changelogPath = 'CHANGELOG.md'; +let changelog = fs.readFileSync(changelogPath, 'utf8'); +changelog = changelog.replace('## main', `## ${process.argv[2]}`); +changelog = changelog.replaceAll('- _...Add new stuff here..._\n', ''); +changelog = `## main + +### ✨ Features and improvements +- _...Add new stuff here..._ + +### 🐞 Bug fixes +- _...Add new stuff here..._ + +` + changelog; + +fs.writeFileSync(changelogPath, changelog, 'utf8'); diff --git a/build/release-notes.js b/build/release-notes.js new file mode 100644 index 00000000..1d169954 --- /dev/null +++ b/build/release-notes.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node + +// Copied from maplibre/maplibre-gl-js +// https://github.com/maplibre/maplibre-gl-js/blob/bc70bc559cea5c987fa1b79fd44766cef68bbe28/build/release-notes.js + +import * as fs from 'fs'; + +const changelogPath = 'CHANGELOG.md'; +const changelog = fs.readFileSync(changelogPath, 'utf8'); + +/* + Parse the raw changelog text and split it into individual releases. + + This regular expression: + - Matches lines starting with "## x.x.x". + - Groups the version number. + - Skips the (optional) release date. + - Groups the changelog content. + - Ends when another "## x.x.x" is found. +*/ +const regex = /^## (\d+\.\d+\.\d+.*?)\n(.+?)(?=\n^## \d+\.\d+\.\d+.*?\n)/gms; + +let releaseNotes = []; +let match; +// eslint-disable-next-line no-cond-assign +while (match = regex.exec(changelog)) { + releaseNotes.push({ + 'version': match[1], + 'changelog': match[2].trim(), + }); +} + +const latest = releaseNotes[0]; +const previous = releaseNotes[1]; + +// Print the release notes template. + +let header = 'Changes since previous version' +if (previous) { + header = `https://github.com/maplibre/maputnik + [Changes](https://github.com/maplibre/maputnik/compare/v${previous.version}...v${latest.version}) since [Maputnik v${previous.version}](https://github.com/maplibre/maputnik/releases/tag/v${previous.version})` +} +const templatedReleaseNotes = `${header} + +${latest.changelog} + +// eslint-disable-next-line eol-last +process.stdout.write(templatedReleaseNotes.trimEnd()); diff --git a/desktop/Makefile b/desktop/Makefile index 140d9d6b..d7984937 100644 --- a/desktop/Makefile +++ b/desktop/Makefile @@ -1,21 +1,21 @@ SOURCEDIR=. SOURCES := $(shell find $(SOURCEDIR) -name '*.go') BINARY=maputnik -EDITOR_VERSION ?= v1.7.0 +DESKTOP_VERSION := 1.1.1 +EDITOR_VERSION := $(shell node -p "require('../package.json').version") GOPATH := $(if $(GOPATH),$(GOPATH),$(HOME)/go) GOBIN := $(if $(GOBIN),$(GOBIN),$(HOME)/go/bin) all: $(BINARY) -$(BINARY): $(GOBIN)/gox $(SOURCES) rice-box.go +$(BINARY): $(GOBIN)/gox $(SOURCES) version.go rice-box.go $(GOBIN)/gox -osarch "windows/amd64 linux/amd64 darwin/amd64" -output "bin/{{.OS}}/${BINARY}" -editor/create_folder: +# Copy the current release into ./editor/maputnik so it can be +# embedded in the binary +editor/pull_release: mkdir -p editor - -editor/pull_release: editor/create_folder - # if the directory /home/runner/work/editor/editor/build/build exists, we assume that we are are running the makefile within the editor ci workflow - test -d /home/runner/work/editor/editor/build/build && echo "exists" && cd editor && cp -R /home/runner/work/editor/editor/build/build public/ || (echo "does not exist" && cd editor && rm -rf public && curl -L https://github.com/maputnik/editor/releases/download/$(EDITOR_VERSION)/public.zip --output public.zip && unzip public.zip && rm public.zip) + cp -r ../dist/* editor $(GOBIN)/gox: go install github.com/mitchellh/gox@v1.0.1 @@ -23,9 +23,17 @@ $(GOBIN)/gox: $(GOBIN)/rice: go install github.com/GeertJohan/go.rice/rice@v1.0.3 +# Embed the current version numbers in the executable by writing version.go +.PHONY: version.go +version.go: + @echo "// DO NOT EDIT: Autogenerated by Makefile\n" > version.go + @echo "package main\n" >> version.go + @echo "const DesktopVersion = \"$(DESKTOP_VERSION)\"" >> version.go + @echo "const EditorVersion = \"$(EDITOR_VERSION)\"" >> version.go + rice-box.go: $(GOBIN)/rice editor/pull_release $(GOBIN)/rice embed-go .PHONY: clean clean: - rm -rf editor/public && rm -f rice-box.go && rm -rf bin + rm -rf editor && rm -f rice-box.go && rm -rf bin diff --git a/desktop/README.md b/desktop/README.md index b6b8baa6..e7592721 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -1,18 +1,17 @@ -# Maputnik Desktop [![GitHub CI status](https://github.com/maputnik/desktop/workflows/ci/badge.svg)](https://github.com/maputnik/desktop/actions?query=workflow%3Aci) - +# Maputnik Desktop [![GitHub CI status](https://github.com/maplibre/maputnik/workflows/ci/badge.svg)][github-action-ci] --- A Golang based cross platform executable for integrating Maputnik locally. -This binary packages up the JavaScript and CSS bundle produced by [maputnik/editor](https://github.com/maputnik/desktop) +This binary packages up the JavaScript and CSS bundle produced by maputnik and embeds it in the program for easy distribution. It also allows exposing a local style file and work on it both in Maputnik and with your favorite editor. -Report issues on [maputnik/editor](https://github.com/maputnik/editor). +Report issues on [maplibre/maputnik](https://github.com/maplibre/maputnik). ## Install -You can download a single binary for Linux, OSX or Windows from [the latest releases of **maputnik/editor**](https://github.com/maputnik/editor/releases/latest). +You can download a single binary for Linux, OSX or Windows from [the latest releases of **maplibre/maputnik**](https://github.com/maplibre/maputnik/editor/releases/latest). ### Usage @@ -63,16 +62,11 @@ maputnik --static ./localFolder ### Build -Clone the repository. Make sure you clone it into the correct directory `$GOPATH/src/github.com/maputnik`. +From the root of the [maplibre/maputnik](https://github.com/maplibre/maputnik) project, install the deps and run the desktop-build command. ``` -git clone git@github.com:maputnik/desktop.git -``` - -Run `make` to install the 3rd party dependencies and build the `maputnik` binary embedding the editor. - -``` -make +npm install +npm run build-desktop ``` You should now find the `maputnik` binary in your `bin` directory. diff --git a/desktop/maputnik.go b/desktop/maputnik.go index 1442cb44..543b1e19 100644 --- a/desktop/maputnik.go +++ b/desktop/maputnik.go @@ -17,7 +17,7 @@ func main() { app := cli.NewApp() app.Name = "maputnik" app.Usage = "Server for integrating Maputnik locally" - app.Version = "Editor: 1.7.0; Desktop: 1.1.0" + app.Version = "Editor: " + EditorVersion + "; Desktop: " + DesktopVersion app.Flags = []cli.Flag{ &cli.StringFlag{ @@ -40,7 +40,7 @@ func main() { } app.Action = func(c *cli.Context) error { - gui := http.FileServer(rice.MustFindBox("editor/public").HTTPBox()) + gui := http.FileServer(rice.MustFindBox("editor").HTTPBox()) router := mux.NewRouter().StrictSlash(true) diff --git a/package.json b/package.json index 9556b3d3..73eabc62 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "scripts": { "start": "vite", "build": "tsc && vite build --base=/maputnik/", + "build-desktop": "tsc && vite build --base=/ && cd desktop && make", "i18n:refresh": "i18next 'src/**/*.{ts,tsx,js,jsx}'", "lint": "eslint ./src ./cypress --ext ts,tsx,js,jsx --report-unused-disable-directives --max-warnings 0", "test": "cypress run",