Compare commits

...

31 Commits

Author SHA1 Message Date
Brandon Currell
44bc4b7fa4 🐳 Add missing package in the exporter Docker image (#7026)
penpot-exporter requires poppler-utils for exporting to a PDF, but it is missing.
Added the package to the Dockerfile in the RUN section where dependencies are
being installed.

Signed-off-by: Brandon Currell <brandon+git@currell.pw>
2025-08-01 13:00:51 +02:00
Yamila Moreno
5c14f486d7 🐳 Update Imagemagick version 2025-08-01 12:49:11 +02:00
Andrey Antukh
0cbd980b68 🎉 Add imagemagick docker image build scripts (#6925)
* 🎉 Add imagemagick docker image build scripts

* 📎 Add PR feedback changes
2025-08-01 12:48:47 +02:00
Andrey Antukh
2e726b62c3 📎 Update changelog 2025-07-29 20:07:05 +02:00
Andrey Antukh
b68c426cd1 🐛 Fix exception on fills menu when binary-fills flag is active
And multiple shapes are selected.
2025-07-29 15:10:32 +02:00
Andrey Antukh
d00de7d5a4 Merge pull request #6960 from penpot/xaviju-remove-image-shape-type-fix
🐛 Remove image type from inspect tab panels
2025-07-25 12:49:57 +02:00
Xaviju
2fbd4b07e0 🐛 Remove image type from inspect tab panels 2025-07-25 12:08:01 +02:00
Andrey Antukh
523373dfa2 📎 Update .gitignore file 2025-07-23 12:09:15 +02:00
Andrey Antukh
b71ec4bfe0 Simplify docker build script (#6924) 2025-07-21 20:45:03 +02:00
Andrey Antukh
51107c3fc9 🐛 Fix incorrect event name on event constructor 2025-07-21 11:58:48 +02:00
Alejandro Alonso
abef9f3cf7 Merge pull request #6889 from penpot/niwinz-staging-bugfix
🐛 Fix unexpected exception on processing old texts
2025-07-14 07:08:31 +02:00
Andrey Antukh
40c300fa1a 🐛 Fix unexpected exception on processing old texts 2025-07-10 09:22:00 +02:00
Alejandro Alonso
5b704faf79 Merge pull request #6862 from penpot/niwinz-develop-minor-fixes
 Add several improvements
2025-07-07 15:40:20 +02:00
Andrey Antukh
d24eab7241 📎 Update changelog 2025-07-07 15:07:07 +02:00
Andrey Antukh
c8fef97598 Add missing field on get-teams rpc method 2025-07-07 13:36:00 +02:00
Andrey Antukh
44e3e4a641 🔥 Remove image shape inspect pannel
Image shapes are long ago deprecated not used
on penpot
2025-07-07 13:36:00 +02:00
Andrey Antukh
f3616c68a0 Improve decode empty string for path content 2025-07-07 13:36:00 +02:00
Andrey Antukh
9ea3f81bc4 🐛 Clean invalid library colors 2025-07-07 13:35:59 +02:00
Alonso Torres
accd5226d7 🐛 Fix sidebar width in localhost (#6732) 2025-07-07 09:28:52 +02:00
Andrey Antukh
16a1fd14e5 🐛 Fix media translation on text nodes on paste (#6845)
Fix incorrect media translation on paste text with fill images
2025-07-07 09:03:35 +02:00
Aitor Moreno
824bb19c7e Merge pull request #6848 from penpot/niwinz-staging-library-referer
 Add referer field to binfile v3
2025-07-07 09:02:13 +02:00
Aitor Moreno
d0f3e0f0b0 Merge pull request #6853 from penpot/niwinz-staging-path-bool-fixes
🐛 Fix exception on a corner case of creating bool shape
2025-07-07 09:00:57 +02:00
Andrey Antukh
43ba2b05e8 📎 Change current config values for error report explain 2025-07-04 14:51:08 +02:00
Andrey Antukh
d5ccb704b2 🐛 Fix unexpected exception on creating bool shapes 2025-07-04 14:42:09 +02:00
David Barragán Merino
6d21fcc9de 🔧 Fix condition for automatic events (#6849) 2025-07-04 11:57:57 +02:00
Andrey Antukh
77741b49a7 Add tracking for referer on the import-binfile 2025-07-04 11:02:36 +02:00
Andrey Antukh
a7e0cfc609 🎉 Bump 1.0.7 release of the penpot library
Includes the ability to pass referer
2025-07-04 11:02:36 +02:00
Andrey Antukh
50a6355537 🎉 Add options for creating library build context
With the ability to pass referer.
2025-07-04 11:02:36 +02:00
Alejandro Alonso
264aef277d Merge pull request #6847 from penpot/niwinz-staging-error-reports-2
 Add minor improvements to error report on calc bool content
2025-07-04 10:53:02 +02:00
Andrey Antukh
78d0e6d059 Add minor improvements to error report on calc bool content 2025-07-04 10:13:24 +02:00
Alonso Torres
6d41d36b3a 🐛 Fix problem when double click on hidden shapes (#6833) 2025-07-04 09:01:20 +02:00
34 changed files with 469 additions and 267 deletions

View File

@@ -15,6 +15,7 @@ on:
# zip_mode defines how the build artifacts are packaged:
# - 'individual': creates one ZIP file per component (frontend, backend, exporter)
# - 'all': creates a single ZIP containing all components
# - null: for the rest of cases (non-manual events)
description: 'Bundle packaging mode'
required: false
default: 'individual'
@@ -62,8 +63,8 @@ jobs:
echo "📦 Packaging Penpot 'all' bundles..."
zip -r zips/penpot-all-bundles.zip penpot
- name: Create zip bundles for zip_mode == 'individual'
if: ${{ github.event.inputs.zip_mode == 'individual' }}
- name: Create zip bundles for zip_mode != 'all'
if: ${{ github.event.inputs.zip_mode != 'all' }}
run: |
echo "📦 Packaging Penpot 'individual' bundles..."
zip -r zips/penpot-frontend.zip penpot/frontend
@@ -78,7 +79,7 @@ jobs:
path: zips/penpot-all-bundles.zip
- name: Upload individual bundles
if: ${{ github.event.inputs.zip_mode == 'individual' }}
if: ${{ github.event.inputs.zip_mode != 'all' }}
uses: actions/upload-artifact@v4
with:
name: penpot-individual-bundles
@@ -94,7 +95,7 @@ jobs:
aws s3 cp zips/penpot-all-bundles.zip s3://${{ secrets.S3_BUCKET }}/penpot-all-bundles-${{ steps.vars.outputs.commit_hash }}.zip
- name: Upload 'individual' bundles to S3
if: ${{ github.event.inputs.zip_mode == 'individual' }}
if: ${{ github.event.inputs.zip_mode != 'all' }}
run: |
for name in penpot-frontend penpot-backend penpot-exporter; do
aws s3 cp zips/${name}.zip s3://${{ secrets.S3_BUCKET }}/${name}-${{ steps.vars.outputs.gh_branch }}-latest.zip

6
.gitignore vendored
View File

@@ -41,6 +41,7 @@
/backend/resources/public/assets
/backend/resources/public/media
/backend/target/
/backend/experiments
/bundle*
/cd.md
/clj-profiler/
@@ -51,9 +52,6 @@
/exporter/target
/frontend/.storybook/preview-body.html
/frontend/.storybook/preview-head.html
/frontend/cypress/fixtures/validuser.json
/frontend/cypress/videos/*/
/frontend/cypress/videos/*/
/frontend/dist/
/frontend/npm-debug.log
/frontend/out/
@@ -70,6 +68,8 @@
/vendor/svgclean/bundle*.js
/web
/library/target/
/library/*.zip
/external
clj-profiler/
node_modules

View File

@@ -1,6 +1,15 @@
# CHANGELOG
## 2.8.0 (Next / Unreleased)
## 2.8.1
### :bug: Bugs fixed
- Fix unexpected exception on processing old texts [Github #6889](https://github.com/penpot/penpot/pull/6889)
- Fix error on inspect tab when selecting multiple shapes [Taiga #11655](https://tree.taiga.io/project/penpot/issue/11655)
- Fix missing package for the penport_exporter Docker image [GitHub #7205](https://github.com/penpot/penpot/issues/7025)
## 2.8.0
### :rocket: Epics and highlights
@@ -15,8 +24,8 @@ on [its own changelog](library/CHANGES.md)
**Penpot migrate from Redis to Valkey**
As [Valkey](https://valkey.io/) is an opne-souce fork of [Redis](https://redis.io/)
version 7.2.4, this version of Penpot will be compatible with Redis but may diverge
in future versions. Therefore, **migration from Redis to ValKey is recommended for all
version 7.2.4, this version of Penpot will be compatible with Redis but may diverge
in future versions. Therefore, **migration from Redis to ValKey is recommended for all
on-premises instances** that want to keep up to date.
### :heart: Community contributions (Thank you!)
@@ -39,6 +48,7 @@ on-premises instances** that want to keep up to date.
- Update google fonts (at 2025/05/19) [Taiga 10792](https://tree.taiga.io/project/penpot/us/10792)
- Add tooltip component to DS [Taiga 9220](https://tree.taiga.io/project/penpot/us/9220)
- Allow multi file token export [Taiga #10144](https://tree.taiga.io/project/penpot/us/10144)
- Fix problem when double click on hidden shapes [Taiga #11314](https://tree.taiga.io/project/penpot/issue/11314)
### :bug: Bugs fixed
@@ -62,6 +72,7 @@ on-premises instances** that want to keep up to date.
- Fix entering long project name [Taiga #11417](https://tree.taiga.io/project/penpot/issue/11417)
- Fix slow color picker [Taiga #11019](https://tree.taiga.io/project/penpot/issue/11019)
- Fix tooltip position after click [Taiga #11405](https://tree.taiga.io/project/penpot/issue/11405)
- Fix incorrect media translation on paste text with fill images [Github #6845](https://github.com/penpot/penpot/pull/6845)
## 2.7.2

View File

@@ -12,7 +12,6 @@
[app.binfile.common :as bfc]
[app.binfile.migrations :as bfm]
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.features :as cfeat]
[app.common.files.migrations :as-alias fmg]
@@ -54,7 +53,7 @@
[:map {:title "Manifest"}
[:version ::sm/int]
[:type :string]
[:referer {:optional true} :string]
[:generated-by {:optional true} :string]
[:files
@@ -373,6 +372,7 @@
params {:type "penpot/export-files"
:version 1
:generated-by (str "penpot/" (:full cf/version))
:refer "penpot"
:files (vec (vals files))
:relations rels}]
(write-entry! output "manifest.json" params))))
@@ -878,13 +878,8 @@
(defn- import-files
[{:keys [::bfc/timestamp ::bfc/input ::bfc/name] :or {timestamp (dt/now)} :as cfg}]
(dm/assert!
"expected zip file"
(instance? ZipFile input))
(dm/assert!
"expected valid instant"
(dt/instant? timestamp))
(assert (instance? ZipFile input) "expected zip file")
(assert (dt/instant? timestamp) "expected valid instant")
(let [manifest (-> (read-manifest input)
(validate-manifest))
@@ -896,6 +891,7 @@
:hint "unexpected type on manifest"
:manifest manifest))
;; Check if all files referenced on manifest are present
(doseq [{file-id :id features :features} (:files manifest)]
(let [path (str "files/" file-id ".json")]
@@ -956,14 +952,13 @@
[{:keys [::bfc/ids] :as cfg} output]
(dm/assert!
"expected a set of uuid's for `::bfc/ids` parameter"
(and (set? ids)
(every? uuid? ids)))
(assert
(and (set? ids) (every? uuid? ids))
"expected a set of uuid's for `::bfc/ids` parameter")
(dm/assert!
"expected instance of jio/IOFactory for `input`"
(satisfies? jio/IOFactory output))
(assert
(satisfies? jio/IOFactory output)
"expected instance of jio/IOFactory for `input`")
(let [id (uuid/next)
tp (dt/tpoint)
@@ -1002,14 +997,14 @@
(defn import-files!
[{:keys [::bfc/input] :as cfg}]
(dm/assert!
"expected valid profile-id and project-id on `cfg`"
(assert
(and (uuid? (::bfc/profile-id cfg))
(uuid? (::bfc/project-id cfg))))
(uuid? (::bfc/project-id cfg)))
"expected valid profile-id and project-id on `cfg`")
(dm/assert!
"expected instance of jio/IOFactory for `input`"
(io/coercible? input))
(assert
(io/coercible? input)
"expected instance of jio/IOFactory for `input`")
(let [id (uuid/next)
tp (dt/tpoint)
@@ -1029,3 +1024,9 @@
:id (str id)
:elapsed (dt/format-duration (tp))
:error? (some? @cs))))))
(defn get-manifest
[path]
(with-open [input (ZipFile. (fs/file path))]
(-> (read-manifest input)
(validate-manifest))))

View File

@@ -67,7 +67,7 @@
(some-> cause (ex/format-throwable :data? true :explain? false :header? false :summary? false)))}
(when-let [params (or (:request/params context) (:params context))]
{:params (pp/pprint-str params :length 20 :level 15)})
{:params (pp/pprint-str params :length 20 :level 20)})
(when-let [value (:value context)]
{:value (pp/pprint-str value :length 30 :level 13)})

View File

@@ -134,11 +134,18 @@
::webhooks/event? true
::sse/stream? true
::sm/params schema:import-binfile}
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id project-id version] :as params}]
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id project-id version file] :as params}]
(projects/check-edition-permissions! pool profile-id project-id)
(let [params (-> params
(assoc :profile-id profile-id)
(assoc :version (or version 1)))]
(let [version (or version 1)
params (-> params
(assoc :profile-id profile-id)
(assoc :version version))
manifest (case (int version)
1 nil
3 (bf.v3/get-manifest (:path file)))]
(with-meta
(sse/response (partial import-binfile cfg params))
{::audit/props {:file nil}})))
{::audit/props {:file nil
:generated-by (:generated-by manifest)
:referer (:referer manifest)}})))

View File

@@ -139,7 +139,8 @@
'~:status', CASE COALESCE(p.props->'~:subscription'->>'~:type', 'professional')
WHEN 'professional' THEN 'active'
ELSE COALESCE(p.props->'~:subscription'->>'~:status', 'incomplete')
END
END,
'~:seats', p.props->'~:quantity'
) AS subscription
FROM team_profile_rel AS tp
JOIN team AS t ON (t.id = tp.team_id)

View File

@@ -1019,8 +1019,8 @@
[data _]
(let [update-colors
(fn [colors]
(into {} (filter #(-> % val types.color/valid-color?) colors)))]
(update data :colors update-colors)))
(into {} (filter #(-> % val types.color/valid-library-color?) colors)))]
(d/update-when data :colors update-colors)))
(defmethod migrate-data "legacy-52"
[data _]
@@ -1034,7 +1034,6 @@
(update data :pages-index d/update-vals update-page)))
(defmethod migrate-data "legacy-53"
[data _]
(migrate-data data "legacy-26"))
@@ -1517,6 +1516,17 @@
(d/update-when data :colors d/update-vals clear-color)))
(defmethod migrate-data "0009-clean-library-colors"
[data _]
(d/update-when data :colors
(fn [colors]
(reduce-kv (fn [colors id color]
(if (types.color/valid-library-color? color)
colors
(dissoc colors id)))
colors
colors))))
(def available-migrations
(into (d/ordered-set)
["legacy-2"
@@ -1580,4 +1590,5 @@
"0005-deprecate-image-type"
"0006-fix-old-texts-fills"
"0007-clear-invalid-strokes-and-fills-v2"
"0008-fix-library-colors-v4"]))
"0008-fix-library-colors-v4"
"0009-clean-library-colors"]))

View File

@@ -170,19 +170,6 @@
item))
root)))
(defn xform-nodes
"The same as transform but instead of receiving a funcion, receives
a transducer."
[xf root]
(let [rf (fn [_ v] v)]
(walk/postwalk
(fn [item]
(let [rf (xf rf)]
(if (is-node? item)
(d/nilv (rf nil item) item)
item)))
root)))
(defn update-text-content
[shape pred-fn update-fn attrs]
(let [update-attrs-fn #(update-fn % attrs)

View File

@@ -117,6 +117,7 @@
[:ref-id {:optional true} ::sm/uuid]
[:ref-file {:optional true} ::sm/uuid]])
;; This schema represent an "applied color"
(def schema:color
[:and
[:merge {:title "Color"}

View File

@@ -200,24 +200,25 @@
contents
(sequence extract-content-xf (:shapes shape))]
(bool/calculate-content (:bool-type shape) contents)))
(ex/try!
(bool/calculate-content (:bool-type shape) contents)
:on-exception
(fn [cause]
(ex/raise :type :internal
:code :invalid-path-content
:hint (str "unable to calculate bool content for shape " (:id shape))
:shapes (:shapes shape)
:type (:bool-type shape)
:content (vec contents)
:cause cause)))))
(defn calc-bool-content
"Calculate the boolean content from shape and objects. Returns a
packed PathData instance"
[shape objects]
(ex/try!
(-> (calc-bool-content* shape objects)
(impl/path-data))
:on-exception
(fn [cause]
(ex/raise :type :internal
:code :invalid-path-content
:hint (str "unable to create bool content for shape " (:id shape))
:content (str (:content shape))
:shape-id (:id shape)
:cause cause))))
(-> (calc-bool-content* shape objects)
(impl/path-data)))
(defn update-bool-shape
"Calculates the selrect+points for the boolean shape"

View File

@@ -27,13 +27,11 @@
(defn make-move-to [to]
{:command :move-to
:relative false
:params {:x (:x to)
:y (:y to)}})
(defn make-line-to [to]
{:command :line-to
:relative false
:params {:x (:x to)
:y (:y to)}})
@@ -65,7 +63,6 @@
(defn make-curve-to
[to h1 h2]
{:command :curve-to
:relative false
:params (make-curve-params to h1 h2)})
(defn prefix->coords [prefix]
@@ -98,7 +95,7 @@
(defn segment->point
([segment] (segment->point segment :x))
([segment coord]
(when-let [params (get segment :params)]
(when-let [params (not-empty (get segment :params))]
(case coord
:c1 (gpt/point (get params :c1x)
(get params :c1y))

View File

@@ -20,7 +20,8 @@
[app.common.schema.generators :as sg]
[app.common.svg.path :as svg.path]
[app.common.transit :as t]
[app.common.types.path :as-alias path])
[app.common.types.path :as-alias path]
[cuerdas.core :as str])
(:import
#?(:cljs [goog.string StringBuffer]
:clj [java.nio ByteBuffer ByteOrder])))
@@ -530,7 +531,9 @@
:decode/json (fn [s]
(cond
(string? s)
(from-string s)
(if (str/empty? s)
(from-plain [])
(from-string s))
(vector? s)
(let [decode-fn (deref decoder)]

View File

@@ -14,6 +14,7 @@
[app.common.pprint :as pp]
[app.common.transit :as trans]
[app.common.types.path :as path]
[app.common.types.path.bool :as path.bool]
[app.common.types.path.helpers :as path.helpers]
[app.common.types.path.impl :as path.impl]
[app.common.types.path.segment :as path.segment]
@@ -414,3 +415,89 @@
result1 (get-handlers sample-content-large)
result2 (path.segment/get-handlers content)]
(t/is (= result1 result2))))
(def contents-for-bool
[[{:command :move-to, :params {:x 1682.9000244140625, :y 48.0}}
{:command :line-to, :params {:x 1682.9000244140625, :y 44.0}}
{:command :curve-to, :params {:x 1683.9000244140625, :y 43.0, :c1x 1682.9000244140625, :c1y 43.400001525878906, :c2x 1683.300048828125, :c2y 43.0}}
{:command :line-to, :params {:x 1687.9000244140625, :y 43.0}}
{:command :curve-to, :params {:x 1688.9000244140625, :y 44.0, :c1x 1688.5, :c1y 43.0, :c2x 1688.9000244140625, :c2y 43.400001525878906}}
{:command :line-to, :params {:x 1688.9000244140625, :y 48.0}}
{:command :curve-to, :params {:x 1687.9000244140625, :y 49.0, :c1x 1688.9000244140625, :c1y 48.599998474121094, :c2x 1688.5, :c2y 49.0}}
{:command :line-to, :params {:x 1683.9000244140625, :y 49.0}}
{:command :curve-to, :params {:x 1682.9000244140625, :y 48.0, :c1x 1683.300048828125, :c1y 49.0, :c2x 1682.9000244140625, :c2y 48.599998474121094}}
{:command :close-path, :params {}}
{:command :close-path, :params {}}
{:command :move-to, :params {:x 1684.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1684.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1686.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1686.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1684.9000244140625, :y 45.0}}
{:command :close-path, :params {}}
{:command :close-path, :params {}}]
[{:command :move-to, :params {:x 1672.9000244140625, :y 48.0}}
{:command :line-to, :params {:x 1672.9000244140625, :y 44.0}}
{:command :curve-to, :params {:x 1673.9000244140625, :y 43.0, :c1x 1672.9000244140625, :c1y 43.400001525878906, :c2x 1673.300048828125, :c2y 43.0}}
{:command :line-to, :params {:x 1677.9000244140625, :y 43.0}}
{:command :curve-to, :params {:x 1678.9000244140625, :y 44.0, :c1x 1678.5, :c1y 43.0, :c2x 1678.9000244140625, :c2y 43.400001525878906}}
{:command :line-to, :params {:x 1678.9000244140625, :y 48.0}}
{:command :curve-to, :params {:x 1677.9000244140625, :y 49.0, :c1x 1678.9000244140625, :c1y 48.599998474121094, :c2x 1678.5, :c2y 49.0}}
{:command :line-to, :params {:x 1673.9000244140625, :y 49.0}}
{:command :curve-to, :params {:x 1672.9000244140625, :y 48.0, :c1x 1673.300048828125, :c1y 49.0, :c2x 1672.9000244140625, :c2y 48.599998474121094}}
{:command :close-path, :params {}}
{:command :close-path, :params {}}
{:command :move-to, :params {:x 1674.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1674.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1676.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1676.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1674.9000244140625, :y 45.0}}
{:command :close-path, :params {}}
{:command :close-path, :params {}}]])
(def bool-result
[{:command :move-to, :params {:x 1682.9000244140625, :y 48.0}}
{:command :line-to, :params {:x 1682.9000244140625, :y 44.0}}
{:command :curve-to,
:params
{:x 1683.9000244140625, :y 43.0, :c1x 1682.9000244140625, :c1y 43.400001525878906, :c2x 1683.300048828125, :c2y 43.0}}
{:command :line-to, :params {:x 1687.9000244140625, :y 43.0}}
{:command :curve-to,
:params {:x 1688.9000244140625, :y 44.0, :c1x 1688.5, :c1y 43.0, :c2x 1688.9000244140625, :c2y 43.400001525878906}}
{:command :line-to, :params {:x 1688.9000244140625, :y 48.0}}
{:command :curve-to,
:params {:x 1687.9000244140625, :y 49.0, :c1x 1688.9000244140625, :c1y 48.599998474121094, :c2x 1688.5, :c2y 49.0}}
{:command :line-to, :params {:x 1683.9000244140625, :y 49.0}}
{:command :curve-to,
:params
{:x 1682.9000244140625, :y 48.0, :c1x 1683.300048828125, :c1y 49.0, :c2x 1682.9000244140625, :c2y 48.599998474121094}}
{:command :move-to, :params {:x 1684.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1684.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1686.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1686.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1684.9000244140625, :y 45.0}}
{:command :move-to, :params {:x 1672.9000244140625, :y 48.0}}
{:command :line-to, :params {:x 1672.9000244140625, :y 44.0}}
{:command :curve-to,
:params
{:x 1673.9000244140625, :y 43.0, :c1x 1672.9000244140625, :c1y 43.400001525878906, :c2x 1673.300048828125, :c2y 43.0}}
{:command :line-to, :params {:x 1677.9000244140625, :y 43.0}}
{:command :curve-to,
:params {:x 1678.9000244140625, :y 44.0, :c1x 1678.5, :c1y 43.0, :c2x 1678.9000244140625, :c2y 43.400001525878906}}
{:command :line-to, :params {:x 1678.9000244140625, :y 48.0}}
{:command :curve-to,
:params {:x 1677.9000244140625, :y 49.0, :c1x 1678.9000244140625, :c1y 48.599998474121094, :c2x 1678.5, :c2y 49.0}}
{:command :line-to, :params {:x 1673.9000244140625, :y 49.0}}
{:command :curve-to,
:params
{:x 1672.9000244140625, :y 48.0, :c1x 1673.300048828125, :c1y 49.0, :c2x 1672.9000244140625, :c2y 48.599998474121094}}
{:command :move-to, :params {:x 1674.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1674.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1676.9000244140625, :y 47.0}}
{:command :line-to, :params {:x 1676.9000244140625, :y 45.0}}
{:command :line-to, :params {:x 1674.9000244140625, :y 45.0}}])
(t/deftest calculate-bool-content
(let [result (path.bool/calculate-content :union contents-for-bool)]
(t/is (= result bool-result))))

View File

@@ -0,0 +1,91 @@
FROM ubuntu:24.04
LABEL maintainer="Penpot <docker@penpot.app>"
ENV LANG='C.UTF-8' \
LC_ALL='C.UTF-8' \
DEBIAN_FRONTEND=noninteractive \
TZ=Etc/UTC
ARG IMAGEMAGICK_VERSION=7.1.1-47
RUN set -e; \
apt-get -qq update; \
apt-get -qq upgrade; \
apt-get -qqy --no-install-recommends install \
autoconf \
binutils \
build-essential \
ca-certificates \
curl \
libfftw3-dev \
libheif-dev \
libjpeg-dev \
liblcms2-dev \
libltdl-dev \
liblzma-dev \
libopenexr-dev \
libpng-dev \
librsvg2-dev \
libtiff-dev \
libtool \
libwebp-dev \
libzip-dev \
libzstd-dev \
pkg-config \
; \
curl -LfsSo /tmp/magick.tar.gz https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IMAGEMAGICK_VERSION}.tar.gz; \
mkdir -p /tmp/magick; \
cd /tmp/magick; \
tar -xf /tmp/magick.tar.gz --strip-components=1; \
./configure --prefix=/opt/imagick; \
make -j 2; \
make install; \
rm -rf /opt/imagick/lib/libMagick++*; \
rm -rf /opt/imagick/include; \
rm -rf /opt/imagick/share; \
apt-get -qqy --autoremove purge \
autoconf \
binutils \
build-essential \
ca-certificates \
curl \
libfftw3-dev \
libheif-dev \
libjpeg-dev \
liblcms2-dev \
libltdl-dev \
liblzma-dev \
libopenexr-dev \
libpng-dev \
librsvg2-dev \
libtiff-dev \
libtool\
libwebp-dev \
libzip-dev \
libzstd-dev \
pkg-config \
;\
apt-get -qqy --no-install-recommends install \
libfontconfig1 \
libfreetype6 \
libglib2.0-0 \
libgomp1 \
libheif1 \
libjpeg-turbo8 \
liblcms2-2 \
libopenexr-3-1-30 \
libopenjp2-7 \
libpng16-16 \
librsvg2-2 \
libtiff6 \
libwebp7 \
libwebpdemux2 \
libwebpmux3 \
libxml2 \
libzip4t64 \
libzstd1 \
;\
apt-get -qqy clean; \
rm -rf /var/lib/apt/lists/*;
ENTRYPOINT ["/opt/imagick/bin/magick"]

View File

@@ -6,37 +6,18 @@ ENV LANG='C.UTF-8' \
JAVA_HOME="/opt/jdk" \
DEBIAN_FRONTEND=noninteractive \
NODE_VERSION=v22.16.0 \
IMAGEMAGICK_VERSION=7.1.1-47 \
TZ=Etc/UTC
RUN set -ex; \
apt-get -qq update; \
apt-get -qq upgrade; \
apt-get -qqy --no-install-recommends install \
curl \
ca-certificates \
binutils \
build-essential autoconf libtool pkg-config \
libltdl-dev \
libpng-dev libjpeg-dev libtiff-dev libwebp-dev libopenexr-dev libfftw3-dev \
libzip-dev \
liblcms2-dev liblzma-dev libzstd-dev \
libheif-dev librsvg2-dev \
ca-certificates \
curl \
; \
rm -rf /var/lib/apt/lists/*
RUN set -eux; \
curl -LfsSo /tmp/magick.tar.gz https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IMAGEMAGICK_VERSION}.tar.gz; \
mkdir -p /tmp/magick; \
cd /tmp/magick; \
tar -xf /tmp/magick.tar.gz --strip-components=1; \
./configure --prefix=/opt/imagick; \
make -j 2; \
make install; \
rm -rf /opt/imagick/lib/libMagick++*; \
rm -rf /opt/imagick/include; \
rm -rf /opt/imagick/share;
RUN set -eux; \
ARCH="$(dpkg --print-architecture)"; \
case "${ARCH}" in \
@@ -105,33 +86,33 @@ RUN set -ex; \
apt-get -qq update; \
apt-get -qq upgrade; \
apt-get -qqy --no-install-recommends install \
tzdata \
ca-certificates \
fontconfig \
woff-tools \
woff2 \
fontforge \
python3 \
python3-tabulate \
fontforge \
tzdata \
woff-tools \
woff2 \
\
libpng16-16 \
libfontconfig1 \
libfreetype6 \
libglib2.0-0 \
libgomp1 \
libheif1 \
libjpeg-turbo8 \
liblcms2-2 \
libopenexr-3-1-30 \
libopenjp2-7 \
libpng16-16 \
librsvg2-2 \
libtiff6 \
libwebp7 \
libopenexr-3-1-30 \
libfreetype6 \
libfontconfig1 \
libglib2.0-0 \
libxml2 \
liblcms2-2 \
libheif1 \
libopenjp2-7 \
libzstd1 \
librsvg2-2 \
libgomp1 \
libwebpmux3 \
libwebpdemux2 \
libwebpmux3 \
libxml2 \
libzip4t64 \
libzstd1 \
; \
find tmp/usr/share/zoneinfo/* -type d ! -name 'Etc' |xargs rm -rf; \
rm -rf /var/lib /var/cache; \
@@ -144,7 +125,7 @@ RUN set -ex; \
COPY --from=build /opt/jre /opt/jre
COPY --from=build /opt/node /opt/node
COPY --from=build /opt/imagick /opt/imagick
COPY --from=penpotapp/imagemagick:7.1.2-0 /opt/imagick /opt/imagick
COPY --chown=penpot:penpot ./bundle-backend/ /opt/penpot/backend/
USER penpot:penpot

View File

@@ -39,6 +39,7 @@ RUN set -ex; \
fonts-wqy-zenhei \
fonts-tlwg-loma-otf \
fonts-freefont-ttf \
poppler-utils \
\
libasound2t64 \
libatk-bridge2.0-0t64 \

View File

@@ -1,14 +1,17 @@
#!/usr/bin/env bash
set -x
DOCKER_CLI_EXPERIMENTAL=enabled
IMAGE=${1:-backend}
OUTPUT="type=registry"
if [ "--local" = "$2" ]; then
OUTPUT="type=docker"
fi
ORG=${PENPOT_DOCKER_NAMESPACE:-penpotapp};
PLATFORM=${PENPOT_BUILD_PLATFORM:-linux/amd64};
IMAGE=${PENPOT_BUILD_IMAGE:-backend}
PLATFORM=${PENPOT_BUILD_PLATFORM:-linux/amd64};
PLATFORM=${PENPOT_BUILD_PLATFORM:-linux/amd64,linux/arm64};
VERSION=${PENPOT_BUILD_VERSION:-latest}
DOCKER_IMAGE="$ORG/$IMAGE";
OPTIONS="-t $DOCKER_IMAGE:$VERSION";
@@ -20,7 +23,7 @@ for element in "${TAGS[@]}"; do
done
docker buildx inspect penpot > /dev/null 2>&1;
docker run --privileged --rm tonistiigi/binfmt --install all
docker run --privileged --rm tonistiigi/binfmt --install all > /dev/null;
if [ $? -eq 1 ]; then
docker buildx create --name=penpot --use
@@ -32,4 +35,5 @@ fi
unset IFS;
docker buildx build --platform ${PLATFORM// /,} $OPTIONS -f Dockerfile.$IMAGE "$@" .;
shift;
docker buildx build --output $OUTPUT --platform ${PLATFORM// /,} $OPTIONS -f Dockerfile.$IMAGE .;

View File

@@ -15,6 +15,9 @@
(def grid-x-axis 10)
(def grid-y-axis 10)
(def sidebar-default-width 318)
(def sidebar-default-max-width 768)
(def page-metadata
"Default data for page metadata."
{:grid-x-axis grid-x-axis

View File

@@ -245,4 +245,4 @@
(defn event
[props]
(ptk/data-event ::events props))
(ptk/data-event ::event props))

View File

@@ -673,41 +673,35 @@
(defn paste-shapes
[{in-viewport? :in-viewport :as pdata}]
(letfn [(translate-media [mdata media-idx attr-path]
(let [id (-> (get-in mdata attr-path)
(:id))
(letfn [(translate-media [mdata media-idx attr]
(let [id (-> (get mdata attr) :id)
mobj (get media-idx id)]
(if mobj
(if (empty? attr-path)
(assoc mdata :id (:id mobj))
(update-in mdata attr-path assoc :id (:id mobj)))
(update mdata attr assoc :id (:id mobj))
mdata)))
(add-obj? [chg]
(= (:type chg) :add-obj))
(process-rchange-shape [obj media-idx]
(let [translate-fill-image #(translate-media % media-idx :fill-image)
translate-stroke-image #(translate-media % media-idx :stroke-image)
translate-fills #(mapv translate-fill-image %)
translate-strokes #(mapv translate-stroke-image %)
process-text-node #(d/update-when % :fills translate-fills)]
(-> obj
(update :fills translate-fills)
(update :strokes translate-strokes)
(d/update-when :content #(txt/transform-nodes process-text-node %))
(d/update-when :position-data #(mapv process-text-node %)))))
;; Analyze the rchange and replace staled media and
;; references to the new uploaded media-objects.
(process-rchange [media-idx change]
(let [;; Texts can have different fills for pieces of the text
tr-fill-xf (map #(translate-media % media-idx [:fill-image]))
tr-stroke-xf (map #(translate-media % media-idx [:stroke-image]))]
(if (add-obj? change)
(update change :obj (fn [obj]
(-> obj
(update :fills #(into [] tr-fill-xf %))
(update :strokes #(into [] tr-stroke-xf %))
(d/update-when :metadata translate-media media-idx [])
(d/update-when :fill-image translate-media media-idx [])
(d/update-when :content
(fn [content]
(txt/xform-nodes tr-fill-xf content)))
(d/update-when :position-data
(fn [position-data]
(mapv (fn [pos-data]
(update pos-data :fills #(into [] tr-fill-xf %)))
position-data))))))
change)))
(if (add-obj? change)
(update change :obj process-rchange-shape media-idx)
change))
(calculate-paste-position [state pobjects selected position]
(let [page-objects (dsh/lookup-page-objects state)

View File

@@ -479,7 +479,7 @@
;; We don't have the fills attribute. It's an old text without color
;; so need to be black
(and (nil? (:fills node)) (empty? color-attrs))
(update :fills conj txt/default-text-attrs)
(assoc :fills (:fills txt/default-text-attrs))
;; Remove duplicates from the fills
:always

View File

@@ -15,7 +15,6 @@
[app.main.ui.inspect.attributes.blur :refer [blur-panel]]
[app.main.ui.inspect.attributes.fill :refer [fill-panel]]
[app.main.ui.inspect.attributes.geometry :refer [geometry-panel]]
[app.main.ui.inspect.attributes.image :refer [image-panel]]
[app.main.ui.inspect.attributes.layout :refer [layout-panel]]
[app.main.ui.inspect.attributes.layout-element :refer [layout-element-panel]]
[app.main.ui.inspect.attributes.shadow :refer [shadow-panel]]
@@ -27,13 +26,12 @@
[rumext.v2 :as mf]))
(def type->options
{:multiple [:fill :stroke :image :text :shadow :blur :layout-element]
{:multiple [:fill :stroke :text :shadow :blur :layout-element]
:frame [:geometry :fill :stroke :shadow :blur :layout :layout-element]
:group [:geometry :svg :layout-element]
:rect [:geometry :fill :stroke :shadow :blur :svg :layout-element]
:circle [:geometry :fill :stroke :shadow :blur :svg :layout-element]
:path [:geometry :fill :stroke :shadow :blur :svg :layout-element]
:image [:image :geometry :fill :stroke :shadow :blur :svg :layout-element]
:text [:geometry :text :shadow :blur :stroke :layout-element]
:variant [:variant :geometry :fill :stroke :shadow :blur :layout :layout-element]})
@@ -69,7 +67,6 @@
:stroke stroke-panel
:shadow shadow-panel
:blur blur-panel
:image image-panel
:text text-panel
:svg svg-panel
:variant variant-panel*)

View File

@@ -1,51 +0,0 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.inspect.attributes.image
(:require-macros [app.main.style :as stl])
(:require
[app.common.files.helpers :as cfh]
[app.common.media :as cm]
[app.config :as cf]
[app.main.ui.components.copy-button :refer [copy-button*]]
[app.util.code-gen.style-css :as css]
[app.util.i18n :refer [tr]]
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(defn has-image? [shape]
(= (:type shape) :image))
(mf/defc image-panel
[{:keys [objects shapes]}]
(for [shape (filter cfh/image-shape? shapes)]
[:div {:class (stl/css :attributes-block)
:key (str "image-" (:id shape))}
[:div {:class (stl/css :image-wrapper)}
[:img {:src (cf/resolve-file-media (-> shape :metadata))}]]
[:div {:class (stl/css :image-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.image.width")]
[:div {:class (stl/css :global/attr-value)}
[:> copy-button* {:data (css/get-css-property objects (:metadata shape) :width)}
[:div {:class (stl/css :button-children)} (css/get-css-value objects (:metadata shape) :width)]]]]
[:div {:class (stl/css :image-row)}
[:div {:class (stl/css :global/attr-label)}
(tr "inspect.attributes.image.height")]
[:div {:class (stl/css :global/attr-value)}
[:> copy-button* {:data (css/get-css-property objects (:metadata shape) :height)}
[:div {:class (stl/css :button-children)} (css/get-css-value objects (:metadata shape) :height)]]]]
(let [mtype (-> shape :metadata :mtype)
name (:name shape)
extension (cm/mtype->extension mtype)]
[:a {:class (stl/css :download-button)
:target "_blank"
:download (cond-> name extension (str/concat extension))
:href (cf/resolve-file-media (-> shape :metadata))}
(tr "inspect.attributes.image.download")])]))

View File

@@ -8,6 +8,7 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.main.constants :refer [sidebar-default-width sidebar-default-max-width]]
[app.main.data.common :as dcm]
[app.main.data.event :as ev]
[app.main.data.workspace :as dw]
@@ -210,7 +211,7 @@
(= current-section :code)))
{:keys [on-pointer-down on-lost-pointer-capture on-pointer-move set-size size]}
(use-resize-hook :code 276 276 768 :x true :right)
(use-resize-hook :code sidebar-default-width sidebar-default-width sidebar-default-max-width :x true :right)
on-change-section
(mf/use-fn
@@ -224,7 +225,7 @@
(mf/use-fn
(mf/deps size)
(fn []
(set-size (if (> size 276) 276 768))))
(set-size (if (> size sidebar-default-width) sidebar-default-width sidebar-default-max-width))))
props
(mf/spread-props props
@@ -235,12 +236,12 @@
[:aside
{:class (stl/css-case :right-settings-bar true
:not-expand (not can-be-expanded?)
:expanded (> size 276))
:expanded (> size sidebar-default-width))
:id "right-sidebar-aside"
:data-testid "right-sidebar"
:data-size (str size)
:style {"--width" (if can-be-expanded? (dm/str size "px") "276px")}}
:style {"--width" (if can-be-expanded? (dm/str size "px") (dm/str sidebar-default-width "px"))}}
(when can-be-expanded?
[:div {:class (stl/css :resize-area)

View File

@@ -55,15 +55,22 @@
;; Excluding nil values
values (d/without-nils values)
fills (if (contains? cfg/flags :frontend-binary-fills)
fills (get values :fills)
fills (if (and (contains? cfg/flags :frontend-binary-fills)
(not= fills :multiple))
(take types.fill/MAX-FILLS (d/nilv (:fills values) []))
(:fills values))
fills)
has-fills? (or (= :multiple fills) (some? (seq fills)))
can-add-fills? (if (contains? cfg/flags :frontend-binary-fills)
(and (not (= :multiple fills))
(< (count fills) types.fill/MAX-FILLS))
(not (= :multiple fills)))
state* (mf/use-state has-fills?)
open? (deref state*)

View File

@@ -286,7 +286,8 @@
(fn [mod? ids]
(let [sorted-ids
(into (d/ordered-set)
(comp (remove #(dm/get-in objects [% :blocked]))
(comp (remove (partial cfh/hidden-parent? objects))
(remove #(dm/get-in objects [% :blocked]))
(remove (partial cfh/svg-raw-shape? objects)))
(ctt/sort-z-index objects ids {:bottom-frames? mod?}))]
(mf/set-ref-val! sorted-ids-cache (assoc cached-ids [mod? ids] sorted-ids))
@@ -355,7 +356,6 @@
hover-shape
(->> ids
(remove remove-hover?)
(remove (partial cfh/hidden-parent? objects))
(remove #(and mod? (no-fill-nested-frames? %)))
(filter #(or (empty? focus) (cpf/is-in-focus? objects focus %)))
(first)
@@ -366,7 +366,6 @@
(when show-measures?
(->> ids
(remove remove-measure?)
(remove (partial cfh/hidden-parent? objects))
(remove #(and mod? (no-fill-nested-frames? %)))
(filter #(or (empty? focus) (cpf/is-in-focus? objects focus %)))
(first)

View File

@@ -1,5 +1,16 @@
# CHANGELOG
## 1.0.7
- Add the ability to provide refereron creating build context
```js
const context = penpot.createBuildContext({referer:"my-referer"});
```
The referer will be added as an additional field on the manifest.json
## 1.0.6
- Fix unexpected issue on library color decoding

View File

@@ -21,11 +21,10 @@
:dev
{:extra-paths ["dev"]
:extra-deps
{thheller/shadow-cljs {:mvn/version "3.1.4"}
{thheller/shadow-cljs {:mvn/version "3.1.7"}
com.bhauman/rebel-readline {:mvn/version "RELEASE"}
org.clojure/tools.namespace {:mvn/version "RELEASE"}
criterium/criterium {:mvn/version "RELEASE"}
cider/cider-nrepl {:mvn/version "0.48.0"}}}
criterium/criterium {:mvn/version "RELEASE"}}}
:shadow-cljs
{:main-opts ["-m" "shadow.cljs.devtools.cli"]

View File

@@ -1,6 +1,6 @@
{
"name": "@penpot/library",
"version": "1.0.6",
"version": "1.0.7",
"license": "MPL-2.0",
"author": "Kaleidos INC",
"packageManager": "yarn@4.9.1+sha512.f95ce356460e05be48d66401c1ae64ef84d163dd689964962c6888a9810865e39097a5e9de748876c2e0bf89b232d583c33982773e9903ae7a76257270986538",
@@ -40,8 +40,7 @@
"@zip.js/zip.js": "patch:@zip.js/zip.js@npm%3A2.7.60#~/.yarn/patches/@zip.js-zip.js-npm-2.7.60-b6b814410b.patch",
"concurrently": "^9.1.2",
"luxon": "^3.6.1",
"nodemon": "^3.1.9",
"shadow-cljs": "3.1.4"
"nodemon": "^3.1.9"
},
"dependencies": {
"source-map-support": "^0.5.21"

View File

@@ -6,7 +6,7 @@ import { Writable } from "stream";
// console.log(penpot);
(async function () {
const context = penpot.createBuildContext();
const context = penpot.createBuildContext({referer:"playground"});
{
context.addFile({ name: "Test File 1" });

View File

@@ -271,11 +271,19 @@
(fn []
(json/->js @state))))
(def ^:private schema:context-options
[:map {:title "ContextOptions"}
[:referer {:optional true} ::sm/text]])
(def ^:private decode-context-options
(sm/decoder schema:context-options sm/json-transformer))
(defn create-build-context
"Create an empty builder state context."
[]
(let [state (atom {})
api (create-builder-api state)]
[options]
(let [options (some-> options decode-params decode-context-options)
state (atom {:options options})
api (create-builder-api state)]
(specify! api
cljs.core/IDeref

View File

@@ -183,17 +183,22 @@
(defn- generate-manifest-procs
[state]
(let [files (->> (get state ::fb/files)
(mapv (fn [[file-id file]]
{:id file-id
:name (:name file)
:features (:features file)})))
(let [opts (get state :options)
files (->> (get state ::fb/files)
(mapv (fn [[file-id file]]
{:id file-id
:name (:name file)
:features (:features file)})))
params {:type "penpot/export-files"
:version 1
:generated-by "penpot-library/%version%"
:referer (get opts :referer)
:files files
:relations []}]
["manifest.json" (delay (json/encode params))]))
:relations []}
params (d/without-nils params)]
["manifest.json"
(delay (json/encode params))]))
(defn- generate-procs
[state]

119
manage.sh
View File

@@ -7,6 +7,7 @@ export DEVENV_PNAME="penpotdev";
export CURRENT_USER_ID=$(id -u);
export CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD);
export IMAGEMAGICK_VERSION=7.1.2-0
# Safe directory to avoid ownership errors with Git
git config --global --add safe.directory /home/penpot/penpot || true
@@ -16,16 +17,23 @@ export JAVA_OPTS=${JAVA_OPTS:-"-Xmx1000m -Xms50m"};
set -e
ARCH=$(uname -m)
if [[ "$ARCH" == "x86_64" || "$ARCH" == "i386" || "$ARCH" == "i686" ]]; then
ARCH="amd64"
elif [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
ARCH="arm64"
else
echo "Unknown architecture $ARCH"
exit -1
fi
function print-current-version {
echo -n "$(git describe --tags --match "*.*.*")";
}
function build-devenv {
set +e;
echo "Building development image $DEVENV_IMGNAME:latest..."
pushd docker/devenv;
function setup-buildx {
docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx inspect penpot > /dev/null 2>&1;
@@ -36,19 +44,28 @@ function build-devenv {
docker buildx use penpot;
docker buildx inspect --bootstrap > /dev/null 2>&1;
fi
# docker build -t $DEVENV_IMGNAME:latest .
docker buildx build --platform linux/amd64 --push -t $DEVENV_IMGNAME:latest .;
docker pull $DEVENV_IMGNAME:latest;
popd;
}
function build-devenv-local {
echo "Building local only development image $DEVENV_IMGNAME:latest..."
function build-devenv {
set +e;
pushd docker/devenv;
docker build -t $DEVENV_IMGNAME:latest .;
if [ "$1" = "--local" ]; then
echo "Build local only $DEVENV_IMGNAME:latest image";
docker build -t $DEVENV_IMGNAME:latest .;
else
echo "Build and push $DEVENV_IMGNAME:latest image";
setup-buildx;
docker buildx build \
--platform linux/amd64,linux/arm64 \
--output type=registry \
-t $DEVENV_IMGNAME:latest .;
docker pull $DEVENV_IMGNAME:latest;
fi
popd;
}
@@ -124,6 +141,32 @@ function run-devenv-isolated-shell {
$DEVENV_IMGNAME:latest sudo -EH -u penpot bash
}
function build-imagemagick-docker-image {
set +e;
echo "Building image penpotapp/imagemagick:$IMAGEMAGICK_VERSION"
pushd docker/imagemagick;
output_option="type=registry";
platform="linux/amd64,linux/arm64";
if [ "$1" = "--local" ]; then
output_option="type=docker";
platform="linux/$ARCH"
fi
setup-buildx;
docker buildx build \
--build-arg IMAGEMAGICK_VERSION=$IMAGEMAGICK_VERSION \
--platform $platform \
--output $output_option \
-t penpotapp/imagemagick:latest \
-t penpotapp/imagemagick:$IMAGEMAGICK_VERSION .;
popd;
}
function build {
echo ">> build start: $1"
local version=$(print-current-version);
@@ -219,21 +262,21 @@ function build-docs-bundle {
echo ">> bundle docs end";
}
function build-frontend-docker-images {
function build-frontend-docker-image {
rsync -avr --delete ./bundles/frontend/ ./docker/images/bundle-frontend/;
pushd ./docker/images;
docker build -t penpotapp/frontend:$CURRENT_BRANCH -t penpotapp/frontend:latest -f Dockerfile.frontend .;
popd;
}
function build-backend-docker-images {
function build-backend-docker-image {
rsync -avr --delete ./bundles/backend/ ./docker/images/bundle-backend/;
pushd ./docker/images;
docker build -t penpotapp/backend:$CURRENT_BRANCH -t penpotapp/backend:latest -f Dockerfile.backend .;
popd;
}
function build-exporter-docker-images {
function build-exporter-docker-image {
rsync -avr --delete ./bundles/exporter/ ./docker/images/bundle-exporter/;
pushd ./docker/images;
docker build -t penpotapp/exporter:$CURRENT_BRANCH -t penpotapp/exporter:latest -f Dockerfile.exporter .;
@@ -246,7 +289,7 @@ function usage {
echo "Options:"
echo "- pull-devenv Pulls docker development oriented image"
echo "- build-devenv Build docker development oriented image"
echo "- build-devenv-local Build a local docker development oriented image"
echo "- build-devenv --local Build a local docker development oriented image"
echo "- create-devenv Create the development oriented docker compose service."
echo "- start-devenv Start the development oriented docker compose service."
echo "- stop-devenv Stops the development oriented docker compose service."
@@ -263,9 +306,9 @@ function usage {
echo "- build-docs-bundle Build docs bundle."
echo ""
echo "- build-docker-images Build all docker images (frontend, backend and exporter)."
echo "- build-frontend-docker-images Build frontend docker images."
echo "- build-backend-docker-images Build backend docker images."
echo "- build-exporter-docker-images Build exporter docker images."
echo "- build-frontend-docker-image Build frontend docker images."
echo "- build-backend-docker-image Build backend docker images."
echo "- build-exporter-docker-image Build exporter docker images."
echo ""
echo "- version Show penpot's version."
}
@@ -281,11 +324,8 @@ case $1 in
;;
build-devenv)
build-devenv ${@:2}
;;
build-devenv-local)
build-devenv-local ${@:2}
shift;
build-devenv $@;
;;
create-devenv)
@@ -339,25 +379,30 @@ case $1 in
build-docs-bundle;
;;
build-imagemagick-docker-image)
shift;
build-imagemagick-docker-image $@;
;;
build-docker-images)
build-frontend-docker-images
build-backend-docker-images
build-exporter-docker-images
build-frontend-docker-image
build-backend-docker-image
build-exporter-docker-image
;;
build-frontend-docker-images)
build-frontend-docker-images
build-frontend-docker-image)
build-frontend-docker-image
;;
build-backend-docker-images)
build-backend-docker-images
build-backend-docker-image)
build-backend-docker-image
;;
build-exporter-docker-images)
build-exporter-docker-images
build-exporter-docker-image)
build-exporter-docker-image
;;
*)
usage
;;
esac
esac