Compare commits
380 commits
docs-redes
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51d30325fc |
||
|
|
f8595e3052 |
||
|
|
4d0abeb37c |
||
|
|
033650d792 |
||
|
|
4c49f27edf |
||
|
|
c84578721c |
||
|
|
354fee648e |
||
|
|
da3ce17161 |
||
|
|
bbd1b33122 |
||
|
|
ae40ca4ac1 |
||
|
|
093aa2d663 |
||
|
|
e906751c89 |
||
|
|
718fd92f85 |
||
|
|
01b661f6a5 |
||
|
|
896344eb66 |
||
|
|
8fd0340404 |
||
|
|
bc4ee373b5 | ||
|
|
5d39f1aa9a | ||
|
|
a27995940a |
||
|
|
4e8b705cda |
||
|
|
7ee2b2d856 |
||
|
|
696c55c6ee |
||
|
|
0357730294 |
||
|
|
158fd41a8b |
||
|
|
fc2b7309c1 |
||
|
|
18b3d0587f |
||
|
|
60d148e4b1 |
||
|
|
423f7e4498 |
||
|
|
4dbde817f4 |
||
|
|
95689bdeb7 |
||
|
|
7d4fe64352 |
||
|
|
e27e85aae9 | ||
|
|
dd7094e5d3 | ||
|
|
6630fa5647 |
||
|
|
7957d23c25 |
||
|
|
b25fe7496f |
||
|
|
00b0ce936d |
||
|
|
bc62140ac0 |
||
|
|
ebe8de8d2b |
||
|
|
6a2619880c |
||
|
|
db11f350cd |
||
|
|
216c9961a5 |
||
|
|
764f9bb175 |
||
|
|
23bd70e057 |
||
|
|
a0cb86ebff |
||
|
|
7aaa203c5f |
||
|
|
44a9d617e8 |
||
|
|
8e77d9358e |
||
|
|
7b8355a385 |
||
|
|
cb3305a2fc |
||
|
|
c73b2dd753 |
||
|
|
e37a7b9d4b |
||
|
|
ef7d3301c9 |
||
|
|
d16fd500df |
||
|
|
27afad59f6 |
||
|
|
4f71b22665 |
||
|
|
467f70ada7 |
||
|
|
9578b627fd |
||
|
|
4c464b3092 |
||
|
|
ba2c9989e6 |
||
|
|
9f3b00bed9 |
||
|
|
e0e96c3bf8 |
||
|
|
9125ef64be |
||
|
|
e5deb1611e |
||
|
|
8d73bec252 |
||
|
|
17bb94bbbf |
||
|
|
ac867f6587 | ||
|
|
cb1c2d86c0 | ||
|
|
8513b77fd8 | ||
|
|
9c78746441 | ||
|
|
7a383e080f | ||
|
|
9df647bb99 |
||
|
|
fc1c90e0ce |
||
|
|
385f1dafb9 |
||
|
|
70d2d52be4 |
||
|
|
6e9b6a1ee5 |
||
|
|
366e6afa3f |
||
|
|
de7a04b57a |
||
|
|
322088d3f8 |
||
|
|
f01afbc852 |
||
|
|
4df077f9b2 |
||
|
|
db22cb234d |
||
|
|
152ac2a7ce |
||
|
|
c113a068ad |
||
|
|
6943a56e8f |
||
|
|
909c16c517 | ||
|
|
5ee47ccf7b |
||
|
|
dfff549002 |
||
|
|
855dcadd79 | ||
|
|
2b8276da42 | ||
|
|
a35b676e05 | ||
|
|
45167ff743 | ||
|
|
140a110e6d |
||
|
|
bc3299fff6 |
||
|
|
1589a2f835 |
||
|
|
fcaff5e09d |
||
|
|
b489af776c |
||
|
|
b7f2d4a43b | ||
|
|
0015f8d3cb |
||
|
|
857f7b7518 |
||
|
|
ac00787202 |
||
|
|
4d7b0b487c |
||
|
|
d258771151 |
||
|
|
8aa187b393 |
||
|
|
ebe377f375 |
||
|
|
62f0d7eb26 |
||
|
|
04e1b05d10 |
||
|
|
03412f9cb0 |
||
|
|
2c2fd26bb5 | ||
|
|
ce7b1fc62b |
||
|
|
91d5da6124 |
||
|
|
612e0853bf |
||
|
|
ae2d97543f |
||
|
|
0dc77a2893 |
||
|
|
559ff6e2f4 |
||
|
|
254a5a652e |
||
|
|
34517218f0 |
||
|
|
82b3420e53 |
||
|
|
b393cf03a3 |
||
|
|
43bfb094c2 |
||
|
|
6cbe626e7f |
||
|
|
e6b725b106 |
||
|
|
0282768c10 |
||
|
|
6544005892 |
||
|
|
ffd98d68da |
||
|
|
7002f2e943 |
||
|
|
72662cf05f | ||
|
|
d9f4a1883f | ||
|
|
7f3358d6a8 | ||
|
|
25f19e03c8 | ||
|
|
6486f9d9b2 | ||
|
|
3798b74c7e | ||
|
|
8b5fb90dae | ||
|
|
3f925105cb | ||
|
|
03758a01e3 | ||
|
|
dbcf85c50c | ||
|
|
c9392806ac | ||
|
|
a8a1f362cb | ||
|
|
82d958747a | ||
|
|
3b59c3f3b9 | ||
|
|
73ade6e94f | ||
|
|
ae8171e9fe | ||
|
|
9640e16c12 | ||
|
|
36a1f7b52b | ||
|
|
d2d9acbdf6 | ||
|
|
b987c1b413 |
||
|
|
1ec3708f68 |
||
|
|
a0937fd3ef |
||
|
|
e753157ad2 |
||
|
|
6b35e06780 | ||
|
|
01be6e3d1f |
||
|
|
466719d160 | ||
|
|
095e8be923 |
||
|
|
4597d7fa64 |
||
|
|
136273503e |
||
|
|
ca3e4f6c45 |
||
|
|
52515277a0 |
||
|
|
ae621d2883 |
||
|
|
832db6d10b |
||
|
|
be7608e079 |
||
|
|
e1282a6371 |
||
|
|
fd71325a42 |
||
|
|
bd8c88e8ac |
||
|
|
8e51d6d32f |
||
|
|
b3bb856ed1 |
||
|
|
2936e8b98e |
||
|
|
539effb6b5 |
||
|
|
d3d87d09aa |
||
|
|
c68c85a384 |
||
|
|
3248f2fd31 |
||
|
|
ac1479afa2 |
||
|
|
0c24aa4313 |
||
|
|
2bd3de1f7f |
||
|
|
0744756695 |
||
|
|
594e2bf60f |
||
|
|
151beed7e8 |
||
|
|
6af1028856 |
||
|
|
a93c52e182 |
||
|
|
49a4193887 |
||
|
|
1bc5a2758f |
||
|
|
0581290cfe |
||
|
|
105c10aee7 | ||
|
|
d1838f42bf |
||
|
|
30d7cccf50 |
||
|
|
19c8d98ed3 |
||
|
|
ce5f733457 | ||
|
|
312146c70e | ||
|
|
4788263b9a |
||
|
|
a220d53a91 |
||
|
|
de29a0bd6f |
||
|
|
467bbfc4e5 |
||
|
|
741ff242f7 |
||
|
|
83ec246f63 |
||
|
|
af659850fc |
||
|
|
9a10be69ae |
||
|
|
797016d736 |
||
|
|
fc1cf90574 | ||
|
|
b12dcb054b | ||
|
|
f8998da78d |
||
|
|
bc7b816c37 |
||
|
|
194b0586ba |
||
|
|
2f389d99a8 |
||
|
|
5b1caf0d08 |
||
|
|
8dc509f49b |
||
|
|
3930f58203 |
||
|
|
ba9ab72893 |
||
|
|
27c9737ecd |
||
|
|
f9392e9980 |
||
|
|
6ac0bcdf7f | ||
|
|
125c4ab485 |
||
|
|
92a25c7dfd | ||
|
|
dadf638c00 |
||
|
|
e7643b8605 | ||
|
|
9763cd3465 | ||
|
|
7245b5b4d7 |
||
|
|
2acf32cd36 |
||
|
|
9c7dc05cea |
||
|
|
59d8650a0f |
||
|
|
00e2f16971 |
||
|
|
993fde17fe |
||
|
|
ae5e3f47a7 | ||
|
|
6bf875f2a2 | ||
|
|
61876448f7 | ||
|
|
202eecdf94 |
||
|
|
ecf1c41db4 | ||
|
|
915efa06bb | ||
|
|
4541cf0b3a | ||
|
|
538ba8daac |
||
|
|
c2db2e550f |
||
|
|
ea2bfa9bcd |
||
|
|
d4015123dd |
||
|
|
ef73a75c68 |
||
|
|
2478926274 |
||
|
|
e9100152e7 |
||
|
|
5df9ac1a53 | ||
|
|
6a3ba3d613 |
||
|
|
15191c3bbe |
||
|
|
6b288be2fa | ||
|
|
5f233f9dd6 |
||
|
|
a78e8c95ee | ||
|
|
4228eab052 |
||
|
|
267e4ec9fa |
||
|
|
aee6d99702 |
||
|
|
dab09a94d7 |
||
|
|
6381e520b9 |
||
|
|
36743ca76f |
||
|
|
a04a31be8c | ||
|
|
114c15197b | ||
|
|
fa4bf38b12 |
||
|
|
7d66f3c26a |
||
|
|
dbf7bba69f |
||
|
|
b2f84d041c |
||
|
|
76f806fe82 |
||
|
|
76e41a6211 |
||
|
|
471a50cd04 |
||
|
|
cacbf030d6 |
||
|
|
49ff9b62bf |
||
|
|
f56093ae27 |
||
|
|
8519d8f024 |
||
|
|
54438a7644 |
||
|
|
7aba2c3b95 |
||
|
|
5be7ee74f8 |
||
|
|
f6aba688a9 |
||
|
|
8624da51f8 |
||
|
|
0d81cd2831 |
||
|
|
3224db508d |
||
|
|
1fb6403e7d |
||
|
|
ba01492198 |
||
|
|
7e45e3d025 |
||
|
|
49b524d169 |
||
|
|
bedebe0c06 |
||
|
|
536422d508 |
||
|
|
fa7c6d80a2 |
||
|
|
3605fdf42f |
||
|
|
347d8cf861 |
||
|
|
89db2ad082 | ||
|
|
8d1e5188ad | ||
|
|
f07ead3fb2 | ||
|
|
d04fd9a35f | ||
|
|
bed3ec4163 | ||
|
|
98f3cc845f |
||
|
|
74fa41330e | ||
|
|
4a1d101d04 |
||
|
|
d824318a66 |
||
|
|
00be6f24d2 |
||
|
|
55b90a50bc |
||
|
|
f82c971cb0 | ||
|
|
2aea5e2dae | ||
|
|
481c145cd3 |
||
|
|
51c7453bd2 |
||
|
|
4598af4d7a |
||
|
|
c4fdfd6415 |
||
|
|
d9b99a990d |
||
|
|
d6383364ab |
||
|
|
3a4c3e7a7f |
||
|
|
caf05adff3 |
||
|
|
67afec3c2a |
||
|
|
7566ed4ba6 |
||
|
|
90be707d9c |
||
|
|
82fd9de339 |
||
|
|
461d34c620 |
||
|
|
ee2156ee2c |
||
|
|
d730c963f4 |
||
|
|
fc0aea1038 |
||
|
|
e219e3b65e |
||
|
|
42e77506d9 |
||
|
|
896a90f69e |
||
|
|
c27d2ceb8e |
||
|
|
dd4aa56310 |
||
|
|
6345b64a22 |
||
|
|
2c45ae69bb |
||
|
|
dade880064 |
||
|
|
bd57598c03 |
||
|
|
8deb8a04e7 |
||
|
|
93b49391c7 |
||
|
|
e5be3c5cfe |
||
|
|
63e1f3c09c |
||
|
|
39c922bc9f |
||
|
|
cadbccfb72 |
||
|
|
ba38474050 |
||
|
|
86e3d51c8e |
||
|
|
10e3a13d12 |
||
|
|
5df8ecc961 |
||
|
|
dca2064916 |
||
|
|
13d4b218e7 |
||
|
|
d1ba26a043 |
||
|
|
1c163422aa |
||
|
|
bdb415130b |
||
|
|
e573bf4df9 |
||
|
|
9772523f46 |
||
|
|
157c8fdbc7 |
||
|
|
758a63648e |
||
|
|
f2881822d2 |
||
|
|
bb4e95e22d |
||
|
|
5ebccf1ea6 |
||
|
|
f08f4be868 | ||
|
|
a964be1ada |
||
|
|
f33e627360 |
||
|
|
1b6ed1bc00 |
||
|
|
14cc9ec45b |
||
|
|
26ff639b62 |
||
|
|
10abe246b0 |
||
|
|
8a5a0506bf |
||
|
|
a2e32fe414 |
||
|
|
7a5e41f904 |
||
|
|
5b8594928b |
||
|
|
a6288c414e |
||
|
|
bd2c1ea73f |
||
|
|
429e94f4ce |
||
|
|
f302c8053c |
||
|
|
5d2b4308a8 |
||
|
|
f4b21a6b37 |
||
|
|
265d2e45db |
||
|
|
c3a7266001 |
||
|
|
3721d73423 |
||
|
|
d218384396 |
||
|
|
475534c132 |
||
|
|
8e810d59f0 |
||
|
|
1a2310265f |
||
|
|
87b1325dbc |
||
|
|
f8c8611219 |
||
|
|
4b6a8e17c5 |
||
|
|
868931fe72 |
||
|
|
3f83b42db5 |
||
|
|
9995dae4ad |
||
|
|
d36d1718d9 |
||
|
|
0f61873fe8 |
||
|
|
fe1f23b0fd |
||
|
|
2b35861aee |
||
|
|
ddf27038e1 |
||
|
|
5b091db26d |
||
|
|
fe9495d776 |
||
|
|
7a40cc59ca |
||
|
|
e941f36267 |
||
|
|
482f19e6b9 |
||
|
|
dd6eb0fa75 |
||
|
|
9efaedfe39 |
||
|
|
c4c0d64fd5 |
||
|
|
ffcfa1b0e7 |
||
|
|
3204287f96 |
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"files": [
|
"files": [
|
||||||
"website/src/pages/credits.mdx",
|
"website/src/pages/credits.mdx"
|
||||||
"docs/src/assets/contributors.html"
|
|
||||||
],
|
],
|
||||||
"imageSize": 75,
|
"imageSize": 75,
|
||||||
"commit": false,
|
"commit": false,
|
||||||
|
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
language: en-US
|
|
||||||
tone_instructions: ''
|
|
||||||
early_access: false
|
|
||||||
enable_free_tier: true
|
|
||||||
reviews:
|
|
||||||
profile: chill
|
|
||||||
request_changes_workflow: false
|
|
||||||
high_level_summary: true
|
|
||||||
high_level_summary_placeholder: '@coderabbitai summary'
|
|
||||||
auto_title_placeholder: '@coderabbitai'
|
|
||||||
review_status: true
|
|
||||||
poem: true
|
|
||||||
collapse_walkthrough: false
|
|
||||||
sequence_diagrams: true
|
|
||||||
path_filters: []
|
|
||||||
path_instructions: []
|
|
||||||
abort_on_close: true
|
|
||||||
auto_review:
|
|
||||||
enabled: true
|
|
||||||
auto_incremental_review: true
|
|
||||||
ignore_title_keywords: []
|
|
||||||
labels: []
|
|
||||||
drafts: false
|
|
||||||
base_branches: ['v3-alpha', 'master']
|
|
||||||
tools:
|
|
||||||
shellcheck:
|
|
||||||
enabled: true
|
|
||||||
ruff:
|
|
||||||
enabled: true
|
|
||||||
markdownlint:
|
|
||||||
enabled: true
|
|
||||||
github-checks:
|
|
||||||
enabled: true
|
|
||||||
timeout_ms: 90000
|
|
||||||
languagetool:
|
|
||||||
enabled: true
|
|
||||||
enabled_only: false
|
|
||||||
level: default
|
|
||||||
biome:
|
|
||||||
enabled: true
|
|
||||||
hadolint:
|
|
||||||
enabled: true
|
|
||||||
swiftlint:
|
|
||||||
enabled: true
|
|
||||||
phpstan:
|
|
||||||
enabled: true
|
|
||||||
level: default
|
|
||||||
golangci-lint:
|
|
||||||
enabled: true
|
|
||||||
yamllint:
|
|
||||||
enabled: true
|
|
||||||
gitleaks:
|
|
||||||
enabled: true
|
|
||||||
checkov:
|
|
||||||
enabled: true
|
|
||||||
detekt:
|
|
||||||
enabled: true
|
|
||||||
eslint:
|
|
||||||
enabled: true
|
|
||||||
chat:
|
|
||||||
auto_reply: true
|
|
||||||
knowledge_base:
|
|
||||||
opt_out: false
|
|
||||||
learnings:
|
|
||||||
scope: auto
|
|
||||||
issues:
|
|
||||||
scope: auto
|
|
||||||
jira:
|
|
||||||
project_keys: []
|
|
||||||
linear:
|
|
||||||
team_keys: []
|
|
||||||
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -7,8 +7,6 @@ body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
***Please note: No bug reports are currently being accepted for Wails v3***
|
|
||||||
***Please note: No bug reports are currently being accepted for Wails v3***
|
|
||||||
***Please note: No bug reports are currently being accepted for Wails v3***
|
***Please note: No bug reports are currently being accepted for Wails v3***
|
||||||
Before submitting this issue, please do the following:
|
Before submitting this issue, please do the following:
|
||||||
- Do a web search for your error. This usually leads to a much better understanding of the issue.
|
- Do a web search for your error. This usually leads to a much better understanding of the issue.
|
||||||
|
|
@ -72,7 +70,7 @@ body:
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: systemetails
|
id: systemdetails
|
||||||
attributes:
|
attributes:
|
||||||
label: System Details
|
label: System Details
|
||||||
description: Please add the output of `wails doctor`.
|
description: Please add the output of `wails doctor`.
|
||||||
|
|
|
||||||
3
.github/pull_request_template.md
vendored
|
|
@ -6,7 +6,6 @@
|
||||||
* YOUR PR MAY BE REJECTED IF IT DOES NOT FOLLOW THESE STEPS *
|
* YOUR PR MAY BE REJECTED IF IT DOES NOT FOLLOW THESE STEPS *
|
||||||
*********************************************************************
|
*********************************************************************
|
||||||
|
|
||||||
- *DO NOT* submit bugs for a source install of v3, ONLY tagged versions, e.g. v3.0.0-alpha.11
|
|
||||||
- *DO NOT* submit PRs for v3 alpha enhancements, unless you have opened a post on the discord channel.
|
- *DO NOT* submit PRs for v3 alpha enhancements, unless you have opened a post on the discord channel.
|
||||||
All enhancements must be discussed first.
|
All enhancements must be discussed first.
|
||||||
The feedback guide for v3 is here: https://v3alpha.wails.io/getting-started/feedback/
|
The feedback guide for v3 is here: https://v3alpha.wails.io/getting-started/feedback/
|
||||||
|
|
@ -48,7 +47,7 @@ Please paste the output of `wails doctor`. If you are unable to run this command
|
||||||
|
|
||||||
# Checklist:
|
# Checklist:
|
||||||
|
|
||||||
- [ ] I have updated `v3/UNRELEASED_CHANGELOG.md` with details of this PR
|
- [ ] I have updated `website/src/pages/changelog.mdx` with details of this PR
|
||||||
- [ ] My code follows the general coding style of this project
|
- [ ] My code follows the general coding style of this project
|
||||||
- [ ] I have performed a self-review of my own code
|
- [ ] I have performed a self-review of my own code
|
||||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||||
|
|
|
||||||
2
.github/workflows/auto-label-issues.yml
vendored
|
|
@ -3,7 +3,7 @@ name: Auto Label Issues
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
types: [opened, edited, reopened]
|
types: [opened, edited, reopened]
|
||||||
pull_request_target:
|
pull_request:
|
||||||
types: [opened, edited, reopened, synchronize]
|
types: [opened, edited, reopened, synchronize]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
||||||
372
.github/workflows/automated-releases.yml
vendored
|
|
@ -1,372 +0,0 @@
|
||||||
name: Automated Nightly Releases
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
force_release:
|
|
||||||
description: 'Force release even if no changes detected'
|
|
||||||
required: false
|
|
||||||
default: false
|
|
||||||
type: boolean
|
|
||||||
dry_run:
|
|
||||||
description: 'Run in dry-run mode (no actual releases)'
|
|
||||||
required: false
|
|
||||||
default: false
|
|
||||||
type: boolean
|
|
||||||
# schedule:
|
|
||||||
# Run at 2 AM UTC every day - DISABLED for safety until ready
|
|
||||||
# - cron: '0 2 * * *'
|
|
||||||
|
|
||||||
env:
|
|
||||||
GO_VERSION: '1.24'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-permissions:
|
|
||||||
name: Check Release Permissions
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
authorized: ${{ steps.check.outputs.authorized }}
|
|
||||||
steps:
|
|
||||||
- name: Check if user is authorized for releases
|
|
||||||
id: check
|
|
||||||
run: |
|
|
||||||
# Only allow specific users to trigger releases
|
|
||||||
AUTHORIZED_USERS="leaanthony"
|
|
||||||
|
|
||||||
if [[ "$AUTHORIZED_USERS" == *"${{ github.actor }}"* ]]; then
|
|
||||||
echo "✅ User ${{ github.actor }} is authorized for releases"
|
|
||||||
echo "authorized=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "❌ User ${{ github.actor }} is not authorized for releases"
|
|
||||||
echo "authorized=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
detect-v2-changes:
|
|
||||||
name: Detect v2 Changes
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: check-permissions
|
|
||||||
if: needs.check-permissions.outputs.authorized == 'true'
|
|
||||||
outputs:
|
|
||||||
has_changes: ${{ steps.changes.outputs.has_changes }}
|
|
||||||
commits_since_last: ${{ steps.changes.outputs.commits_since_last }}
|
|
||||||
last_release_tag: ${{ steps.changes.outputs.last_release_tag }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Check for v2 changes since last release
|
|
||||||
id: changes
|
|
||||||
run: |
|
|
||||||
echo "🔍 Checking for v2 changes since last release..."
|
|
||||||
|
|
||||||
# Find the last v2 release tag
|
|
||||||
LAST_TAG=$(git tag -l "v2.*" --sort=-version:refname | head -n 1)
|
|
||||||
if [ -z "$LAST_TAG" ]; then
|
|
||||||
echo "No previous v2 tags found, assuming first release"
|
|
||||||
LAST_TAG=$(git rev-list --max-parents=0 HEAD)
|
|
||||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
|
||||||
echo "commits_since_last=999" >> $GITHUB_OUTPUT
|
|
||||||
echo "last_release_tag=none" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "Last v2 release tag: $LAST_TAG"
|
|
||||||
echo "last_release_tag=$LAST_TAG" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
# Count commits since last release affecting v2 or root files
|
|
||||||
COMMITS_COUNT=$(git rev-list --count ${LAST_TAG}..HEAD -- v2/ website/ README.md CHANGELOG.md || echo "0")
|
|
||||||
echo "Commits since last v2 release: $COMMITS_COUNT"
|
|
||||||
echo "commits_since_last=$COMMITS_COUNT" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
if [ "$COMMITS_COUNT" -gt 0 ] || [ "${{ github.event.inputs.force_release }}" == "true" ]; then
|
|
||||||
echo "✅ Changes detected or forced release"
|
|
||||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "ℹ️ No changes detected since last release"
|
|
||||||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
detect-v3-changes:
|
|
||||||
name: Detect v3-alpha Changes
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: check-permissions
|
|
||||||
if: needs.check-permissions.outputs.authorized == 'true'
|
|
||||||
outputs:
|
|
||||||
has_changes: ${{ steps.changes.outputs.has_changes }}
|
|
||||||
commits_since_last: ${{ steps.changes.outputs.commits_since_last }}
|
|
||||||
last_release_tag: ${{ steps.changes.outputs.last_release_tag }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout v3-alpha branch
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: v3-alpha
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Check for v3-alpha changes since last release
|
|
||||||
id: changes
|
|
||||||
run: |
|
|
||||||
echo "🔍 Checking for v3-alpha changes since last release..."
|
|
||||||
|
|
||||||
# Find the last v3 alpha release tag
|
|
||||||
LAST_TAG=$(git tag -l "v3.*-alpha.*" --sort=-version:refname | head -n 1)
|
|
||||||
if [ -z "$LAST_TAG" ]; then
|
|
||||||
echo "No previous v3-alpha tags found, assuming first release"
|
|
||||||
LAST_TAG=$(git rev-list --max-parents=0 HEAD)
|
|
||||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
|
||||||
echo "commits_since_last=999" >> $GITHUB_OUTPUT
|
|
||||||
echo "last_release_tag=none" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "Last v3-alpha release tag: $LAST_TAG"
|
|
||||||
echo "last_release_tag=$LAST_TAG" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
# Count commits since last release affecting v3 or docs
|
|
||||||
COMMITS_COUNT=$(git rev-list --count ${LAST_TAG}..HEAD -- v3/ docs/ || echo "0")
|
|
||||||
echo "Commits since last v3-alpha release: $COMMITS_COUNT"
|
|
||||||
echo "commits_since_last=$COMMITS_COUNT" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
if [ "$COMMITS_COUNT" -gt 0 ] || [ "${{ github.event.inputs.force_release }}" == "true" ]; then
|
|
||||||
echo "✅ Changes detected or forced release"
|
|
||||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "ℹ️ No changes detected since last release"
|
|
||||||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
release-v2:
|
|
||||||
name: Create v2 Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [check-permissions, detect-v2-changes]
|
|
||||||
if: |
|
|
||||||
needs.check-permissions.outputs.authorized == 'true' &&
|
|
||||||
needs.detect-v2-changes.outputs.has_changes == 'true'
|
|
||||||
outputs:
|
|
||||||
version: ${{ steps.release.outputs.version }}
|
|
||||||
release_notes: ${{ steps.release.outputs.release_notes }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Setup Go
|
|
||||||
uses: actions/setup-go@v4
|
|
||||||
with:
|
|
||||||
go-version: ${{ env.GO_VERSION }}
|
|
||||||
|
|
||||||
- name: Run v2 release script and extract notes
|
|
||||||
id: release
|
|
||||||
run: |
|
|
||||||
echo "🚀 Running v2 release script..."
|
|
||||||
cd v2/tools/release
|
|
||||||
|
|
||||||
# Run release script and capture output
|
|
||||||
RELEASE_OUTPUT=$(go run release.go 2>&1)
|
|
||||||
echo "$RELEASE_OUTPUT"
|
|
||||||
|
|
||||||
# Extract version from output or version file
|
|
||||||
NEW_VERSION=$(cat ../../cmd/wails/internal/version.txt)
|
|
||||||
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
# Extract release notes from delimited output
|
|
||||||
RELEASE_NOTES=$(echo "$RELEASE_OUTPUT" | sed -n '/=== RELEASE NOTES FOR/,/=== END RELEASE NOTES ===/p' | sed '1d;$d')
|
|
||||||
|
|
||||||
# Save release notes to file for multiline output
|
|
||||||
echo "$RELEASE_NOTES" > ../../../release_notes_v2.md
|
|
||||||
|
|
||||||
# Set output (escape for GitHub Actions)
|
|
||||||
{
|
|
||||||
echo "release_notes<<EOF"
|
|
||||||
echo "$RELEASE_NOTES"
|
|
||||||
echo "EOF"
|
|
||||||
} >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
echo "✅ v2 release script completed - version: $NEW_VERSION"
|
|
||||||
|
|
||||||
- name: Create v2 git tag and release
|
|
||||||
if: github.event.inputs.dry_run != 'true'
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
VERSION="${{ steps.release.outputs.version }}"
|
|
||||||
echo "📝 Creating v2 release: $VERSION"
|
|
||||||
|
|
||||||
# Configure git
|
|
||||||
git config user.name "github-actions[bot]"
|
|
||||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
||||||
|
|
||||||
# Commit the changelog changes
|
|
||||||
git add website/src/pages/changelog.mdx v2/cmd/wails/internal/version.txt
|
|
||||||
git commit -m "chore: release $VERSION
|
|
||||||
|
|
||||||
Automated release created by GitHub Actions
|
|
||||||
|
|
||||||
🤖 Generated with [Claude Code](https://claude.ai/code)
|
|
||||||
|
|
||||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
||||||
|
|
||||||
# Create and push tag
|
|
||||||
git tag -a "$VERSION" -m "Release $VERSION"
|
|
||||||
git push origin master
|
|
||||||
git push origin "$VERSION"
|
|
||||||
|
|
||||||
# Create GitHub release with notes
|
|
||||||
gh release create "$VERSION" \
|
|
||||||
--title "Release $VERSION" \
|
|
||||||
--notes-file release_notes_v2.md \
|
|
||||||
--target master
|
|
||||||
|
|
||||||
- name: Log dry-run results for v2
|
|
||||||
if: github.event.inputs.dry_run == 'true'
|
|
||||||
run: |
|
|
||||||
echo "🧪 DRY RUN - Would have created v2 release:"
|
|
||||||
echo "Version: ${{ steps.release.outputs.version }}"
|
|
||||||
echo "Release Notes:"
|
|
||||||
cat release_notes_v2.md
|
|
||||||
|
|
||||||
release-v3:
|
|
||||||
name: Create v3-alpha Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [check-permissions, detect-v3-changes]
|
|
||||||
if: |
|
|
||||||
needs.check-permissions.outputs.authorized == 'true' &&
|
|
||||||
needs.detect-v3-changes.outputs.has_changes == 'true'
|
|
||||||
outputs:
|
|
||||||
version: ${{ steps.release.outputs.version }}
|
|
||||||
release_notes: ${{ steps.release.outputs.release_notes }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout v3-alpha branch
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: v3-alpha
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Setup Go
|
|
||||||
uses: actions/setup-go@v4
|
|
||||||
with:
|
|
||||||
go-version: ${{ env.GO_VERSION }}
|
|
||||||
|
|
||||||
- name: Run v3 release script and extract notes
|
|
||||||
id: release
|
|
||||||
run: |
|
|
||||||
echo "🚀 Running v3-alpha release script..."
|
|
||||||
cd v3/tasks/release
|
|
||||||
|
|
||||||
# Run release script and capture output
|
|
||||||
RELEASE_OUTPUT=$(go run release.go 2>&1)
|
|
||||||
echo "$RELEASE_OUTPUT"
|
|
||||||
|
|
||||||
# Extract version from output or version file
|
|
||||||
NEW_VERSION=$(cat ../../internal/version/version.txt)
|
|
||||||
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
# Extract release notes from delimited output
|
|
||||||
RELEASE_NOTES=$(echo "$RELEASE_OUTPUT" | sed -n '/=== RELEASE NOTES FOR/,/=== END RELEASE NOTES ===/p' | sed '1d;$d')
|
|
||||||
|
|
||||||
# Save release notes to file for multiline output
|
|
||||||
echo "$RELEASE_NOTES" > ../../../release_notes_v3.md
|
|
||||||
|
|
||||||
# Set output (escape for GitHub Actions)
|
|
||||||
{
|
|
||||||
echo "release_notes<<EOF"
|
|
||||||
echo "$RELEASE_NOTES"
|
|
||||||
echo "EOF"
|
|
||||||
} >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
echo "✅ v3-alpha release script completed - version: $NEW_VERSION"
|
|
||||||
|
|
||||||
- name: Create v3-alpha git tag and release
|
|
||||||
if: github.event.inputs.dry_run != 'true'
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
VERSION="${{ steps.release.outputs.version }}"
|
|
||||||
echo "📝 Creating v3-alpha release: $VERSION"
|
|
||||||
|
|
||||||
# Configure git
|
|
||||||
git config user.name "github-actions[bot]"
|
|
||||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
||||||
|
|
||||||
# Commit the changelog changes
|
|
||||||
git add docs/src/content/docs/changelog.mdx v3/internal/version/version.txt
|
|
||||||
git commit -m "chore: release $VERSION
|
|
||||||
|
|
||||||
Automated v3-alpha release created by GitHub Actions
|
|
||||||
|
|
||||||
🤖 Generated with [Claude Code](https://claude.ai/code)
|
|
||||||
|
|
||||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
||||||
|
|
||||||
# Create and push tag
|
|
||||||
git tag -a "$VERSION" -m "Release $VERSION"
|
|
||||||
git push origin v3-alpha
|
|
||||||
git push origin "$VERSION"
|
|
||||||
|
|
||||||
# Create GitHub release with notes
|
|
||||||
gh release create "$VERSION" \
|
|
||||||
--title "Release $VERSION" \
|
|
||||||
--notes-file release_notes_v3.md \
|
|
||||||
--target v3-alpha \
|
|
||||||
--prerelease
|
|
||||||
|
|
||||||
- name: Log dry-run results for v3-alpha
|
|
||||||
if: github.event.inputs.dry_run == 'true'
|
|
||||||
run: |
|
|
||||||
echo "🧪 DRY RUN - Would have created v3-alpha release:"
|
|
||||||
echo "Version: ${{ steps.release.outputs.version }}"
|
|
||||||
echo "Release Notes:"
|
|
||||||
cat release_notes_v3.md
|
|
||||||
|
|
||||||
summary:
|
|
||||||
name: Release Summary
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [check-permissions, detect-v2-changes, detect-v3-changes, release-v2, release-v3]
|
|
||||||
if: always() && needs.check-permissions.outputs.authorized == 'true'
|
|
||||||
steps:
|
|
||||||
- name: Create release summary
|
|
||||||
run: |
|
|
||||||
echo "# 🚀 Automated Release Summary" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "**Repository**: ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "**Triggered by**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "**Dry Run Mode**: ${{ github.event.inputs.dry_run || 'false' }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
|
||||||
# v2 Summary
|
|
||||||
echo "## v2 Release" >> $GITHUB_STEP_SUMMARY
|
|
||||||
if [ "${{ needs.detect-v2-changes.outputs.has_changes }}" == "true" ]; then
|
|
||||||
if [ "${{ needs.release-v2.result }}" == "success" ]; then
|
|
||||||
echo "✅ **v2 Release**: Created successfully" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo " - Version: ${{ needs.release-v2.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo " - Commits since last: ${{ needs.detect-v2-changes.outputs.commits_since_last }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
else
|
|
||||||
echo "❌ **v2 Release**: Failed" >> $GITHUB_STEP_SUMMARY
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "⏭️ **v2 Release**: Skipped (no changes)" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo " - Commits since last: ${{ needs.detect-v2-changes.outputs.commits_since_last }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
fi
|
|
||||||
|
|
||||||
# v3 Summary
|
|
||||||
echo "## v3-alpha Release" >> $GITHUB_STEP_SUMMARY
|
|
||||||
if [ "${{ needs.detect-v3-changes.outputs.has_changes }}" == "true" ]; then
|
|
||||||
if [ "${{ needs.release-v3.result }}" == "success" ]; then
|
|
||||||
echo "✅ **v3-alpha Release**: Created successfully" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo " - Version: ${{ needs.release-v3.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo " - Commits since last: ${{ needs.detect-v3-changes.outputs.commits_since_last }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
else
|
|
||||||
echo "❌ **v3-alpha Release**: Failed" >> $GITHUB_STEP_SUMMARY
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "⏭️ **v3-alpha Release**: Skipped (no changes)" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo " - Commits since last: ${{ needs.detect-v3-changes.outputs.commits_since_last }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "---" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "🤖 **Automated Release System** | Generated with [Claude Code](https://claude.ai/code)" >> $GITHUB_STEP_SUMMARY
|
|
||||||
103
.github/workflows/build-and-test-v3.yml
vendored
|
|
@ -29,68 +29,9 @@ jobs:
|
||||||
echo "approved=false" >> $GITHUB_OUTPUT
|
echo "approved=false" >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test_js:
|
|
||||||
name: Run JS Tests
|
|
||||||
needs: check_approval
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.base_ref == 'v3-alpha'
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [20.x]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
|
|
||||||
- name: Install Task
|
|
||||||
uses: arduino/setup-task@v2
|
|
||||||
with:
|
|
||||||
version: 3.x
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
working-directory: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npx --yes esbuild@latest --version
|
|
||||||
|
|
||||||
- name: Clean build artifacts
|
|
||||||
working-directory: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
run: npm run clean
|
|
||||||
|
|
||||||
- name: Type-check runtime
|
|
||||||
working-directory: v3
|
|
||||||
run: task runtime:check
|
|
||||||
|
|
||||||
- name: Test runtime
|
|
||||||
working-directory: v3
|
|
||||||
run: task runtime:test
|
|
||||||
|
|
||||||
- name: Check that the bundled runtime builds
|
|
||||||
working-directory: v3
|
|
||||||
run: task runtime:build
|
|
||||||
|
|
||||||
- name: Check that the npm package builds
|
|
||||||
working-directory: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
run: npm run build
|
|
||||||
|
|
||||||
- name: Store runtime build artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: runtime-build-artifacts
|
|
||||||
path: |
|
|
||||||
v3/internal/runtime/desktop/@wailsio/runtime/dist/
|
|
||||||
v3/internal/runtime/desktop/@wailsio/runtime/types/
|
|
||||||
v3/internal/runtime/desktop/@wailsio/runtime/tsconfig.tsbuildinfo
|
|
||||||
|
|
||||||
test_go:
|
test_go:
|
||||||
name: Run Go Tests v3
|
name: Run Go Tests v3
|
||||||
needs: [check_approval, test_js]
|
needs: check_approval
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
if: github.base_ref == 'v3-alpha'
|
if: github.base_ref == 'v3-alpha'
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -114,7 +55,6 @@ jobs:
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
cache: true
|
|
||||||
cache-dependency-path: "v3/go.sum"
|
cache-dependency-path: "v3/go.sum"
|
||||||
|
|
||||||
- name: Install Task
|
- name: Install Task
|
||||||
|
|
@ -123,18 +63,9 @@ jobs:
|
||||||
version: 3.x
|
version: 3.x
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Retrieve runtime build artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: runtime-build-artifacts
|
|
||||||
path: v3/internal/runtime/desktop/@wailsio/runtime/
|
|
||||||
|
|
||||||
- name: Build Examples
|
- name: Build Examples
|
||||||
working-directory: v3
|
working-directory: v3
|
||||||
run: |
|
run: task test:examples
|
||||||
echo "Starting example compilation tests..."
|
|
||||||
task test:examples
|
|
||||||
echo "Example compilation tests completed successfully"
|
|
||||||
|
|
||||||
- name: Run tests (mac)
|
- name: Run tests (mac)
|
||||||
if: matrix.os == 'macos-latest'
|
if: matrix.os == 'macos-latest'
|
||||||
|
|
@ -162,16 +93,31 @@ jobs:
|
||||||
working-directory: v3
|
working-directory: v3
|
||||||
run: task generator:test:check
|
run: task generator:test:check
|
||||||
|
|
||||||
cleanup:
|
test_js:
|
||||||
name: Cleanup build artifacts
|
name: Run JS Tests
|
||||||
if: always()
|
needs: check_approval
|
||||||
needs: [test_js, test_go]
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: github.base_ref == 'v3-alpha'
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [20.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: geekyeggo/delete-artifact@v5
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
name: runtime-build-artifacts
|
node-version: ${{ matrix.node-version }}
|
||||||
failOnError: false
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install
|
||||||
|
working-directory: v2/internal/frontend/runtime
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: npm test
|
||||||
|
working-directory: v2/internal/frontend/runtime
|
||||||
|
|
||||||
test_templates:
|
test_templates:
|
||||||
name: Test Templates
|
name: Test Templates
|
||||||
|
|
@ -211,7 +157,6 @@ jobs:
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
cache: true
|
|
||||||
cache-dependency-path: "v3/go.sum"
|
cache-dependency-path: "v3/go.sum"
|
||||||
|
|
||||||
- name: Install Task
|
- name: Install Task
|
||||||
|
|
|
||||||
36
.github/workflows/build-and-test.yml
vendored
|
|
@ -12,8 +12,8 @@ jobs:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest, macos-11]
|
os: [ubuntu-22.04, ubuntu-24.04, windows-latest, macos-latest]
|
||||||
go-version: ['1.21']
|
go-version: ['1.22']
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
|
|
@ -28,7 +28,7 @@ jobs:
|
||||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||||
if: matrix.os == 'ubuntu-24.04'
|
if: matrix.os == 'ubuntu-24.04'
|
||||||
with:
|
with:
|
||||||
packages: libgtk-3-dev libwebkit2gtk-4.1-dev build-essential pkg-config
|
packages: libgtk-3-dev libwebkit2gtk-4.1-dev build-essential pkg-config libegl1
|
||||||
version: 1.0
|
version: 1.0
|
||||||
|
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
|
|
@ -38,14 +38,14 @@ jobs:
|
||||||
cache-dependency-path: ./v2/go.sum
|
cache-dependency-path: ./v2/go.sum
|
||||||
|
|
||||||
- name: Run tests (mac)
|
- name: Run tests (mac)
|
||||||
if: matrix.os == 'macos-latest' || matrix.os == 'macos-11'
|
if: matrix.os == 'macos-latest'
|
||||||
env:
|
env:
|
||||||
CGO_LDFLAGS: -framework UniformTypeIdentifiers -mmacosx-version-min=10.13
|
CGO_LDFLAGS: -framework UniformTypeIdentifiers -mmacosx-version-min=10.13
|
||||||
working-directory: ./v2
|
working-directory: ./v2
|
||||||
run: go test -v ./...
|
run: go test -v ./...
|
||||||
|
|
||||||
- name: Run tests (!mac)
|
- name: Run tests (!mac)
|
||||||
if: matrix.os != 'macos-latest' && matrix.os != 'macos-11' && matrix.os != 'ubuntu-24.04'
|
if: matrix.os != 'macos-latest' && matrix.os != 'ubuntu-24.04'
|
||||||
working-directory: ./v2
|
working-directory: ./v2
|
||||||
run: go test -v ./...
|
run: go test -v ./...
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, windows-latest, macos-latest, ubuntu-24.04, macos-11]
|
os: [ubuntu-22.04, windows-latest, macos-latest, ubuntu-24.04]
|
||||||
template:
|
template:
|
||||||
[
|
[
|
||||||
svelte,
|
svelte,
|
||||||
|
|
@ -103,13 +103,13 @@ jobs:
|
||||||
vanilla-ts,
|
vanilla-ts,
|
||||||
plain,
|
plain,
|
||||||
]
|
]
|
||||||
go-version: ['1.21']
|
go-version: ['1.22']
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
cache-dependency-path: ./v2/go.sum
|
cache-dependency-path: ./v2/go.sum
|
||||||
|
|
@ -120,13 +120,25 @@ jobs:
|
||||||
go install
|
go install
|
||||||
wails -help
|
wails -help
|
||||||
|
|
||||||
- name: Install linux dependencies ( 22.04 )
|
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||||
if: matrix.os == 'ubuntu-22.04'
|
if: matrix.os == 'ubuntu-22.04'
|
||||||
run: sudo apt-get update -y && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev build-essential pkg-config
|
with:
|
||||||
|
packages: libgtk-3-dev libwebkit2gtk-4.0-dev build-essential pkg-config
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
- name: Install linux dependencies ( 24.04 )
|
# - name: Install linux dependencies ( 22.04 )
|
||||||
|
# if: matrix.os == 'ubuntu-22.04'
|
||||||
|
# run: sudo apt-get update -y && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev build-essential pkg-config
|
||||||
|
|
||||||
|
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||||
if: matrix.os == 'ubuntu-24.04'
|
if: matrix.os == 'ubuntu-24.04'
|
||||||
run: sudo apt-get update -y && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev build-essential pkg-config
|
with:
|
||||||
|
packages: libgtk-3-dev libwebkit2gtk-4.1-dev build-essential pkg-config libegl1
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
|
# - name: Install linux dependencies ( 24.04 )
|
||||||
|
# if: matrix.os == 'ubuntu-24.04'
|
||||||
|
# run: sudo apt-get update -y && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev build-essential pkg-config
|
||||||
|
|
||||||
- name: Generate & Build template '${{ matrix.template }}'
|
- name: Generate & Build template '${{ matrix.template }}'
|
||||||
if: matrix.os != 'ubuntu-24.04'
|
if: matrix.os != 'ubuntu-24.04'
|
||||||
|
|
|
||||||
423
.github/workflows/build-cross-image.yml
vendored
Normal file
|
|
@ -0,0 +1,423 @@
|
||||||
|
name: Build Cross-Compiler Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
branch:
|
||||||
|
description: 'Branch containing Dockerfile'
|
||||||
|
required: true
|
||||||
|
default: 'v3-alpha'
|
||||||
|
sdk_version:
|
||||||
|
description: 'macOS SDK version'
|
||||||
|
required: true
|
||||||
|
default: '14.5'
|
||||||
|
zig_version:
|
||||||
|
description: 'Zig version'
|
||||||
|
required: true
|
||||||
|
default: '0.14.0'
|
||||||
|
image_version:
|
||||||
|
description: 'Image version tag'
|
||||||
|
required: true
|
||||||
|
default: 'latest'
|
||||||
|
skip_tests:
|
||||||
|
description: 'Skip cross-compilation tests'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
type: boolean
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- v3-alpha
|
||||||
|
paths:
|
||||||
|
- 'v3/internal/commands/build_assets/docker/Dockerfile.cross'
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: wailsapp/wails-cross
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
outputs:
|
||||||
|
image_tag: ${{ steps.vars.outputs.image_version }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.branch || github.ref }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set build variables
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
echo "sdk_version=${{ inputs.sdk_version || '14.5' }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "zig_version=${{ inputs.zig_version || '0.14.0' }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "image_version=${{ inputs.image_version || 'latest' }}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Extract metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=raw,value=latest
|
||||||
|
type=raw,value=${{ steps.vars.outputs.image_version }}
|
||||||
|
type=raw,value=sdk-${{ steps.vars.outputs.sdk_version }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: v3/internal/commands/build_assets/docker
|
||||||
|
file: v3/internal/commands/build_assets/docker/Dockerfile.cross
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: |
|
||||||
|
${{ steps.meta.outputs.labels }}
|
||||||
|
io.wails.zig.version=${{ steps.vars.outputs.zig_version }}
|
||||||
|
io.wails.sdk.version=${{ steps.vars.outputs.sdk_version }}
|
||||||
|
build-args: |
|
||||||
|
ZIG_VERSION=${{ steps.vars.outputs.zig_version }}
|
||||||
|
MACOS_SDK_VERSION=${{ steps.vars.outputs.sdk_version }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
# Test cross-compilation for all platforms
|
||||||
|
test-cross-compile:
|
||||||
|
needs: build
|
||||||
|
if: ${{ inputs.skip_tests != 'true' }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# Darwin targets (Zig + macOS SDK) - no platform emulation needed
|
||||||
|
- os: darwin
|
||||||
|
arch: arm64
|
||||||
|
platform: ""
|
||||||
|
expected_file: "Mach-O 64-bit.*arm64"
|
||||||
|
- os: darwin
|
||||||
|
arch: amd64
|
||||||
|
platform: ""
|
||||||
|
expected_file: "Mach-O 64-bit.*x86_64"
|
||||||
|
# Linux targets (GCC) - need platform to match architecture
|
||||||
|
- os: linux
|
||||||
|
arch: amd64
|
||||||
|
platform: "linux/amd64"
|
||||||
|
expected_file: "ELF 64-bit LSB.*x86-64"
|
||||||
|
- os: linux
|
||||||
|
arch: arm64
|
||||||
|
platform: "linux/arm64"
|
||||||
|
expected_file: "ELF 64-bit LSB.*ARM aarch64"
|
||||||
|
# Windows targets (Zig + mingw) - no platform emulation needed
|
||||||
|
- os: windows
|
||||||
|
arch: amd64
|
||||||
|
platform: ""
|
||||||
|
expected_file: "PE32\\+ executable.*x86-64"
|
||||||
|
- os: windows
|
||||||
|
arch: arm64
|
||||||
|
platform: ""
|
||||||
|
expected_file: "PE32\\+ executable.*Aarch64"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.branch || github.ref }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
if: matrix.platform != ''
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Log in to Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create test CGO project
|
||||||
|
run: |
|
||||||
|
mkdir -p test-project
|
||||||
|
cd test-project
|
||||||
|
|
||||||
|
# Create a minimal CGO test program
|
||||||
|
cat > main.go << 'EOF'
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int add(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
result := C.add(1, 2)
|
||||||
|
fmt.Printf("CGO test: 1 + 2 = %d\n", result)
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > go.mod << 'EOF'
|
||||||
|
module test-cgo
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Build ${{ matrix.os }}/${{ matrix.arch }} (CGO)
|
||||||
|
run: |
|
||||||
|
cd test-project
|
||||||
|
PLATFORM_FLAG=""
|
||||||
|
if [ -n "${{ matrix.platform }}" ]; then
|
||||||
|
PLATFORM_FLAG="--platform ${{ matrix.platform }}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker run --rm $PLATFORM_FLAG \
|
||||||
|
-v "$(pwd):/app" \
|
||||||
|
-e APP_NAME="test-cgo" \
|
||||||
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build.outputs.image_tag || 'latest' }} \
|
||||||
|
${{ matrix.os }} ${{ matrix.arch }}
|
||||||
|
|
||||||
|
- name: Verify binary format
|
||||||
|
run: |
|
||||||
|
cd test-project/bin
|
||||||
|
ls -la
|
||||||
|
|
||||||
|
# Find the built binary
|
||||||
|
if [ "${{ matrix.os }}" = "windows" ]; then
|
||||||
|
BINARY=$(ls test-cgo-${{ matrix.os }}-${{ matrix.arch }}.exe 2>/dev/null || ls *.exe | head -1)
|
||||||
|
else
|
||||||
|
BINARY=$(ls test-cgo-${{ matrix.os }}-${{ matrix.arch }} 2>/dev/null || ls test-cgo* | grep -v '.exe' | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Binary: $BINARY"
|
||||||
|
FILE_OUTPUT=$(file "$BINARY")
|
||||||
|
echo "File output: $FILE_OUTPUT"
|
||||||
|
|
||||||
|
# Verify the binary format matches expected
|
||||||
|
if echo "$FILE_OUTPUT" | grep -qE "${{ matrix.expected_file }}"; then
|
||||||
|
echo "✅ Binary format verified: ${{ matrix.os }}/${{ matrix.arch }}"
|
||||||
|
else
|
||||||
|
echo "❌ Binary format mismatch!"
|
||||||
|
echo "Expected pattern: ${{ matrix.expected_file }}"
|
||||||
|
echo "Got: $FILE_OUTPUT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check library dependencies (Linux only)
|
||||||
|
if: matrix.os == 'linux'
|
||||||
|
run: |
|
||||||
|
cd test-project/bin
|
||||||
|
BINARY=$(ls test-cgo-${{ matrix.os }}-${{ matrix.arch }} 2>/dev/null || ls test-cgo* | grep -v '.exe' | head -1)
|
||||||
|
|
||||||
|
echo "## Library Dependencies for $BINARY"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Use readelf to show dynamic dependencies
|
||||||
|
echo "### NEEDED libraries:"
|
||||||
|
readelf -d "$BINARY" | grep NEEDED || echo "No dynamic dependencies (statically linked)"
|
||||||
|
|
||||||
|
# Verify expected libraries are linked
|
||||||
|
echo ""
|
||||||
|
echo "### Verifying required libraries..."
|
||||||
|
NEEDED=$(readelf -d "$BINARY" | grep NEEDED)
|
||||||
|
|
||||||
|
MISSING=""
|
||||||
|
for lib in libwebkit2gtk-4.1.so libgtk-3.so libglib-2.0.so libc.so; do
|
||||||
|
if echo "$NEEDED" | grep -q "$lib"; then
|
||||||
|
echo "✅ $lib"
|
||||||
|
else
|
||||||
|
echo "❌ $lib MISSING"
|
||||||
|
MISSING="$MISSING $lib"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$MISSING" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "ERROR: Missing required libraries:$MISSING"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test non-CGO builds (pure Go cross-compilation)
|
||||||
|
test-non-cgo:
|
||||||
|
needs: build
|
||||||
|
if: ${{ inputs.skip_tests != 'true' }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: darwin
|
||||||
|
arch: arm64
|
||||||
|
expected_file: "Mach-O 64-bit.*arm64"
|
||||||
|
- os: darwin
|
||||||
|
arch: amd64
|
||||||
|
expected_file: "Mach-O 64-bit.*x86_64"
|
||||||
|
- os: linux
|
||||||
|
arch: amd64
|
||||||
|
expected_file: "ELF 64-bit LSB"
|
||||||
|
- os: linux
|
||||||
|
arch: arm64
|
||||||
|
expected_file: "ELF 64-bit LSB.*ARM aarch64"
|
||||||
|
- os: windows
|
||||||
|
arch: amd64
|
||||||
|
expected_file: "PE32\\+ executable.*x86-64"
|
||||||
|
- os: windows
|
||||||
|
arch: arm64
|
||||||
|
expected_file: "PE32\\+ executable.*Aarch64"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.branch || github.ref }}
|
||||||
|
|
||||||
|
- name: Log in to Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create test non-CGO project
|
||||||
|
run: |
|
||||||
|
mkdir -p test-project
|
||||||
|
cd test-project
|
||||||
|
|
||||||
|
# Create a pure Go test program (no CGO)
|
||||||
|
cat > main.go << 'EOF'
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Pure Go cross-compilation test")
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat > go.mod << 'EOF'
|
||||||
|
module test-pure-go
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Build ${{ matrix.os }}/${{ matrix.arch }} (non-CGO)
|
||||||
|
run: |
|
||||||
|
cd test-project
|
||||||
|
|
||||||
|
# For non-CGO, we can use any platform since Go handles cross-compilation
|
||||||
|
# We set CGO_ENABLED=0 to ensure pure Go build
|
||||||
|
docker run --rm \
|
||||||
|
-v "$(pwd):/app" \
|
||||||
|
-e APP_NAME="test-pure-go" \
|
||||||
|
-e CGO_ENABLED=0 \
|
||||||
|
--entrypoint /bin/sh \
|
||||||
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build.outputs.image_tag || 'latest' }} \
|
||||||
|
-c "GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} go build -o bin/test-pure-go-${{ matrix.os }}-${{ matrix.arch }}${{ matrix.os == 'windows' && '.exe' || '' }} ."
|
||||||
|
|
||||||
|
- name: Verify binary format
|
||||||
|
run: |
|
||||||
|
cd test-project/bin
|
||||||
|
ls -la
|
||||||
|
|
||||||
|
# Find the built binary
|
||||||
|
if [ "${{ matrix.os }}" = "windows" ]; then
|
||||||
|
BINARY="test-pure-go-${{ matrix.os }}-${{ matrix.arch }}.exe"
|
||||||
|
else
|
||||||
|
BINARY="test-pure-go-${{ matrix.os }}-${{ matrix.arch }}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Binary: $BINARY"
|
||||||
|
FILE_OUTPUT=$(file "$BINARY")
|
||||||
|
echo "File output: $FILE_OUTPUT"
|
||||||
|
|
||||||
|
# Verify the binary format matches expected
|
||||||
|
if echo "$FILE_OUTPUT" | grep -qE "${{ matrix.expected_file }}"; then
|
||||||
|
echo "✅ Binary format verified: ${{ matrix.os }}/${{ matrix.arch }} (non-CGO)"
|
||||||
|
else
|
||||||
|
echo "❌ Binary format mismatch!"
|
||||||
|
echo "Expected pattern: ${{ matrix.expected_file }}"
|
||||||
|
echo "Got: $FILE_OUTPUT"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check library dependencies (Linux only)
|
||||||
|
if: matrix.os == 'linux'
|
||||||
|
run: |
|
||||||
|
cd test-project/bin
|
||||||
|
BINARY="test-pure-go-${{ matrix.os }}-${{ matrix.arch }}"
|
||||||
|
|
||||||
|
echo "## Library Dependencies for $BINARY (non-CGO)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Non-CGO builds should have minimal dependencies (just libc or statically linked)
|
||||||
|
echo "### NEEDED libraries:"
|
||||||
|
readelf -d "$BINARY" | grep NEEDED || echo "No dynamic dependencies (statically linked)"
|
||||||
|
|
||||||
|
# Verify NO GTK/WebKit libraries (since CGO is disabled)
|
||||||
|
NEEDED=$(readelf -d "$BINARY" | grep NEEDED || true)
|
||||||
|
if echo "$NEEDED" | grep -q "libwebkit\|libgtk"; then
|
||||||
|
echo "❌ ERROR: Non-CGO binary should not link to GTK/WebKit!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✅ Confirmed: No GTK/WebKit dependencies (expected for non-CGO)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Summary job
|
||||||
|
test-summary:
|
||||||
|
needs: [build, test-cross-compile, test-non-cgo]
|
||||||
|
if: always() && inputs.skip_tests != 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check test results
|
||||||
|
run: |
|
||||||
|
echo "## Cross-Compilation Test Results" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ "${{ needs.test-cross-compile.result }}" = "success" ]; then
|
||||||
|
echo "✅ **CGO Tests**: All passed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "❌ **CGO Tests**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.test-non-cgo.result }}" = "success" ]; then
|
||||||
|
echo "✅ **Non-CGO Tests**: All passed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "❌ **Non-CGO Tests**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "### Tested Platforms" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Platform | Architecture | CGO | Non-CGO |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|----------|-------------|-----|---------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Darwin | arm64 | ✅ | ✅ |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Darwin | amd64 | ✅ | ✅ |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Linux | arm64 | ✅ | ✅ |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Linux | amd64 | ✅ | ✅ |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Windows | arm64 | ✅ | ✅ |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Windows | amd64 | ✅ | ✅ |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# Fail if any test failed
|
||||||
|
if [ "${{ needs.test-cross-compile.result }}" != "success" ] || [ "${{ needs.test-non-cgo.result }}" != "success" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "❌ Some tests failed. Check the individual job logs for details."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
216
.github/workflows/changelog-v3.yml
vendored
Normal file
|
|
@ -0,0 +1,216 @@
|
||||||
|
name: Changelog Validation (v3)
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [ v3-alpha ]
|
||||||
|
paths:
|
||||||
|
- 'docs/src/content/docs/changelog.mdx'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
pr_number:
|
||||||
|
description: 'PR number to validate'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
actions: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout PR code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', github.event.inputs.pr_number) }}
|
||||||
|
fetch-depth: 0
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN || github.token }}
|
||||||
|
|
||||||
|
- name: Get REAL validation script from v3-alpha
|
||||||
|
run: |
|
||||||
|
echo "Fetching the REAL validation script from v3-alpha branch..."
|
||||||
|
git fetch origin v3-alpha
|
||||||
|
git checkout origin/v3-alpha -- v3/scripts/validate-changelog.go
|
||||||
|
|
||||||
|
echo "Validation script fetched successfully:"
|
||||||
|
ls -la v3/scripts/
|
||||||
|
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
|
||||||
|
- name: Get PR information
|
||||||
|
id: pr_info
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||||
|
echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "base_ref=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "pr_number=${{ github.event.inputs.pr_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "base_ref=v3-alpha" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check changelog modifications
|
||||||
|
id: changelog_check
|
||||||
|
run: |
|
||||||
|
echo "Checking PR #${{ steps.pr_info.outputs.pr_number }} for changelog changes"
|
||||||
|
git fetch origin ${{ steps.pr_info.outputs.base_ref }}
|
||||||
|
|
||||||
|
if git diff --name-only origin/${{ steps.pr_info.outputs.base_ref }}..HEAD | grep -q "docs/src/content/docs/changelog.mdx"; then
|
||||||
|
echo "changelog_modified=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✅ Changelog was modified in this PR"
|
||||||
|
else
|
||||||
|
echo "changelog_modified=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "ℹ️ Changelog was not modified - skipping validation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Get changelog diff
|
||||||
|
id: get_diff
|
||||||
|
if: steps.changelog_check.outputs.changelog_modified == 'true'
|
||||||
|
run: |
|
||||||
|
echo "Getting diff for changelog changes..."
|
||||||
|
git diff origin/${{ steps.pr_info.outputs.base_ref }}..HEAD docs/src/content/docs/changelog.mdx | grep "^+" | grep -v "^+++" | sed 's/^+//' > /tmp/pr_added_lines.txt
|
||||||
|
|
||||||
|
echo "Lines added in this PR:"
|
||||||
|
cat /tmp/pr_added_lines.txt
|
||||||
|
echo "Total lines added: $(wc -l < /tmp/pr_added_lines.txt)"
|
||||||
|
|
||||||
|
- name: Validate changelog
|
||||||
|
id: validate
|
||||||
|
if: steps.changelog_check.outputs.changelog_modified == 'true'
|
||||||
|
run: |
|
||||||
|
echo "Running changelog validation..."
|
||||||
|
cd v3/scripts
|
||||||
|
OUTPUT=$(go run validate-changelog.go ../../docs/src/content/docs/changelog.mdx /tmp/pr_added_lines.txt 2>&1)
|
||||||
|
echo "$OUTPUT"
|
||||||
|
|
||||||
|
RESULT=$(echo "$OUTPUT" | grep "VALIDATION_RESULT=" | cut -d'=' -f2)
|
||||||
|
echo "result=$RESULT" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Commit fixes
|
||||||
|
id: commit_fixes
|
||||||
|
if: steps.validate.outputs.result == 'fixed'
|
||||||
|
run: |
|
||||||
|
echo "Committing automatic fixes..."
|
||||||
|
git config --local user.email "action@github.com"
|
||||||
|
git config --local user.name "GitHub Action"
|
||||||
|
|
||||||
|
# Check only the changelog file for changes
|
||||||
|
if git diff --quiet docs/src/content/docs/changelog.mdx; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
echo "committed=false" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
# Ensure validation script doesn't get committed
|
||||||
|
echo "v3/scripts/validate-changelog.go" >> .git/info/exclude
|
||||||
|
# Get the correct branch name to push to
|
||||||
|
REPO_OWNER="wailsapp" # Always wailsapp for this repo
|
||||||
|
|
||||||
|
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||||
|
BRANCH_NAME="${{ github.event.pull_request.head.ref }}"
|
||||||
|
else
|
||||||
|
# For manual workflow dispatch, get PR info
|
||||||
|
PR_INFO=$(gh pr view ${{ steps.pr_info.outputs.pr_number }} --json headRefName,headRepository)
|
||||||
|
BRANCH_NAME=$(echo "$PR_INFO" | jq -r '.headRefName')
|
||||||
|
HEAD_REPO=$(echo "$PR_INFO" | jq -r '.headRepository.name')
|
||||||
|
|
||||||
|
echo "🔍 PR source branch: $BRANCH_NAME"
|
||||||
|
echo "🔍 Head repository: $HEAD_REPO"
|
||||||
|
|
||||||
|
# Don't push if this is from a fork or if branch is v3-alpha (main branch)
|
||||||
|
if [ "$HEAD_REPO" != "wails" ] || [ "$BRANCH_NAME" = "v3-alpha" ]; then
|
||||||
|
echo "⚠️ Cannot push - either fork or direct v3-alpha branch. Manual fix required."
|
||||||
|
echo "committed=false" >> $GITHUB_OUTPUT
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Pushing to branch: $BRANCH_NAME in repo: $REPO_OWNER"
|
||||||
|
|
||||||
|
# Only commit the changelog changes, not the validation script
|
||||||
|
git add docs/src/content/docs/changelog.mdx
|
||||||
|
git commit -m "🤖 Fix changelog: move entries to Unreleased section"
|
||||||
|
|
||||||
|
# Only push if running on the main wailsapp repository
|
||||||
|
if [ "${{ github.repository }}" = "wailsapp/wails" ]; then
|
||||||
|
# Pull latest changes and rebase our commit
|
||||||
|
git fetch origin $BRANCH_NAME
|
||||||
|
git rebase origin/$BRANCH_NAME
|
||||||
|
git push origin HEAD:$BRANCH_NAME
|
||||||
|
else
|
||||||
|
echo "⚠️ Running on fork (${{ github.repository }}). Skipping push - manual fix required."
|
||||||
|
echo "committed=false" >> $GITHUB_OUTPUT
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "committed=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "✅ Changes committed and pushed"
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get PR author for tagging
|
||||||
|
id: pr_author
|
||||||
|
if: steps.validate.outputs.result && github.event.inputs.pr_number
|
||||||
|
run: |
|
||||||
|
PR_AUTHOR=$(gh pr view ${{ steps.pr_info.outputs.pr_number }} --json author --jq '.author.login')
|
||||||
|
echo "author=$PR_AUTHOR" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Comment on PR
|
||||||
|
if: steps.validate.outputs.result && github.event.inputs.pr_number
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const result = '${{ steps.validate.outputs.result }}';
|
||||||
|
const committed = '${{ steps.commit_fixes.outputs.committed }}';
|
||||||
|
const author = '${{ steps.pr_author.outputs.author }}';
|
||||||
|
|
||||||
|
let message;
|
||||||
|
if (result === 'success') {
|
||||||
|
message = '## ✅ Changelog Validation Passed\n\nNo misplaced changelog entries detected.';
|
||||||
|
} else if (result === 'fixed' && committed === 'true') {
|
||||||
|
message = '## 🔧 Changelog Updated\n\nMisplaced entries were automatically moved to the `[Unreleased]` section. The changes have been committed to this PR.';
|
||||||
|
} else if (result === 'fixed' || result === 'cannot_fix' || result === 'error') {
|
||||||
|
// Read the fixed changelog content
|
||||||
|
const fs = require('fs');
|
||||||
|
let fixedContent = '';
|
||||||
|
try {
|
||||||
|
fixedContent = fs.readFileSync('docs/src/content/docs/changelog.mdx', 'utf8');
|
||||||
|
} catch (error) {
|
||||||
|
fixedContent = 'Error reading fixed changelog content';
|
||||||
|
}
|
||||||
|
|
||||||
|
message = '## ⚠️ Changelog Validation Issue\\n\\n' +
|
||||||
|
'@' + author + ' Your PR contains changelog entries that were added to already-released versions. These need to be moved to the `[Unreleased]` section.\\n\\n' +
|
||||||
|
(committed === 'true' ?
|
||||||
|
'✅ **Auto-fix applied**: The changes have been automatically committed to this PR.' :
|
||||||
|
'❌ **Manual fix required**: Please apply the changes shown below manually.') + '\\n\\n' +
|
||||||
|
'<details>\\n' +
|
||||||
|
'<summary>📝 Click to see the corrected changelog content</summary>\\n\\n' +
|
||||||
|
'```mdx\\n' +
|
||||||
|
fixedContent +
|
||||||
|
'\\n```\\n\\n' +
|
||||||
|
'</details>\\n\\n' +
|
||||||
|
'**What happened?** \\n' +
|
||||||
|
'The validation script detected that you added changelog entries to a version section that has already been released (like `v3.0.0-alpha.10`). All new entries should go in the `[Unreleased]` section under the appropriate category (`### Added`, `### Fixed`, etc.).\\n\\n' +
|
||||||
|
(committed !== 'true' ? '**Action needed:** Please copy the corrected content from above and replace your changelog file.' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message) {
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
issue_number: ${{ steps.pr_info.outputs.pr_number }},
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
body: message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Fail if validation failed
|
||||||
|
if: steps.validate.outputs.result == 'cannot_fix' || steps.validate.outputs.result == 'error'
|
||||||
|
run: |
|
||||||
|
echo "❌ Changelog validation failed"
|
||||||
|
exit 1
|
||||||
74
.github/workflows/changelog-validation-v3.yml
vendored
|
|
@ -1,74 +0,0 @@
|
||||||
name: Changelog Validation (v3)
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [ v3-alpha ]
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
pr_number:
|
|
||||||
description: 'PR number to validate (for manual testing)'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
validate-changelog:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event_name == 'pull_request' || github.event.inputs.pr_number
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', github.event.inputs.pr_number) }}
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Setup Go
|
|
||||||
uses: actions/setup-go@v4
|
|
||||||
with:
|
|
||||||
go-version: '1.23'
|
|
||||||
|
|
||||||
- name: Get PR information
|
|
||||||
id: pr_info
|
|
||||||
run: |
|
|
||||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
||||||
echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
|
|
||||||
echo "base_ref=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT
|
|
||||||
else
|
|
||||||
echo "pr_number=${{ github.event.inputs.pr_number }}" >> $GITHUB_OUTPUT
|
|
||||||
echo "base_ref=v3-alpha" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Check if changelog was modified
|
|
||||||
id: changelog_check
|
|
||||||
run: |
|
|
||||||
git fetch origin ${{ steps.pr_info.outputs.base_ref }}
|
|
||||||
if git diff --name-only origin/${{ steps.pr_info.outputs.base_ref }}..HEAD | grep -q "v3/UNRELEASED_CHANGELOG.md"; then
|
|
||||||
echo "changelog_modified=true" >> $GITHUB_OUTPUT
|
|
||||||
echo "✅ UNRELEASED_CHANGELOG.md was modified in this PR"
|
|
||||||
else
|
|
||||||
echo "changelog_modified=false" >> $GITHUB_OUTPUT
|
|
||||||
echo "⚠️ UNRELEASED_CHANGELOG.md was not modified"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Comment on PR about missing changelog
|
|
||||||
if: steps.changelog_check.outputs.changelog_modified == 'false' && github.event_name == 'pull_request'
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const author = context.payload.pull_request.user.login;
|
|
||||||
const message = '## ⚠️ Missing Changelog Update\n\n' +
|
|
||||||
`Hi @${author}, please update \`v3/UNRELEASED_CHANGELOG.md\` with a description of your changes.\n\n` +
|
|
||||||
'This helps us keep track of changes for the next release.';
|
|
||||||
|
|
||||||
await github.rest.issues.createComment({
|
|
||||||
issue_number: ${{ steps.pr_info.outputs.pr_number }},
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
body: message
|
|
||||||
});
|
|
||||||
|
|
||||||
44
.github/workflows/claude-code-review.yml
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
name: Claude Code Review
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, ready_for_review, reopened]
|
||||||
|
# Optional: Only run on specific file changes
|
||||||
|
# paths:
|
||||||
|
# - "src/**/*.ts"
|
||||||
|
# - "src/**/*.tsx"
|
||||||
|
# - "src/**/*.js"
|
||||||
|
# - "src/**/*.jsx"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
claude-review:
|
||||||
|
# Optional: Filter by PR author
|
||||||
|
# if: |
|
||||||
|
# github.event.pull_request.user.login == 'external-contributor' ||
|
||||||
|
# github.event.pull_request.user.login == 'new-developer' ||
|
||||||
|
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
issues: read
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Run Claude Code Review
|
||||||
|
id: claude-review
|
||||||
|
uses: anthropics/claude-code-action@v1
|
||||||
|
with:
|
||||||
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||||
|
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
|
||||||
|
plugins: 'code-review@claude-code-plugins'
|
||||||
|
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
|
||||||
|
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
||||||
|
# or https://code.claude.com/docs/en/cli-reference for available options
|
||||||
|
|
||||||
50
.github/workflows/claude.yml
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
name: Claude Code
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
pull_request_review_comment:
|
||||||
|
types: [created]
|
||||||
|
issues:
|
||||||
|
types: [opened, assigned]
|
||||||
|
pull_request_review:
|
||||||
|
types: [submitted]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
claude:
|
||||||
|
if: |
|
||||||
|
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||||
|
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||||
|
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||||
|
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
issues: read
|
||||||
|
id-token: write
|
||||||
|
actions: read # Required for Claude to read CI results on PRs
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Run Claude Code
|
||||||
|
id: claude
|
||||||
|
uses: anthropics/claude-code-action@v1
|
||||||
|
with:
|
||||||
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||||
|
|
||||||
|
# This is an optional setting that allows Claude to read CI results on PRs
|
||||||
|
additional_permissions: |
|
||||||
|
actions: read
|
||||||
|
|
||||||
|
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
||||||
|
# prompt: 'Update the pull request description to include a summary of changes.'
|
||||||
|
|
||||||
|
# Optional: Add claude_args to customize behavior and configuration
|
||||||
|
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
||||||
|
# or https://code.claude.com/docs/en/cli-reference for available options
|
||||||
|
# claude_args: '--allowed-tools Bash(gh pr:*)'
|
||||||
|
|
||||||
2
.github/workflows/generate-sponsor-image.yml
vendored
|
|
@ -25,7 +25,7 @@ jobs:
|
||||||
SPONSORKIT_GITHUB_LOGIN: wailsapp
|
SPONSORKIT_GITHUB_LOGIN: wailsapp
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@v4
|
uses: peter-evans/create-pull-request@v6
|
||||||
with:
|
with:
|
||||||
commit-message: "chore: update sponsors.svg"
|
commit-message: "chore: update sponsors.svg"
|
||||||
add-paths: "website/static/img/sponsors.svg"
|
add-paths: "website/static/img/sponsors.svg"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ name: Issue Triage Automation
|
||||||
|
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
types: [opened, reopened, labeled, unlabeled]
|
types: [opened]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
triage:
|
triage:
|
||||||
|
|
|
||||||
41
.github/workflows/pr-master.yml
vendored
|
|
@ -1,17 +1,26 @@
|
||||||
name: PR Checks (master)
|
# Updated to ensure "Run Go Tests" runs for pull requests as expected.
|
||||||
|
# Key fix: the test_go job previously required github.event.review.state == 'approved'
|
||||||
|
# which only exists on pull_request_review events. That prevented the job from
|
||||||
|
# running for regular pull_request events (opened / synchronize / reopened).
|
||||||
|
# New logic: run tests for pull_request events, and also allow running when a
|
||||||
|
# pull_request_review is submitted with state == 'approved'.
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
pull_request_review:
|
pull_request_review:
|
||||||
types: [submitted]
|
types: [submitted]
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
name: PR Checks (master)
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check_docs:
|
check_docs:
|
||||||
name: Check Docs
|
name: Check Docs
|
||||||
if: ${{github.repository == 'wailsapp/wails' && github.base_ref == 'master'}}
|
if: ${{ github.repository == 'wailsapp/wails' && github.base_ref == 'master' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
@ -23,7 +32,6 @@ jobs:
|
||||||
files: |
|
files: |
|
||||||
website/**/*.mdx
|
website/**/*.mdx
|
||||||
website/**/*.md
|
website/**/*.md
|
||||||
|
|
||||||
- name: Run step only when files change.
|
- name: Run step only when files change.
|
||||||
if: steps.verify-changed-files.outputs.files_changed != 'true'
|
if: steps.verify-changed-files.outputs.files_changed != 'true'
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -32,11 +40,18 @@ jobs:
|
||||||
test_go:
|
test_go:
|
||||||
name: Run Go Tests
|
name: Run Go Tests
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
# Run when:
|
||||||
|
# - the event is a pull_request (opened/synchronize/reopened) OR
|
||||||
|
# - the event is a pull_request_review AND the review state is 'approved'
|
||||||
|
# plus other existing filters (not the update-sponsors branch, repo and base_ref)
|
||||||
if: >
|
if: >
|
||||||
github.event.review.state == 'approved' &&
|
github.repository == 'wailsapp/wails' &&
|
||||||
github.repository == 'wailsapp/wails' &&
|
|
||||||
github.base_ref == 'master' &&
|
github.base_ref == 'master' &&
|
||||||
github.event.pull_request.head.ref != 'update-sponsors'
|
github.event.pull_request.head.ref != 'update-sponsors' &&
|
||||||
|
(
|
||||||
|
github.event_name == 'pull_request' ||
|
||||||
|
(github.event_name == 'pull_request_review' && github.event.review.state == 'approved')
|
||||||
|
)
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, windows-latest, macos-latest, ubuntu-24.04]
|
os: [ubuntu-22.04, windows-latest, macos-latest, ubuntu-24.04]
|
||||||
|
|
@ -75,3 +90,15 @@ jobs:
|
||||||
if: matrix.os == 'ubuntu-24.04'
|
if: matrix.os == 'ubuntu-24.04'
|
||||||
working-directory: ./v2
|
working-directory: ./v2
|
||||||
run: go test -v -tags webkit2_41 ./...
|
run: go test -v -tags webkit2_41 ./...
|
||||||
|
|
||||||
|
# This job will run instead of test_go for the update-sponsors branch
|
||||||
|
skip_tests:
|
||||||
|
name: Skip Tests (Sponsor Update)
|
||||||
|
if: github.event.pull_request.head.ref == 'update-sponsors'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Skip tests for sponsor updates
|
||||||
|
run: |
|
||||||
|
echo "Skipping tests for sponsor update branch"
|
||||||
|
echo "This is an automated update of the sponsors image."
|
||||||
|
continue-on-error: true
|
||||||
|
|
|
||||||
119
.github/workflows/publish-npm.yml
vendored
|
|
@ -1,119 +0,0 @@
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: ['v3-alpha']
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: publish-npm-v3
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
detect:
|
|
||||||
name: Detect committed changes
|
|
||||||
if: github.event_name != 'workflow_dispatch'
|
|
||||||
outputs:
|
|
||||||
changed: ${{ steps.package-json-changes.outputs.any_modified == 'true' || steps.source-changes.outputs.any_modified == 'true' }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.sha }}
|
|
||||||
persist-credentials: 'true'
|
|
||||||
|
|
||||||
- name: Detect committed package.json changes
|
|
||||||
id: package-json-changes
|
|
||||||
uses: step-security/changed-files@3dbe17c78367e7d60f00d78ae6781a35be47b4a1 # v45.0.1
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
v3/internal/runtime/desktop/@wailsio/runtime/package.json
|
|
||||||
v3/internal/runtime/desktop/@wailsio/runtime/package-lock.json
|
|
||||||
|
|
||||||
- name: Detect committed source changes
|
|
||||||
if: >-
|
|
||||||
steps.package-json-changes.outputs.any_modified != 'true'
|
|
||||||
id: source-changes
|
|
||||||
uses: step-security/changed-files@3dbe17c78367e7d60f00d78ae6781a35be47b4a1 # v45.0.1
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
v3/internal/runtime/Taskfile.yaml
|
|
||||||
v3/internal/runtime/desktop/@wailsio/compiled/main.js
|
|
||||||
v3/internal/runtime/desktop/@wailsio/runtime/tsconfig.json
|
|
||||||
v3/internal/runtime/desktop/@wailsio/runtime/src/**
|
|
||||||
v3/pkg/events/events.txt
|
|
||||||
v3/tasks/events/**
|
|
||||||
|
|
||||||
rebuild_and_publish:
|
|
||||||
name: Rebuild and publish
|
|
||||||
needs: [detect]
|
|
||||||
if: >-
|
|
||||||
!failure() && !cancelled()
|
|
||||||
&& (github.event_name == 'workflow_dispatch' || needs.detect.outputs.changed == 'true')
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
actions: read
|
|
||||||
pull-requests: read
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
ref: 'v3-alpha'
|
|
||||||
token: ${{ secrets.WAILS_REPO_TOKEN || github.token }}
|
|
||||||
|
|
||||||
- name: Configure git
|
|
||||||
run: |
|
|
||||||
git config --global user.email "github-actions@github.com"
|
|
||||||
git config --global user.name "GitHub Actions"
|
|
||||||
git config --global url."https://x-access-token:${{ secrets.WAILS_REPO_TOKEN || github.token }}@github.com/".insteadOf "https://github.com/"
|
|
||||||
|
|
||||||
- name: Install Task
|
|
||||||
uses: arduino/setup-task@v2
|
|
||||||
with:
|
|
||||||
version: 3.x
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Use Node.js 20
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: "20"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
working-directory: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npx --yes esbuild@latest --version
|
|
||||||
|
|
||||||
- name: Clean build artifacts
|
|
||||||
working-directory: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
run: npm run clean
|
|
||||||
|
|
||||||
- name: Build bundled runtime
|
|
||||||
working-directory: v3
|
|
||||||
run: task runtime:build
|
|
||||||
|
|
||||||
- name: Test+Build npm package
|
|
||||||
working-directory: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
run: |
|
|
||||||
npm test
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
- name: Bump version
|
|
||||||
id: bump-version
|
|
||||||
working-directory: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
run: |
|
|
||||||
echo "version=$(npm --no-git-tag-version --force version prerelease)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Commit changes
|
|
||||||
run: |
|
|
||||||
git add .
|
|
||||||
git commit -m "[skip ci] Publish @wailsio/runtime ${{ steps.bump-version.outputs.version }}"
|
|
||||||
git push
|
|
||||||
|
|
||||||
- name: Publish npm package
|
|
||||||
uses: JS-DevTools/npm-publish@v3
|
|
||||||
with:
|
|
||||||
package: v3/internal/runtime/desktop/@wailsio/runtime
|
|
||||||
access: public
|
|
||||||
token: ${{ secrets.NPM_TOKEN }}
|
|
||||||
11
.github/workflows/test-simple.yml
vendored
|
|
@ -1,11 +0,0 @@
|
||||||
name: Test Simple
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Test
|
|
||||||
run: echo "Hello World"
|
|
||||||
|
|
@ -39,6 +39,7 @@ jobs:
|
||||||
name: Trigger v3-alpha Release
|
name: Trigger v3-alpha Release
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
actions: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: check-permissions
|
needs: check-permissions
|
||||||
if: needs.check-permissions.outputs.authorized == 'true'
|
if: needs.check-permissions.outputs.authorized == 'true'
|
||||||
|
|
|
||||||
42
.github/workflows/v3-docs.yml
vendored
|
|
@ -1,42 +0,0 @@
|
||||||
name: Deploy to GitHub Pages
|
|
||||||
|
|
||||||
on:
|
|
||||||
# Trigger the workflow every time you push to the `main` branch
|
|
||||||
# Using a different branch name? Replace `main` with your branch’s name
|
|
||||||
push:
|
|
||||||
branches: [v3-alpha]
|
|
||||||
# Allows you to run this workflow manually from the Actions tab on GitHub.
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
# Allow this job to clone the repo and create a page deployment
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event.repository.fork == false
|
|
||||||
steps:
|
|
||||||
- name: Checkout your repository using git
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install, build, and upload your site output
|
|
||||||
uses: withastro/action@v2
|
|
||||||
with:
|
|
||||||
path: docs
|
|
||||||
node-version: 20 # The specific version of Node that should be used to build your site. Defaults to 18. (optional)
|
|
||||||
# package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
steps:
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
id: deployment
|
|
||||||
uses: actions/deploy-pages@v4
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
54
.gitignore
vendored
|
|
@ -37,57 +37,5 @@ v2/cmd/wails/internal/commands/initialise/templates/testtemplates/
|
||||||
/websitev3/site/
|
/websitev3/site/
|
||||||
/v3/examples/plugins/bin/testapp
|
/v3/examples/plugins/bin/testapp
|
||||||
|
|
||||||
# V3 Example binaries - ignore executables that match directory names
|
|
||||||
/v3/examples/badge-custom/badge-custom
|
|
||||||
/v3/examples/badge/badge
|
|
||||||
/v3/examples/binding/binding
|
|
||||||
/v3/examples/cancel-async/cancel-async
|
|
||||||
/v3/examples/cancel-chaining/cancel-chaining
|
|
||||||
/v3/examples/clipboard/clipboard
|
|
||||||
/v3/examples/contextmenus/contextmenus
|
|
||||||
/v3/examples/dev/dev
|
|
||||||
/v3/examples/dialogs-basic/dialogs-basic
|
|
||||||
/v3/examples/dialogs/dialogs
|
|
||||||
/v3/examples/drag-n-drop/drag-n-drop
|
|
||||||
/v3/examples/environment/environment
|
|
||||||
/v3/examples/events-bug/events-bug
|
|
||||||
/v3/examples/events/events
|
|
||||||
/v3/examples/file-association/file-association
|
|
||||||
/v3/examples/frameless/frameless
|
|
||||||
/v3/examples/gin-example/gin-example
|
|
||||||
/v3/examples/gin-routing/gin-routing
|
|
||||||
/v3/examples/gin-service/gin-service
|
|
||||||
/v3/examples/hide-window/hide-window
|
|
||||||
/v3/examples/html-dnd-api/html-dnd-api
|
|
||||||
/v3/examples/ignore-mouse/ignore-mouse
|
|
||||||
/v3/examples/keybindings/keybindings
|
|
||||||
/v3/examples/menu/menu
|
|
||||||
/v3/examples/notifications/notifications
|
|
||||||
/v3/examples/panic-handling/panic-handling
|
|
||||||
/v3/examples/plain/plain
|
|
||||||
/v3/examples/raw-message/raw-message
|
|
||||||
/v3/examples/screen/screen
|
|
||||||
/v3/examples/services/services
|
|
||||||
/v3/examples/show-macos-toolbar/show-macos-toolbar
|
|
||||||
/v3/examples/single-instance/single-instance
|
|
||||||
/v3/examples/systray-basic/systray-basic
|
|
||||||
/v3/examples/systray-custom/systray-custom
|
|
||||||
/v3/examples/systray-menu/systray-menu
|
|
||||||
/v3/examples/video/video
|
|
||||||
/v3/examples/window-api/window-api
|
|
||||||
/v3/examples/window-call/window-call
|
|
||||||
/v3/examples/window-menu/window-menu
|
|
||||||
/v3/examples/window/window
|
|
||||||
/v3/examples/wml/wml
|
|
||||||
|
|
||||||
# Common binary names in examples
|
|
||||||
/v3/examples/*/main
|
|
||||||
/v3/examples/*/app
|
|
||||||
/v3/examples/*/changeme
|
|
||||||
/v3/examples/*/testbuild-*
|
|
||||||
|
|
||||||
# Temporary called mkdocs, should be renamed to more standard -website or similar
|
# Temporary called mkdocs, should be renamed to more standard -website or similar
|
||||||
/docs/site
|
/mkdocs-website/site
|
||||||
.aider*
|
|
||||||
.cache
|
|
||||||
.local
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
overrides:
|
overrides:
|
||||||
- files:
|
- files:
|
||||||
- "**/*.md"
|
- "**/*.md"
|
||||||
- "**/*.mdx"
|
|
||||||
options:
|
options:
|
||||||
printWidth: 80
|
printWidth: 80
|
||||||
proseWrap: always
|
proseWrap: always
|
||||||
|
|
|
||||||
8
.replit
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
modules = ["go-1.21", "web", "nodejs-20"]
|
||||||
|
run = "go run v2/cmd/wails/main.go"
|
||||||
|
|
||||||
|
[nix]
|
||||||
|
channel = "stable-24_05"
|
||||||
|
|
||||||
|
[deployment]
|
||||||
|
run = ["sh", "-c", "go run v2/cmd/wails/main.go"]
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
golang 1.25.1
|
|
||||||
nodejs 24.8.0
|
|
||||||
16
AGENTS.md
|
|
@ -1,16 +0,0 @@
|
||||||
# Repository Guidelines
|
|
||||||
|
|
||||||
## Project Structure & Module Organization
|
|
||||||
The repository hosts the current Wails tooling in `v3/`, the maintained v2 runtime in `v2/`, and shared assets under `assets/` and `pkg/`. CLI entrypoints live in `v3/cmd/wails3`, while reusable runtime code is grouped under `v3/internal/*` (platform integrations, packaging, templates) and `v3/pkg/*` (application, services, UI helpers). Example applications used for testing and documentation reside in `v3/examples`, with Docker build scripts and harnesses in `v3/test` and targeted regression suites in `v3/tests`. Documentation and site content are stored in `docs/` and `website/`; keep tutorial updates alongside related code changes.
|
|
||||||
|
|
||||||
## Build, Test, and Development Commands
|
|
||||||
Run `task v3:install` to compile and install the v3 CLI locally, and `task v3:precommit` before submitting changes to execute `go test ./...` and apply repository formatters. Use `task v3:test:examples` for a full platform-agnostic build of every example, or scope work with `task v3:test:example:windows DIR=badge` (replace `badge` as needed). Markdown formatting is standardized with `task format:md`, and changelog automation is driven via `task contributors:update` when contributor metadata changes.
|
|
||||||
|
|
||||||
## Coding Style & Naming Conventions
|
|
||||||
Go code must remain `gofmt`-clean with idiomatic package names (lowercase, no underscores) and exported API names following Go's PascalCase. Match existing directory naming by grouping platform-specific code under clearly named packages (e.g., `mac`, `w32`) and keep generator templates in `internal/templates`. Frontend or documentation updates should respect Prettier defaults; run `npx prettier --write "**/*.md"` or the Taskfile wrapper to stay consistent.
|
|
||||||
|
|
||||||
## Testing Guidelines
|
|
||||||
Unit and integration tests accompany Go sources inside the nearest package; add new suites under `v3/tests` for regression coverage. Cross-platform build validation relies on the Taskfile matrix—`task test:examples:all` exercises macOS, Windows, and Linux Docker pipelines, while `task test:example:linux:docker DIR=<name>` verifies a single sample with architecture auto-detection. Prefer deterministic tests and clean up generated binaries (`testbuild-*`) after manual runs.
|
|
||||||
|
|
||||||
## Commit & Pull Request Guidelines
|
|
||||||
Adopt conventional commits recognized by the release tooling (`feat:`, `fix:`, `chore:`, with `!` or `BREAKING CHANGE:` when necessary) so nightly pipelines classify versions correctly. Reference issues or discussion threads in the body, and update `v3/UNRELEASED_CHANGELOG.md` with concise entries under the appropriate heading. Pull requests should summarize scope, list validation commands executed (e.g., `task v3:precommit`), and include platform-specific notes or screenshots for UI-affecting work. Ensure CI passes and that new docs or samples link from the relevant navigation files in `docs/src/content` before requesting review.
|
|
||||||
1
CNAME
|
|
@ -1 +0,0 @@
|
||||||
v3alpha.wails.io
|
|
||||||
|
|
@ -1,317 +0,0 @@
|
||||||
# Wails v3 Developer Guide (Top-Level Overview)
|
|
||||||
|
|
||||||
This guide provides a technical, developer-focused overview of the Wails v3 codebase located under the `v3` directory. It is the start of a comprehensive series that will later dive into each package and file in detail. For now, it establishes orientation, architecture, responsibilities, and workflows so contributors have a reliable high-level map before we document every component thoroughly.
|
|
||||||
|
|
||||||
Scope: Only the `v3` directory is in scope for this guide.
|
|
||||||
|
|
||||||
Last updated: 2025-09-24
|
|
||||||
|
|
||||||
|
|
||||||
## Goals of Wails v3
|
|
||||||
|
|
||||||
Wails lets you build desktop applications using Go for the backend and web technologies (HTML/CSS/JS) for the frontend, packaging them into a native desktop experience across platforms. Version 3 focuses on modular internal packages, improved runtime and tooling, and clearer boundaries between build-time and run-time responsibilities.
|
|
||||||
|
|
||||||
|
|
||||||
## High-Level Architecture
|
|
||||||
|
|
||||||
- Command-line tooling (CLI): developer-facing entry points for building, generating, packaging, and inspecting Wails apps.
|
|
||||||
- Internal libraries: build orchestration, runtime integration, OS abstractions, packaging, capabilities, templates, and utilities. These are mostly under `v3/internal` and not intended as public API.
|
|
||||||
- Public Go packages: simple APIs for applications to use (e.g., `v3/pkg/application`, `v3/pkg/ui`, `v3/pkg/services`, etc.).
|
|
||||||
- Runtime (desktop): the bridge between the Go app and the web frontend, with bindings, window control, events, and platform integrations.
|
|
||||||
- Examples and tests: reference implementations and validation.
|
|
||||||
|
|
||||||
|
|
||||||
## Directory Map (top-level under v3)
|
|
||||||
|
|
||||||
- `cmd/` — CLI entrypoints.
|
|
||||||
- `wails3/` — The main Wails v3 CLI. Includes `main.go`, usage docs, and a prebuilt binary (when present in repo artifacts).
|
|
||||||
|
|
||||||
- `examples/` — Working sample apps demonstrating various capabilities.
|
|
||||||
- Examples include, among others: drag-and-drop, raw message handling, etc. These show best practices and can be used to validate changes.
|
|
||||||
|
|
||||||
- `internal/` — Internal (non-public) packages used by the CLI and by build/runtime components.
|
|
||||||
- `assetserver/` — Static file serving logic for development or build steps.
|
|
||||||
- `buildinfo/` — Build metadata and version stamping.
|
|
||||||
- `capabilities/` — Capabilities gating or feature flags across subsystems.
|
|
||||||
- `changelog/` — Utilities for changelog parsing/validation.
|
|
||||||
- `commands/` — Implementation of CLI subcommands and orchestration logic.
|
|
||||||
- `dbus/` — D-Bus integration for Linux desktop features.
|
|
||||||
- `debug/` — Debug utilities or dev-mode helpers.
|
|
||||||
- `doctor/` — Environment diagnostics (e.g., checking toolchains).
|
|
||||||
- `fileexplorer/` — File chooser/dialog logic beyond platform primitives.
|
|
||||||
- `flags/` — Centralized command-line flag definitions and parsing helpers.
|
|
||||||
- `generator/` — Code and project generators (scaffolding, bindings, etc.).
|
|
||||||
- `github/` — GitHub integration (release automation or metadata helpers).
|
|
||||||
- `go-common-file-dialog/` — Common file dialog wrappers (likely cross-platform helpers).
|
|
||||||
- `hash/` — Hashing utilities for caching, integrity, or content addressing.
|
|
||||||
- `operatingsystem/` — OS detection and OS-specific helpers.
|
|
||||||
- `packager/` — Packaging/build pipelines to produce platform-specific bundles.
|
|
||||||
- `runtime/` — Runtime glue for the desktop environment.
|
|
||||||
- `desktop/` — Desktop runtime resources including the browser window bridge and TS/JS runtime.
|
|
||||||
- `@wailsio/runtime/` — TypeScript source for the frontend runtime bridge (window and app bindings, event bus, etc.).
|
|
||||||
- `s/` — Small internal helpers or shared primitives.
|
|
||||||
- `service/` — Service abstractions and service lifecycle helpers used internally.
|
|
||||||
- `signal/` — Signal handling (OS process signals).
|
|
||||||
- `templates/` — Project and code templates (used by the generator and packager).
|
|
||||||
- `term/`, `term2/` — Terminal rendering, progress, and rich text helpers.
|
|
||||||
- `version/` — Versioning helpers shared across commands.
|
|
||||||
|
|
||||||
- `pkg/` — Public packages intended for application developers.
|
|
||||||
- `application/` — Main application abstraction (app lifecycle, window management hooks, startup/shutdown).
|
|
||||||
- `events/` — Event bus/interfaces for app<->frontend communication.
|
|
||||||
- `icons/` — Icon helpers/types for application and window icons.
|
|
||||||
- `mac/` — macOS-specific helpers.
|
|
||||||
- `mcp/` — Platform or protocol utilities (exact scope to be detailed in the deep dive).
|
|
||||||
- `services/` — Public service interfaces and service registration.
|
|
||||||
- `ui/` — UI helpers and types exposed to apps.
|
|
||||||
- `w32/` — Windows-specific helpers and bindings.
|
|
||||||
|
|
||||||
- `scripts/` — Maintenance or developer scripts used in CI or local workflows.
|
|
||||||
- `validate-changelog.go` — Validates changelog format and rules.
|
|
||||||
|
|
||||||
- `tasks/` — Task-based workflow helpers (used by maintainers and CI).
|
|
||||||
- `cleanup/`, `contribs/`, `events/`, `fix-bindings/`, `release/`, `sed/` — Per-task utilities and scripts.
|
|
||||||
|
|
||||||
- `test/`, `tests/`, `tooltest/` — Test suites, fixtures, and tools used for verifying functionality.
|
|
||||||
|
|
||||||
- `.task/`, `wep/` — Project tooling/configuration directories (to be detailed later as needed).
|
|
||||||
|
|
||||||
|
|
||||||
## Build and Development Overview
|
|
||||||
|
|
||||||
- CLI usage: The `v3/cmd/wails3` command is the primary interface. Typical workflows include:
|
|
||||||
- Project creation via templates (generator).
|
|
||||||
- Development server and live reload for the frontend (assetserver, runtime dev helpers).
|
|
||||||
- Building a production bundle and packaging for the target OS (packager).
|
|
||||||
- Internal packages are not part of the public API contract and may change. Public Go APIs under `v3/pkg/` are maintained for application developers.
|
|
||||||
- The desktop runtime bridges Go and the Web frontend via a JS/TS runtime (`internal/runtime/desktop/@wailsio/runtime`). This provides window controls, eventing, and invocation bridges to Go.
|
|
||||||
|
|
||||||
|
|
||||||
## Key Data Flows (Conceptual)
|
|
||||||
|
|
||||||
1. Developer runs a CLI command (wails3) → CLI delegates to `internal/commands` and uses helpers under `internal/*` for build, generate, package, etc.
|
|
||||||
2. The application code (using `v3/pkg/*`) defines the Go-side application, services, and event handlers.
|
|
||||||
3. At runtime, the desktop bridge injects a JS runtime into the web app so frontend can call Go methods and subscribe to events. The Go-side emits events to the frontend via the runtime channel.
|
|
||||||
4. Packaging uses `internal/packager` to produce OS-native bundles, using OS-specific helpers from `pkg/mac`, `pkg/w32`, etc., as needed.
|
|
||||||
|
|
||||||
|
|
||||||
## Contributing Workflow (High-Level)
|
|
||||||
|
|
||||||
- Make small, focused changes. For cross-platform features, ensure Linux, macOS, and Windows implications are considered.
|
|
||||||
- Run example apps under `v3/examples` to validate changes.
|
|
||||||
- Use scripts under `v3/scripts` and tasks under `v3/tasks` where applicable (e.g., changelog validation or release workflows).
|
|
||||||
- When modifying the runtime bridge, ensure TypeScript builds for `@wailsio/runtime` are up-to-date and integration-tested against example apps.
|
|
||||||
|
|
||||||
|
|
||||||
## Next Steps in This Guide
|
|
||||||
|
|
||||||
This is the top-level overview. In subsequent iterations, we will deep-dive into every package and file in the `v3` directory with:
|
|
||||||
- Detailed per-package responsibilities and structure.
|
|
||||||
- File-by-file documentation including key types, functions, and data flow.
|
|
||||||
- Build, test, and troubleshooting instructions for each component.
|
|
||||||
|
|
||||||
If you need a specific package documented next, please indicate which one, and we’ll start the in-depth coverage there.
|
|
||||||
|
|
||||||
|
|
||||||
# Deep Dive: pkg/application
|
|
||||||
|
|
||||||
Scope: This section documents every file under v3/pkg/application and explains the end-to-end data flows for how an application is initialised and then run. It complements the top-level overview above.
|
|
||||||
|
|
||||||
Last reviewed: 2025-09-24
|
|
||||||
|
|
||||||
|
|
||||||
Overview of the application package
|
|
||||||
- Purpose: Provides the public API and core runtime glue for building and running a Wails desktop application. It owns the App type and orchestrates windows, menus, dialogs, system trays, eventing, and platform-specific main loops.
|
|
||||||
- Key types:
|
|
||||||
- App: The core application object exposed to developers.
|
|
||||||
- Window/WebviewWindow: Represents a browser-hosted UI Window (WebView2 on Windows, WKWebView on macOS, WebKitGTK on Linux).
|
|
||||||
- Managers: Subsystems that manage windows, menus, dialogs, events, clipboard, screens, environment, system trays, etc.
|
|
||||||
- Options: Configuration used to create the App and its initial windows and services.
|
|
||||||
- EventProcessor and event contexts: Abstractions for custom events and application/window event flows.
|
|
||||||
|
|
||||||
|
|
||||||
Lifecycle and data flow (initialisation -> run -> shutdown)
|
|
||||||
1) Construction via New(options)
|
|
||||||
- File: application.go (New)
|
|
||||||
- Actions:
|
|
||||||
- Merge defaults (mergeApplicationDefaults) and normalize Options (application_options.go).
|
|
||||||
- Construct the App: allocate fields, set logger, prepare asset serving (middleware, asset handlers), store any initial services from options.
|
|
||||||
- Prepare developer tooling (dev vs production variants in application_dev.go/application_production.go). In dev, static server may proxy to dev server; in production, use bundled assets.
|
|
||||||
- Defer platform-specific initialization; platform-specific App (platformApp) is created later in Run() via newPlatformApp(...) implemented per-OS.
|
|
||||||
|
|
||||||
2) App.init()
|
|
||||||
- File: application.go (init method on App)
|
|
||||||
- Actions:
|
|
||||||
- Create root context (a.ctx) and cancellation function.
|
|
||||||
- Instantiate and wire all managers:
|
|
||||||
- newWindowManager, newContextMenuManager, newKeyBindingManager, newBrowserManager, newEnvironmentManager, newDialogManager, newEventManager, newMenuManager, newScreenManager, newClipboardManager, newSystemTrayManager.
|
|
||||||
- Initialize internal maps: windows, systemTrays, contextMenus, keyBindings, listener registries.
|
|
||||||
|
|
||||||
3) Pre-run hooks and service startup
|
|
||||||
- File: application.go (Run -> preRun -> service startup)
|
|
||||||
- Actions:
|
|
||||||
- preRun() executes any post-creation hooks (e.g., build/runtime settling, menu prep, assetserver finalization). If this fails, Run aborts.
|
|
||||||
- Services provided in Options.Services are started in order (startupService). On failure, an error is returned and started services are tracked for orderly shutdown.
|
|
||||||
|
|
||||||
4) Platform App creation
|
|
||||||
- File: application.go (Run)
|
|
||||||
- Calls newPlatformApp(a) which selects implementation based on GOOS:
|
|
||||||
- application_windows.go -> windowsApp
|
|
||||||
- application_darwin.go -> darwinApp (plus associated Objective-C glue .m/.h for Cocoa/WKWebView)
|
|
||||||
- application_linux.go -> gtkApp (with CGO or purego variants)
|
|
||||||
- The platformApp implements methods like run(), init(), setApplicationMenu(), setIcon(), show/hide, main-thread dispatch, window/tray registration, etc.
|
|
||||||
|
|
||||||
5) Event pump setup (concurrency and channels)
|
|
||||||
- File: application.go (Run)
|
|
||||||
- Starts goroutines to drain and dispatch internal channels:
|
|
||||||
- applicationEvents -> a.Event.handleApplicationEvent
|
|
||||||
- windowEvents -> a.handleWindowEvent
|
|
||||||
- webviewRequests -> a.handleWebViewRequest
|
|
||||||
- windowMessageBuffer -> a.handleWindowMessage
|
|
||||||
- windowKeyEvents -> a.handleWindowKeyEvent
|
|
||||||
- windowDragAndDropBuffer -> a.handleDragAndDropMessage
|
|
||||||
- menuItemClicked -> a.Menu.handleMenuItemClicked
|
|
||||||
- These goroutines run for the lifetime of the app and route messages from the platform layer and WebView bridges into App managers and windows.
|
|
||||||
|
|
||||||
6) Final run
|
|
||||||
- File: application.go (Run)
|
|
||||||
- Marks a.running = true, drains any a.pendingRun tasks scheduled before the run loop started, sets the application menu (darwin) and icon (if provided), and then calls a.impl.run() which enters the platform event loop (message pump on Windows, CFRunLoop on macOS, GTK main loop on Linux).
|
|
||||||
|
|
||||||
7) Shutdown
|
|
||||||
- File: application.go (cleanup, shutdownServices, Quit)
|
|
||||||
- Cancel root context, tear down windows/system trays/menus, stop services in reverse order, and exit the platform loop. Fatal errors use handleFatalError to log and os.Exit(1).
|
|
||||||
|
|
||||||
|
|
||||||
File-by-file guide (v3/pkg/application)
|
|
||||||
Note: Brief purpose for each file and how it participates in init/run and data flows.
|
|
||||||
|
|
||||||
Core App and options
|
|
||||||
- application.go: Defines App and its lifecycle. Key functions/methods: New, init (method), Run, cleanup, Quit, event and message handlers, Hide/Show, SetIcon, runOrDeferToAppRun. Creates managers and coordinates inter-manager communication via channels and callbacks.
|
|
||||||
- application_options.go: Defines Options for configuring the App: window defaults, asset options, logger, middlewares, platform-specific options (MacOptions, WindowsOptions, LinuxOptions), and asset server helpers. Contains middleware chaining and helpers for serving assets from fs.FS.
|
|
||||||
- services.go: Declares Service interface and service lifecycle integration with App (startupService, shutdownServices) and registration via App.RegisterService.
|
|
||||||
- environment.go / environment_manager.go: Detects and exposes environment info to the app (dev/prod, capabilities, platform variables), often referenced when preparing runtime flags and window defaults.
|
|
||||||
- errors.go: Error types, including FatalError used by handleFatalError in App.
|
|
||||||
- panic_handler.go: Centralized panic recovery where goroutines defer handlePanic() to avoid crashing the app silently.
|
|
||||||
- mainthread*.go: Utilities to ensure code runs on the GUI main thread when required by the OS toolkit; used by platformApp implementations and App.dispatchOnMainThread.
|
|
||||||
- messageprocessor*.go: Message router between WebView frontend and Go backend; different files focus on different domains (application, window, dialogs, clipboard, context menus, screens, system). They parse inbound messages (e.g., from JS runtime) and call into managers/App methods.
|
|
||||||
- bindings.go: Handles Go<->JS binding registration and call routing, including returning values/errors to the frontend via WebView.
|
|
||||||
|
|
||||||
Platform-specific app implementations
|
|
||||||
- application_windows.go: windowsApp implements platformApp for Windows. Responsibilities:
|
|
||||||
- init(): OS integration (DPI awareness, COM init as needed via WebView2 loader), building application menu, creating hidden “application” window for message routing if needed.
|
|
||||||
- run(): Enters the Windows message loop, dispatches messages to wndProc, and integrates with WebView2 (go-webview2).
|
|
||||||
- wndProc(): Translates native window messages into Wails events: focus, resize, menu select, accelerator keys, system tray clicks, drag/drop, etc., forwarding into channels consumed by App.Run goroutines.
|
|
||||||
- setApplicationMenu(), setIcon(), show/hide, registration of windows and system trays.
|
|
||||||
- logPlatformInfo() and platformEnvironment() provide environment metadata used during startup.
|
|
||||||
- application_darwin.go and related Objective-C files (.h/.m): darwinApp uses Cocoa and WKWebView. Objective-C delegate files integrate with NSApplication, NSWindow, menus, and app activation policy; bridge callbacks enqueue events into Go channels.
|
|
||||||
- application_linux.go plus linux_cgo.go/linux_purego.go: GTK-based implementation; CGO variant integrates with GTK main loop and dialogs; purego variant offers a fallback depending on build tags.
|
|
||||||
- application_dev.go / application_production.go: Build-tagged files that adjust behavior for development vs production (e.g., logger defaults, asset server wiring, runtime flags). logger_dev*.go/logger_prod.go customize logging sinks by target OS and mode.
|
|
||||||
|
|
||||||
Windows/macOS/Linux specific helpers
|
|
||||||
- keys*.go: Keyboard key codes and modifier mappings per OS; used to parse accelerators and handle key bindings.
|
|
||||||
- dialogs*.go: Platform-specific dialog implementations (message box, file open/save) backing the cross-platform dialogs.go facade.
|
|
||||||
- clipboard*.go and clipboard_manager.go: Clipboard APIs per OS.
|
|
||||||
- screen_*.go and screenmanager.go: Screen enumeration, DPI/scale factors, active screen selection; used when positioning windows.
|
|
||||||
- systemtray_*.go and system_tray_manager.go: System tray icon/menu management; events funneled through channels to App and Menu managers.
|
|
||||||
|
|
||||||
Windowing: webview window and options
|
|
||||||
- webview_window.go: The core window abstraction backed by a webviewWindowImpl (implemented per-OS). Responsibilities:
|
|
||||||
- Window creation via NewWindow(options) after App is created.
|
|
||||||
- Eventing: WindowEvent and listener registration (OnWindowEvent, RegisterHook), mapping of events to callbacks.
|
|
||||||
- Lifecycle methods: Show/Hide, Run (window-level), Close/Destroy, Focus, Resize/Move, Fullscreen/Maximise/Minimise, Zoom, ContentProtection, Frameless toggling, DevTools (per OS), ExecJS, SetHTML/URL, printing.
|
|
||||||
- Input handling: processKeyBinding and HandleKeyEvent for accelerators; integrates with menu accelerator mappings.
|
|
||||||
- Messaging bridge: HandleMessage (routes call responses and RPC from JS), DialogResponse/CallResponse, drag-and-drop (HandleDragAndDropMessage), context menus.
|
|
||||||
- Internal queues: dispatchWindowEvent, isDestroyed checks, destroyed state management.
|
|
||||||
- webview_window_options.go: Defines WebviewWindowOptions, styling and behavior (title, size, min/max constraints, position, background color, frameless, URL/HTML/Assets, debug flags, dev tools, zoom policy, theme, user agent, drag regions, etc.). Also includes GPU policy and per-OS defaults. Options feed directly into platform window creation.
|
|
||||||
- webview_window_* per-OS files: Implement webviewWindowImpl for each platform. They translate cross-platform window API to native toolkit calls and send back events via channels (e.g., windowEvents, windowMessageBuffer, windowKeyEvents).
|
|
||||||
- window.go and window_manager.go: The common Window interface and its manager. The manager tracks windows by ID, exposes Find/All/Focused, and routes broadcast events.
|
|
||||||
|
|
||||||
Menus, roles, and accelerators
|
|
||||||
- menu.go/menu_darwin.go/menu_linux.go/menu_windows.go: Cross-platform Menu representation with platform renderers. Supports app menu (macOS), window menus, and menu bar visibility.
|
|
||||||
- menuitem.go and family: MenuItem definition, roles, selectors (macOS), per-OS renderers. menuitem_roles.go defines standard roles (Copy, Paste, Quit, etc.).
|
|
||||||
- roles*.go: Dev vs production role sets.
|
|
||||||
- popupmenu_windows.go and context_menu_manager.go: Context menu helpers and manager lifecycle.
|
|
||||||
- key_binding_manager.go: Manages registration of accelerators (e.g., "CmdOrCtrl+Shift+P") and dispatches to window/menu handlers.
|
|
||||||
|
|
||||||
Dialogs
|
|
||||||
- dialogs.go: Cross-platform API for dialogs. Provides MessageDialog, OpenFileDialog, SaveFileDialog with builder-style options; delegates to per-OS implementations via messageDialogImpl/openFileDialogImpl/saveFileDialogImpl.
|
|
||||||
- dialogs_* per-OS: Bridge to native dialog toolkits (NSAlert/NSSavePanel on macOS, IFileDialog/MessageBox on Windows, GTK dialogs on Linux).
|
|
||||||
|
|
||||||
Eventing
|
|
||||||
- events.go: Custom event system for the application package. Provides:
|
|
||||||
- CustomEvent (name, data, cancellation) and ApplicationEvent/WindowEvent wrappers with Context() access to typed event contexts.
|
|
||||||
- EventProcessor to register listeners (On/Once/OnMultiple), hooks, and to Emit events. Safe for concurrent use via sync primitives.
|
|
||||||
- Bridges to pkg/events for enum types (ApplicationEventType, WindowEventType) used throughout.
|
|
||||||
- context_application_event.go, context_window_event.go: Define typed context payloads for app/window events passed to listeners (e.g., theme change info, file open URL, window IDs).
|
|
||||||
- events_common_*.go and event_manager.go: Glue code that maps platform events to high-level events and exposes App.Event API used by apps and internal subsystems.
|
|
||||||
|
|
||||||
Miscellaneous utilities
|
|
||||||
- browser_manager.go: Tracks browser/webview state across windows; used by certain operations that need to coordinate with the web runtime.
|
|
||||||
- image.go: Image helpers (e.g., RGBA), icons.
|
|
||||||
- path.go: Small helpers for path normalization when interacting with OS file dialogs or asset paths.
|
|
||||||
- urlvalidator.go: Validates URLs provided for window content (security and correctness). Unit tests in urlvalidator_test.go.
|
|
||||||
- single_instance*.go: Optional single-instance enforcement per OS; integrates with platform IPC or file locks.
|
|
||||||
- systemtray.go: Cross-platform SystemTray API given to app developers; platform-specific implementations in systemtray_*.go.
|
|
||||||
- clipboard.go: Cross-platform Clipboard API facade; platform-specific glue in clipboard_*.go.
|
|
||||||
- logger_dev*.go/logger_prod.go: Logging helpers per build mode and OS.
|
|
||||||
- TODO.md: Notes for maintainers.
|
|
||||||
|
|
||||||
|
|
||||||
Detailed init/run sequence with call graph highlights
|
|
||||||
- App creation:
|
|
||||||
1. application.New(options)
|
|
||||||
- Merges defaults; stores Options; sets up assets/middleware stack; chooses dev/prod behaviors; prepares logger.
|
|
||||||
- Does NOT start platform loop yet.
|
|
||||||
2. App.init() (method) is called by New internally to initialise managers and state.
|
|
||||||
|
|
||||||
- Run startup (application.go: Run):
|
|
||||||
3. Guard against double Run; mark starting; arrange context cancellation on failure.
|
|
||||||
4. preRun(): perform any post-construction checks and assetserver finalisation.
|
|
||||||
5. Create platform app: a.impl = newPlatformApp(a) -> application_{os}.go
|
|
||||||
- Platform impl may do platform-specific pre-main-loop init in impl.init().
|
|
||||||
6. Start services: for each options.Service, a.startupService(service) and record for shutdown order.
|
|
||||||
7. Start event pumps: spin goroutines to drain internal channels and dispatch to managers and windows (see channels list above).
|
|
||||||
8. Flip a.running = true and execute any pending runnables queued before Run (runOrDeferToAppRun).
|
|
||||||
9. Apply app-level UI state: set application menu (macOS), set icon if provided.
|
|
||||||
10. Enter platform loop: return a.impl.run(). From here, the native main loop owns the thread and dispatches native events that are bridged back into Go via callbacks and channels.
|
|
||||||
|
|
||||||
- Runtime interactions:
|
|
||||||
- Window creation: NewWindow(options) constructs a WebviewWindow, invokes platform creation, and registers it with WindowManager and platformApp. Events from native layer (resize, focus, key) become messages in windowEvents/windowMessageBuffer/windowKeyEvents and are dispatched by App handlers to per-window callbacks.
|
|
||||||
- Dialogs: The public dialog builders call through to per-OS implementations; responses are sent back via DialogResponse/DialogError into the originating Window.
|
|
||||||
- Menus and accelerators: Menu items with accelerators are registered with KeyBindingManager. Native key events are turned into accelerator strings per-OS (keys_*.go) and routed back to WebviewWindow.processKeyBinding.
|
|
||||||
- Custom events: App.Event.Emit(CustomEvent) dispatches to registered listeners and also to windows (DispatchWailsEvent) so frontends subscribed via the JS runtime receive them.
|
|
||||||
|
|
||||||
- Shutdown:
|
|
||||||
- Triggered by App.Quit(), window close that results in shouldQuit() returning true, or fatal errors.
|
|
||||||
- App.cleanup() tears down windows, trays, menus, and services in order; cancels root context; releases native resources via platformApp.destroy().
|
|
||||||
|
|
||||||
|
|
||||||
Data channels and queues (core ones referenced in application.go)
|
|
||||||
- applicationEvents: carries ApplicationEvent to App.Event handler.
|
|
||||||
- windowEvents: carries internal windowEvent to App.handleWindowEvent which locates the Window and emits a typed WindowEvent.
|
|
||||||
- webviewRequests: transports webview asset HTTP requests to the asset server pipeline (headers, middleware, handlers).
|
|
||||||
- windowMessageBuffer: messages from webview to window (RPC responses, console/log, menu clicks, etc.).
|
|
||||||
- windowKeyEvents: key accelerator strings per window; processed by WebviewWindow to run actions or menu accelerators.
|
|
||||||
- windowDragAndDropBuffer: drag-and-drop messages containing filenames and drop-zone details; dispatched to the destination window.
|
|
||||||
- menuItemClicked: menu item selection IDs enqueued by platform menu handlers and dispatched to Menu manager.
|
|
||||||
|
|
||||||
|
|
||||||
How to trace the flow yourself
|
|
||||||
- Set breakpoints in application.go Run() and platform newPlatformApp(...) to observe startup.
|
|
||||||
- On Windows, observe application_windows.go run() and wndProc() to see message dispatch into channels.
|
|
||||||
- Create a simple Example (see v3/examples) and instrument NewWindow() and WebviewWindow.HandleMessage() to see frontend<->backend calls.
|
|
||||||
- Enable dev logging (logger_dev*.go) to see debug lines emitted when events and drag-and-drop messages are processed.
|
|
||||||
|
|
||||||
|
|
||||||
Practical usage pattern (developer API surface)
|
|
||||||
- Create and configure the app:
|
|
||||||
- app := application.New(application.Options{ /* set windows, assets, menu, services, etc. */ })
|
|
||||||
- mainWindow := application.NewWindow(webview_window_options)
|
|
||||||
- mainWindow.Show()
|
|
||||||
- return app.Run()
|
|
||||||
- Register services via app.RegisterService(...) before Run().
|
|
||||||
- Use app.Event.On/Once to register for application events (ApplicationStarted, ThemeChanged, etc.).
|
|
||||||
- Use window.OnWindowEvent to subscribe to per-window events.
|
|
||||||
- Use dialogs via application.InfoDialog()/OpenFileDialog()/SaveFileDialog(), etc.
|
|
||||||
|
|
||||||
This deep dive should equip you to understand and trace how an application is initialised and run across platforms within the v3/pkg/application package.
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# Drag-and-Drop Analysis (Windows Focus)
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
- Wails v3 supports two drag-and-drop surfaces when `EnableDragAndDrop` is set: a native window-level file drop channel and HTML drag/drop within the embedded webview. You can see the end-to-end flow in `v3/pkg/application/webview_window_windows.go` (native bridge) and `v3/internal/runtime/desktop/@wailsio/runtime/src/window.ts` (runtime dispatcher).
|
|
||||||
- Native drops rely on a custom `IDropTarget` implementation that gathers files/coordinates from Win32, pushes them through the Wails event system, and fan out as `events.Common.WindowDropZoneFilesDropped` with enriched context (`DropZoneDetails`, attribute map, coordinates).
|
|
||||||
- Pure HTML drag/drop (e.g. `v3/examples/html-dnd-api`) is handled entirely by the browser layer; Wails only needs to stay out of the way so standard DOM APIs operate normally.
|
|
||||||
|
|
||||||
## Native/Go Pipeline
|
|
||||||
1. When a window is created with `EnableDragAndDrop`, line ~1948 of `v3/pkg/application/webview_window_windows.go` instantiates `w32.NewDropTarget()` and (optionally) calls `chromium.AllowExternalDrag(false)` to disable WebView2’s built-in file handling.
|
|
||||||
2. `EnumChildWindows` registers the COM drop target against every current child HWND. The callbacks (`OnEnter`, `OnOver`, `OnLeave`, `OnDrop`) emit Windows-specific events (`events.Windows.WindowDragEnter` etc.) via `w.parent.emit`, so listeners can react even before files are delivered.
|
|
||||||
3. `DropTarget.Drop` (see `v3/pkg/w32/idroptarget.go:69-140`) extracts filenames from the `IDataObject`, then hands control back to the window impl. Coordinates arrive as screen pixels (`POINT`), so `OnDrop` converts to window-relative coordinates and then calls `convertWindowToWebviewCoordinates` (lines ~1908-1990). Finally `InitiateFrontendDropProcessing` (in `v3/pkg/application/webview_window.go:1484-1515`) formats a JS call: `window.wails.Window.HandlePlatformFileDrop([...], x, y)`.
|
|
||||||
4. `MessageProcessor` case `WindowDropZoneDropped` (`v3/pkg/application/messageprocessor_window.go:430-488`) decodes the payload that the runtime posts back, wraps it in `DropZoneDetails`, and pushes it through the buffered `windowDragAndDropBuffer`. `App.handleDragAndDropMessage` picks it up and forwards to `WebviewWindow.HandleDragAndDropMessage`, which attaches dropped files + drop-zone metadata to the `WindowEventContext`.
|
|
||||||
5. The consumer API is the `events.Common.WindowDropZoneFilesDropped` event. The drag-n-drop example shows how to subscribe (`v3/examples/drag-n-drop/main.go:109-158`) and propagate to the frontend via custom events.
|
|
||||||
|
|
||||||
## Runtime/JS Behaviour
|
|
||||||
- `@wailsio/runtime/src/window.ts:538-680` controls the frontend side. `HandlePlatformFileDrop` locates a drop target using `document.elementFromPoint` and `closest([data-wails-dropzone])`; if nothing qualifies it returns early, so native drops that miss a registered dropzone never reach Go.
|
|
||||||
- The runtime maintains hover styling by tracking `dragenter/over/leave` on `document.documentElement` and toggling `wails-dropzone-hover`. This is how the example achieves live highlighting.
|
|
||||||
- A legacy helper still exists: `System.HandlePlatformFileDrop` in `@wailsio/runtime/src/system.ts:159-184` marshals a different payload and calls method id `ApplicationFilesDroppedWithContext`, but there is no matching handler in `messageprocessor_application.go`. That means any codepath that invokes it would receive an HTTP 400/500.
|
|
||||||
- The window runtime bundles `drag.ts`, which manages `--wails-draggable` regions so window dragging/resizing does not swallow pointer events. Developers must ensure dropzones are not also marked draggable.
|
|
||||||
|
|
||||||
## Example Insights
|
|
||||||
- `v3/examples/drag-n-drop/assets/index.html` annotates folders with `data-wails-dropzone` and demonstrates how attributes flow through to Go (`DropZoneDetails.Attributes`). It also shows that the frontend expects `dropX/dropY` in CSS pixels, which helps when validating coordinate transforms.
|
|
||||||
- `v3/examples/html-dnd-api` confirms standard HTML DnD works without the native bridge; it is a useful regression test when tweaking `drag.ts` so pointer suppression does not break DOM events.
|
|
||||||
|
|
||||||
## Potential Bug Hotspots
|
|
||||||
- **Window-level drops ignored** - `window.ts:554-569` bails if no dropzone is discovered, so the documented `WindowFilesDropped` event never fires. Users expecting “drop anywhere” support lose file payloads entirely.
|
|
||||||
- **Coordinate scaling** - `convertWindowToWebviewCoordinates` (`webview_window_windows.go:1908-1994`) computes offsets using physical pixels but never converts to WebView2 DIPs. On mixed-DPI or >100% scaling setups, `elementFromPoint` will query the wrong DOM position.
|
|
||||||
- **Drop target lifecycle** - `EnumChildWindows` runs only once during initialisation. WebView2 can spawn new `Chrome_RenderWidgetHostHWND` instances on navigation or GPU process resets, leaving them unregistered and breaking drops until the app restarts.
|
|
||||||
- **OLE cleanup** - `DropTarget.Drop` never calls `w32.DragFinish` after `DragQueryFile`. Windows docs recommend doing so to release HDROP resources; skipping it risks leaks on repeated drops.
|
|
||||||
- **Stale runtime API** - `System.HandlePlatformFileDrop` references a non-existent backend method (`messageprocessor_application.go` lacks case 100). Any future JS that follows the generated docs will fail at runtime.
|
|
||||||
- **Backpressure risk** - `windowDragAndDropBuffer` (channel size 5) blocks the HTTP handler if event consumers stall. Heavy processing in listeners could cause the runtime call to hang and, on Windows, freeze the drag cursor until the fetch resolves.
|
|
||||||
|
|
||||||
## Improvement Opportunities
|
|
||||||
1. Emit a fallback `WindowFilesDropped` event directly from `DropTarget.OnDrop` when `HandlePlatformFileDrop` declines the payload, preserving drop-anywhere behaviour.
|
|
||||||
2. Introduce DPI-aware coordinate conversion (use `globalApplication.Screen.PhysicalToDipPoint`) before invoking `elementFromPoint`.
|
|
||||||
3. Re-run `RegisterDragDrop` whenever a new WebView child window appears (CoreWebView2 `FrameCreated` / `NewBrowserVersionAvailable` callbacks) and on navigation completions.
|
|
||||||
4. Either wire up the `ApplicationFilesDroppedWithContext` method or remove the `System.HandlePlatformFileDrop` export to avoid misleading integrators.
|
|
||||||
5. Add integration tests that exercise drops on high-DPI displays and across multiple monitors using the drag-n-drop example as a harness.
|
|
||||||
6. Consider surfacing drop-target state (e.g., active element id) via diagnostic logging so Windows reports can be correlated without attaching a debugger.
|
|
||||||
|
|
||||||
## Open Questions
|
|
||||||
- Do we need to respect WebView2’s native `AllowExternalDrop(true)` when `EnableDragAndDrop` is disabled, or should we expose both behaviours concurrently?
|
|
||||||
- How should conflicting CSS states (`--wails-draggable` vs `data-wails-dropzone`) be resolved? Current logic leaves it up to the developer, but documenting or enforcing precedence could prevent accidental suppression.
|
|
||||||
- Can we guarantee that `elementFromPoint` is safe when overlays or transparent windows are involved, or do we need hit-testing improvements using `elementsFromPoint`?
|
|
||||||
- Would it be safer to move drop processing entirely to Go (dispatching both window-wide and targeted events) and keep JS solely for hover styling?
|
|
||||||
246
DND_ISSUES.md
|
|
@ -1,246 +0,0 @@
|
||||||
# Wails Drag and Drop Issues Report
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
This report compiles all drag and drop related issues found in Wails v3 GitHub repository. The issues span across multiple platforms (Windows, macOS, Linux) and various versions of Wails.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #1: [V3] Drag-and-drop broken on Windows since alpha 19
|
|
||||||
|
|
||||||
**Title:** [V3] Drag-and-drop broken on windows since alpha 19
|
|
||||||
**Platform:** Windows 10
|
|
||||||
**Reported:** 2024-08-09
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** xob0t
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/4489
|
|
||||||
|
|
||||||
**Summary:** No drag and drop events are triggered on the Go side in Wails v3 alpha 20+. The issue appears to have been introduced by PR #4318.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. Run dnd example on Windows
|
|
||||||
2. Observe that no DnD events are triggered
|
|
||||||
|
|
||||||
**System:** Windows 10 Pro, Wails v3.0.0-alpha.20, AMD Ryzen 5 5600X, NVIDIA GeForce RTX 3070
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #2: Windows 10 doesn't receive drag and drop events on the backend
|
|
||||||
|
|
||||||
**Title:** Windows 10 doesn't receive drag and drop events on the backend
|
|
||||||
**Platform:** Windows 10
|
|
||||||
**Reported:** 2025-01-07
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** makew0rld
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3985
|
|
||||||
|
|
||||||
**Summary:** Backend drop handler registered with `runtime.OnFileDrop` never gets executed when dropping files on Windows 10, though JavaScript drop events do fire. The event is not being propagated to the backend properly.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. Clone https://github.com/makew0rld/wails-issue-3985
|
|
||||||
2. Build for Windows: `wails build -platform windows/amd64 -windowsconsole -debug`
|
|
||||||
3. Open the .exe in Windows
|
|
||||||
4. Open web console using right-click menu
|
|
||||||
5. Drag in a file
|
|
||||||
6. Observe nothing appears in backend console, but drop event appears in web console
|
|
||||||
|
|
||||||
**System:** Built on Arch Linux, tested on Windows 10 VM, Wails v2.9.2
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #3: [v3] [mac] drag n drop does not work as expected after resizing window
|
|
||||||
|
|
||||||
**Title:** [v3] [mac] drag n drop does not work as expected after resizing window
|
|
||||||
**Platform:** macOS
|
|
||||||
**Reported:** 2024-09-12
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** Etesam913
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3743
|
|
||||||
|
|
||||||
**Summary:** On macOS, after resizing the window, drag and drop usually gets rejected when trying to drag a file into the window.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. `git checkout v3-alpha`
|
|
||||||
2. `cd v3/examples/drag-n-drop`
|
|
||||||
3. `go run main.go`
|
|
||||||
4. Resize window
|
|
||||||
5. Drag file into window
|
|
||||||
6. File gets rejected
|
|
||||||
|
|
||||||
**System:** macOS 15.0, Apple M2, Wails v3.0.0-alpha.6
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #4: Webview failed to set AllowExternalDrag to false on Win 10
|
|
||||||
|
|
||||||
**Title:** Webview failed to set AllowExternalDrag to false on Win 10 (after cross compile on macOS)
|
|
||||||
**Platform:** Windows 10
|
|
||||||
**Reported:** 2024-09-26
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** barats
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3782
|
|
||||||
|
|
||||||
**Summary:** Two main issues: 1) WebView fails to set AllowExternalDrag to false, causing WebView to automatically open dragged files. 2) Backend `runtime.OnFileDrop` doesn't work - no events are triggered.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. Build windows/amd64 app on macOS
|
|
||||||
2. Move .exe files to Win10 and run
|
|
||||||
3. Drag and drop files into app window
|
|
||||||
4. WebView DnD not disabled, backend events not called
|
|
||||||
|
|
||||||
**System:** Built on macOS 15.0, tested on Windows 10, Wails v2.9.2
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #5: [v2] Files DragAndDrop bugs
|
|
||||||
|
|
||||||
**Title:** [v2] Files DragAndDrop bugs
|
|
||||||
**Platform:** Linux (Ubuntu)
|
|
||||||
**Reported:** 2024-06-23
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** Vovan-VE
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3563
|
|
||||||
|
|
||||||
**Summary:** Two issues: 1) When only `EnableFileDrop: true`, every D'n'D triggers an `OnDomReady` event. 2) When `EnableFileDrop: true, DisableWebViewDrop: true`, D'n'D doesn't work at all for files.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
```go
|
|
||||||
func (a *App) domReady(ctx context.Context) {
|
|
||||||
runtime.OnFileDropOff(ctx)
|
|
||||||
runtime.LogInfof(ctx, "DOM READY -------------------------------\n%+v", errors.New("WTF?"))
|
|
||||||
runtime.OnFileDrop(ctx, a.onFileDrop)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) onFileDrop(x, y int, paths []string) {
|
|
||||||
runtime.LogInfof(a.ctx, "drop files: %#v\n%+v", paths, errors.New("WTF?"))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**System:** Ubuntu 22.04, AMD Ryzen 9 7950X, Wails v2.9.1 and v2.9.2
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #6: File drag and drop displays file in Linux WebKit
|
|
||||||
|
|
||||||
**Title:** File drag and drop displays file in Linux WebKit
|
|
||||||
**Platform:** Linux
|
|
||||||
**Reported:** 2024-08-17
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** makew0rld
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3686
|
|
||||||
|
|
||||||
**Summary:** When dragging and dropping a file onto the Window, the `OnFileDrop` handler runs successfully, but the entire GUI is replaced with a view of the file if the browser supports it (e.g., images, PDFs). This makes the dropped file unusable as all UI is gone.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. Enable file dropping and add a simple handler
|
|
||||||
2. Try and drop an image file with WebKit on Linux
|
|
||||||
3. Observe the UI get replaced with a view of the image
|
|
||||||
|
|
||||||
**System:** Arch Linux, Intel Core i7-1165G7, Wails v2.9.1
|
|
||||||
|
|
||||||
**Note:** Issue was closed on 2025-08-02 with a workaround involving preventDefault() on drop and dragover events.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #7: Drag And Drop "wails-drop-target-active" class issue
|
|
||||||
|
|
||||||
**Title:** Drag And Drop "wails-drop-target-active" class is only applied if cssDropProperty is set via raw `style`
|
|
||||||
**Platform:** Windows
|
|
||||||
**Reported:** 2025-07-13
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** riannucci
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/4419
|
|
||||||
|
|
||||||
**Summary:** `OnFileDrop` does not apply the `wails-drop-target-active` class unless `--wails-drop-target: drop` is set directly via the element's `style` attribute, even though the `OnFileDrop` callback does fire.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. Set up a new wails project
|
|
||||||
2. Set EnableFileDrop in Application Options
|
|
||||||
3. Add CSS with `--wails-drop-target: drop` in stylesheet
|
|
||||||
4. Run app and drag file to target element
|
|
||||||
5. Base path gets set but element doesn't change styles
|
|
||||||
|
|
||||||
**System:** Windows 10/11 Pro, AMD Ryzen 7 5800X3D, Wails v2.10.2
|
|
||||||
|
|
||||||
**Note:** Issue was closed on 2025-08-02. Problem was in draganddrop.js using element.style instead of getComputedStyle.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #8: Use a user-agent that is more recognizable by front-end code
|
|
||||||
|
|
||||||
**Title:** Use a user-agent that is more recognizable by front-end code
|
|
||||||
**Platform:** macOS
|
|
||||||
**Reported:** 2024-01-31
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** hsiafan
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3226
|
|
||||||
|
|
||||||
**Summary:** SortableJS (drag-and-drop library) doesn't work properly in Wails' webview because the userAgent doesn't contain standard browser identifiers like 'Safari/605.1.15', causing library detection to fail.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
Libraries like SortableJS check userAgent for specific strings ('Edge', 'Firefox', 'Chrome', 'Safari') and fail to work properly when these are not present.
|
|
||||||
|
|
||||||
**System:** macOS, affects drag-and-drop libraries
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #9: Application soft crashes when using vue-virtual-scroller on Linux
|
|
||||||
|
|
||||||
**Title:** Application soft crashes when using vue-virtual-scroller on Linux
|
|
||||||
**Platform:** Linux (Ubuntu)
|
|
||||||
**Reported:** 2024-10-22
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** ysmilda
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3849
|
|
||||||
|
|
||||||
**Summary:** Using vue-virtual-scroller component causes the application to crash on Linux builds, rendering a grey screen and hanging the inspector window. Works fine on Windows and in dev view.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. Create new wails instance with `wails init -n myproject -t vue-ts`
|
|
||||||
2. Add vue-virtual-scroller component
|
|
||||||
3. Create Linux build (`wails build -tags webkit2_41`)
|
|
||||||
4. Observe crash while rendering
|
|
||||||
|
|
||||||
**System:** Ubuntu 24.04, Intel Core i7-12700, Wails v2.9.2
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Issue #10: [DragAndDrop] panic when dropping non-file objects
|
|
||||||
|
|
||||||
**Title:** [DragAndDrop] panic when dropping non-file objects
|
|
||||||
**Platform:** Windows
|
|
||||||
**Reported:** 2024-07-09
|
|
||||||
**Location:** GitHub
|
|
||||||
**Reporter:** Alpa-1
|
|
||||||
**Link:** https://github.com/wailsapp/wails/issues/3596
|
|
||||||
|
|
||||||
**Summary:** A panic occurs when dropping non-file objects (like strings or browser tabs) into the webview. The application crashes with a nil pointer dereference.
|
|
||||||
|
|
||||||
**Reproduction:**
|
|
||||||
1. Enable DragAndDrop
|
|
||||||
2. Add a drop target on frontend with `--wails-drop-target`
|
|
||||||
3. Register a callback with `OnFileDrop((x,y,f) => { console.log(f) }, true)`
|
|
||||||
4. Drop a Browser Tab onto the element
|
|
||||||
5. Application panics
|
|
||||||
|
|
||||||
**System:** Windows 10 Enterprise, AMD Ryzen 7 PRO 4750U, Wails v2.9.1
|
|
||||||
|
|
||||||
**Note:** Issue was closed on 2024-08-18. A simple nil check fix was provided.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Common Patterns Identified:
|
|
||||||
|
|
||||||
1. **Platform-specific issues:** Windows has the most reported issues, particularly with events not reaching the backend
|
|
||||||
2. **Version regression:** Multiple reports indicate v3 alpha 19+ broke drag and drop on Windows
|
|
||||||
3. **WebView configuration:** Several issues relate to DisableWebViewDrop not working correctly
|
|
||||||
4. **Cross-platform builds:** Issues when building for Windows on other platforms
|
|
||||||
5. **Frontend/Backend disconnect:** Common pattern of JavaScript events firing but Go handlers not receiving events
|
|
||||||
6. **UI replacement on Linux:** Specific issue where dropped files replace the entire UI in WebKit
|
|
||||||
|
|
||||||
## Recommendations:
|
|
||||||
|
|
||||||
1. Focus on Windows platform issues first as they are most prevalent
|
|
||||||
2. Investigate the changes in PR #4318 which allegedly broke Windows DnD
|
|
||||||
3. Review the event propagation mechanism between frontend and backend
|
|
||||||
4. Test cross-platform builds more thoroughly
|
|
||||||
5. Improve documentation on DragAndDrop configuration options
|
|
||||||
|
|
@ -25,7 +25,7 @@ Erschaffe Desktop Anwendungen mit Go & Web Technologien.
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
@ -98,9 +98,9 @@ The installation instructions are on the [official website](https://wails.io/doc
|
||||||
This project is supported by these kind people / companies:
|
This project is supported by these kind people / companies:
|
||||||
<img src="website/static/img/sponsors.svg" style="width:100%;max-width:800px;"/>
|
<img src="website/static/img/sponsors.svg" style="width:100%;max-width:800px;"/>
|
||||||
|
|
||||||
<p align="center">
|
## Powered By
|
||||||
<img src="https://wails.io/img/sponsor/jetbrains-grayscale.webp" style="width: 100px"/>
|
|
||||||
</p>
|
[](https://jb.gg/OpenSource)
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/BrRSWTaxVK">
|
<a href="https://discord.gg/BrRSWTaxVK">
|
||||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
<img alt="Discord" src="https://img.shields.io/discord/1042734330029547630?logo=discord"/>
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,6 @@ includes:
|
||||||
dir: v3
|
dir: v3
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
docs:
|
|
||||||
taskfile: docs
|
|
||||||
dir: docs
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
contributors:check:
|
contributors:check:
|
||||||
cmds:
|
cmds:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
import { defineConfig } from 'astro/config';
|
|
||||||
import d2 from 'astro-d2';
|
|
||||||
// https://astro.build/config
|
|
||||||
export default defineConfig({
|
|
||||||
integrations: [d2()]
|
|
||||||
});
|
|
||||||
21
docs/.gitignore
vendored
|
|
@ -1,21 +0,0 @@
|
||||||
# build output
|
|
||||||
dist/
|
|
||||||
# generated types
|
|
||||||
.astro/
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# logs
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
|
|
||||||
|
|
||||||
# environment variables
|
|
||||||
.env
|
|
||||||
.env.production
|
|
||||||
|
|
||||||
# macOS-specific files
|
|
||||||
.DS_Store
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
save-exact=true
|
|
||||||
4
docs/.vscode/extensions.json
vendored
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"recommendations": ["astro-build.astro-vscode"],
|
|
||||||
"unwantedRecommendations": []
|
|
||||||
}
|
|
||||||
11
docs/.vscode/launch.json
vendored
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"command": "./node_modules/.bin/astro dev",
|
|
||||||
"name": "Development server",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "node-terminal"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
v3alpha.wails.io
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# Wails v3 Documentation
|
|
||||||
|
|
||||||
[](https://starlight.astro.build)
|
|
||||||
|
|
||||||
World-class documentation for Wails v3, redesigned following Netflix documentation principles.
|
|
||||||
|
|
||||||
## 📚 Documentation Redesign (2025-10-01)
|
|
||||||
|
|
||||||
This documentation has been completely redesigned to follow the **Netflix approach** to developer documentation:
|
|
||||||
|
|
||||||
- **Problem-first framing** - Start with why, not what
|
|
||||||
- **Progressive disclosure** - Multiple entry points for different skill levels
|
|
||||||
- **Real production examples** - No toy code
|
|
||||||
- **Story-Code-Context pattern** - Why → How → When
|
|
||||||
- **Scannable content** - Clear structure, visual aids
|
|
||||||
|
|
||||||
**Status:** Foundation complete (~20%), ready for content migration
|
|
||||||
|
|
||||||
See [IMPLEMENTATION_SUMMARY.md](./IMPLEMENTATION_SUMMARY.md) for full details.
|
|
||||||
|
|
||||||
## 🚀 Project Structure
|
|
||||||
|
|
||||||
Inside of your Astro + Starlight project, you'll see the following folders and
|
|
||||||
files:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
.
|
|
||||||
├── public/
|
|
||||||
├── src/
|
|
||||||
│ ├── assets/
|
|
||||||
│ ├── content/
|
|
||||||
│ │ ├── docs/
|
|
||||||
│ │ └── config.ts
|
|
||||||
│ └── env.d.ts
|
|
||||||
├── astro.config.mjs
|
|
||||||
├── package.json
|
|
||||||
└── tsconfig.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory.
|
|
||||||
Each file is exposed as a route based on its file name.
|
|
||||||
|
|
||||||
Images can be added to `src/assets/` and embedded in Markdown with a relative
|
|
||||||
link.
|
|
||||||
|
|
||||||
Static assets, like favicons, can be placed in the `public/` directory.
|
|
||||||
|
|
||||||
## 🧞 Commands
|
|
||||||
|
|
||||||
All commands are run from the root of the project, from a terminal:
|
|
||||||
|
|
||||||
| Command | Action |
|
|
||||||
| :------------------------ | :----------------------------------------------- |
|
|
||||||
| `npm install` | Installs dependencies |
|
|
||||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
|
||||||
| `npm run build` | Build your production site to `./dist/` |
|
|
||||||
| `npm run preview` | Preview your build locally, before deploying |
|
|
||||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
|
||||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
|
||||||
|
|
||||||
## 👀 Want to learn more?
|
|
||||||
|
|
||||||
Check out [Starlight’s docs](https://starlight.astro.build/), read
|
|
||||||
[the Astro documentation](https://docs.astro.build), or jump into the
|
|
||||||
[Astro Discord server](https://astro.build/chat).
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
# https://taskfile.dev
|
|
||||||
|
|
||||||
version: '3'
|
|
||||||
|
|
||||||
vars:
|
|
||||||
# Change this to switch package managers: bun, npm, pnpm, yarn
|
|
||||||
PKG_MANAGER: bun
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
|
|
||||||
setup:
|
|
||||||
summary: Setup the project (including D2 diagram tool)
|
|
||||||
preconditions:
|
|
||||||
- sh: '{{.PKG_MANAGER}} --version'
|
|
||||||
msg: "Looks like {{.PKG_MANAGER}} isn't installed."
|
|
||||||
- sh: 'go version'
|
|
||||||
msg: "Go is not installed. Install from https://go.dev/dl/"
|
|
||||||
cmds:
|
|
||||||
- '{{.PKG_MANAGER}} install'
|
|
||||||
- go install oss.terrastruct.com/d2@latest
|
|
||||||
- echo "✓ Setup complete. D2 installed to $(go env GOPATH)/bin/d2"
|
|
||||||
|
|
||||||
dev:
|
|
||||||
summary: Run the dev server
|
|
||||||
preconditions:
|
|
||||||
- sh: '{{.PKG_MANAGER}} --version'
|
|
||||||
msg: "Looks like {{.PKG_MANAGER}} isn't installed."
|
|
||||||
cmds:
|
|
||||||
- '{{.PKG_MANAGER}} run dev'
|
|
||||||
|
|
||||||
build:
|
|
||||||
summary: Build the docs
|
|
||||||
preconditions:
|
|
||||||
- sh: '{{.PKG_MANAGER}} --version'
|
|
||||||
msg: "Looks like {{.PKG_MANAGER}} isn't installed."
|
|
||||||
cmds:
|
|
||||||
- '{{.PKG_MANAGER}} run build'
|
|
||||||
|
|
||||||
|
|
@ -1,342 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
import { defineConfig } from "astro/config";
|
|
||||||
import starlight from "@astrojs/starlight";
|
|
||||||
import sitemap from "@astrojs/sitemap";
|
|
||||||
import starlightLinksValidator from "starlight-links-validator";
|
|
||||||
import starlightImageZoom from "starlight-image-zoom";
|
|
||||||
import starlightBlog from "starlight-blog";
|
|
||||||
import { authors } from "./src/content/authors";
|
|
||||||
import d2 from 'astro-d2';
|
|
||||||
|
|
||||||
// https://astro.build/config
|
|
||||||
export default defineConfig({
|
|
||||||
site: "https://wails.io",
|
|
||||||
trailingSlash: "ignore",
|
|
||||||
compressHTML: true,
|
|
||||||
output: "static",
|
|
||||||
build: { format: "directory" },
|
|
||||||
devToolbar: { enabled: true },
|
|
||||||
integrations: [
|
|
||||||
d2(),
|
|
||||||
sitemap(),
|
|
||||||
starlight({
|
|
||||||
title: "",
|
|
||||||
titleDelimiter: "",
|
|
||||||
logo: {
|
|
||||||
dark: "./src/assets/wails-logo-horizontal-dark.svg",
|
|
||||||
light: "./src/assets/wails-logo-horizontal-light.svg",
|
|
||||||
},
|
|
||||||
favicon: "./public/favicon.svg",
|
|
||||||
description: "Build beautiful desktop applications using Go and modern web technologies.",
|
|
||||||
pagefind: true,
|
|
||||||
customCss: ["./src/stylesheets/extra.css"],
|
|
||||||
lastUpdated: true,
|
|
||||||
pagination: true,
|
|
||||||
editLink: {
|
|
||||||
baseUrl: "https://github.com/wailsapp/wails/edit/v3-alpha/docs",
|
|
||||||
},
|
|
||||||
social: {
|
|
||||||
github: "https://github.com/wailsapp/wails",
|
|
||||||
discord: "https://discord.gg/JDdSxwjhGf",
|
|
||||||
"x.com": "https://x.com/wailsapp",
|
|
||||||
},
|
|
||||||
head: [
|
|
||||||
{
|
|
||||||
tag: 'script',
|
|
||||||
content: `
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const socialLinks = document.querySelector('.social-icons');
|
|
||||||
if (socialLinks) {
|
|
||||||
const sponsorLink = document.createElement('a');
|
|
||||||
sponsorLink.href = 'https://github.com/sponsors/leaanthony';
|
|
||||||
sponsorLink.className = 'sl-flex';
|
|
||||||
sponsorLink.title = 'Sponsor';
|
|
||||||
sponsorLink.innerHTML = '<span class="sr-only">Sponsor</span><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="#ef4444" stroke="none"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/></svg>';
|
|
||||||
socialLinks.appendChild(sponsorLink);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
defaultLocale: "root",
|
|
||||||
locales: {
|
|
||||||
root: { label: "English", lang: "en", dir: "ltr" },
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
starlightImageZoom(),
|
|
||||||
starlightBlog({
|
|
||||||
title: "Wails Blog",
|
|
||||||
authors: authors,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
sidebar: [
|
|
||||||
{ label: "Home", link: "/" },
|
|
||||||
|
|
||||||
// Progressive Onboarding - Netflix Principle: Start with the problem
|
|
||||||
{ label: "Why Wails?", link: "/quick-start/why-wails" },
|
|
||||||
|
|
||||||
{
|
|
||||||
label: "Quick Start",
|
|
||||||
collapsed: false,
|
|
||||||
items: [
|
|
||||||
{ label: "Installation", link: "/quick-start/installation" },
|
|
||||||
{ label: "Your First App", link: "/quick-start/first-app" },
|
|
||||||
{ label: "Next Steps", link: "/quick-start/next-steps" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// Tutorials
|
|
||||||
{
|
|
||||||
label: "Tutorials",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "tutorials" },
|
|
||||||
},
|
|
||||||
|
|
||||||
// Core Concepts
|
|
||||||
{
|
|
||||||
label: "Core Concepts",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "How Wails Works", link: "/concepts/architecture" },
|
|
||||||
{ label: "Manager API", link: "/concepts/manager-api" },
|
|
||||||
{ label: "Application Lifecycle", link: "/concepts/lifecycle" },
|
|
||||||
{ label: "Go-Frontend Bridge", link: "/concepts/bridge" },
|
|
||||||
{ label: "Build System", link: "/concepts/build-system" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: "Features",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: "Windows",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Window Basics", link: "/features/windows/basics" },
|
|
||||||
{ label: "Window Options", link: "/features/windows/options" },
|
|
||||||
{ label: "Multiple Windows", link: "/features/windows/multiple" },
|
|
||||||
{ label: "Frameless Windows", link: "/features/windows/frameless" },
|
|
||||||
{ label: "Window Events", link: "/features/windows/events" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Menus",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Application Menus", link: "/features/menus/application" },
|
|
||||||
{ label: "Context Menus", link: "/features/menus/context" },
|
|
||||||
{ label: "System Tray Menus", link: "/features/menus/systray" },
|
|
||||||
{ label: "Menu Reference", link: "/features/menus/reference" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Bindings & Services",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Method Binding", link: "/features/bindings/methods" },
|
|
||||||
{ label: "Services", link: "/features/bindings/services" },
|
|
||||||
{ label: "Advanced Binding", link: "/features/bindings/advanced" },
|
|
||||||
{ label: "Best Practices", link: "/features/bindings/best-practices" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Events",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Event System", link: "/features/events/system" },
|
|
||||||
{ label: "Application Events", link: "/features/events/application" },
|
|
||||||
{ label: "Window Events", link: "/features/events/window" },
|
|
||||||
{ label: "Custom Events", link: "/features/events/custom" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Dialogs",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "File Dialogs", link: "/features/dialogs/file" },
|
|
||||||
{ label: "Message Dialogs", link: "/features/dialogs/message" },
|
|
||||||
{ label: "Custom Dialogs", link: "/features/dialogs/custom" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Clipboard",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "features/clipboard" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Browser",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "features/browser" },
|
|
||||||
},
|
|
||||||
{ label: "Drag & Drop", link: "/features/drag-drop" },
|
|
||||||
{
|
|
||||||
label: "Keyboard",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "features/keyboard" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Notifications",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "features/notifications" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Screens",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "features/screens" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Environment",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "features/environment" },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Platform-Specific",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "features/platform" },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// Guides - Task-oriented patterns (Netflix: When to use it, when not to use it)
|
|
||||||
{
|
|
||||||
label: "Guides",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
label: "Development",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Project Structure", link: "/guides/dev/project-structure" },
|
|
||||||
{ label: "Development Workflow", link: "/guides/dev/workflow" },
|
|
||||||
{ label: "Debugging", link: "/guides/dev/debugging" },
|
|
||||||
{ label: "Testing", link: "/guides/dev/testing" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Building & Packaging",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Building Applications", link: "/guides/build/building" },
|
|
||||||
{ label: "Build Customization", link: "/guides/build/customization" },
|
|
||||||
{ label: "Cross-Platform Builds", link: "/guides/build/cross-platform" },
|
|
||||||
{ label: "Code Signing", link: "/guides/build/signing" },
|
|
||||||
{ label: "Windows Packaging", link: "/guides/build/windows" },
|
|
||||||
{ label: "macOS Packaging", link: "/guides/build/macos" },
|
|
||||||
{ label: "Linux Packaging", link: "/guides/build/linux" },
|
|
||||||
{ label: "MSIX Packaging", link: "/guides/build/msix" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Distribution",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Auto-Updates", link: "/guides/distribution/auto-updates" },
|
|
||||||
{ label: "File Associations", link: "/guides/distribution/file-associations" },
|
|
||||||
{ label: "Custom Protocols", link: "/guides/distribution/custom-protocols" },
|
|
||||||
{ label: "Single Instance", link: "/guides/distribution/single-instance" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Integration Patterns",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Using Gin Router", link: "/guides/patterns/gin-routing" },
|
|
||||||
{ label: "Gin Services", link: "/guides/patterns/gin-services" },
|
|
||||||
{ label: "Database Integration", link: "/guides/patterns/database" },
|
|
||||||
{ label: "REST APIs", link: "/guides/patterns/rest-api" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Advanced Topics",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Custom Templates", link: "/guides/advanced/custom-templates" },
|
|
||||||
{ label: "WML (Wails Markup)", link: "/guides/advanced/wml" },
|
|
||||||
{ label: "Panic Handling", link: "/guides/advanced/panic-handling" },
|
|
||||||
{ label: "Security Best Practices", link: "/guides/advanced/security" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// Reference - Comprehensive API docs (Netflix: Complete technical reference)
|
|
||||||
{
|
|
||||||
label: "API Reference",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Overview", link: "/reference/overview" },
|
|
||||||
{ label: "Application", link: "/reference/application" },
|
|
||||||
{ label: "Window", link: "/reference/window" },
|
|
||||||
{ label: "Menu", link: "/reference/menu" },
|
|
||||||
{ label: "Events", link: "/reference/events" },
|
|
||||||
{ label: "Dialogs", link: "/reference/dialogs" },
|
|
||||||
{ label: "Frontend Runtime", link: "/reference/frontend-runtime" },
|
|
||||||
{ label: "CLI", link: "/reference/cli" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// Contributing
|
|
||||||
{
|
|
||||||
label: "Contributing",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Getting Started", link: "/contributing/getting-started" },
|
|
||||||
{ label: "Development Setup", link: "/contributing/setup" },
|
|
||||||
{ label: "Coding Standards", link: "/contributing/standards" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// Migration & Troubleshooting
|
|
||||||
{
|
|
||||||
label: "Migration",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "From v2 to v3", link: "/migration/v2-to-v3" },
|
|
||||||
{ label: "From Electron", link: "/migration/from-electron" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: "Troubleshooting",
|
|
||||||
collapsed: true,
|
|
||||||
autogenerate: { directory: "troubleshooting" },
|
|
||||||
},
|
|
||||||
|
|
||||||
// Community & Resources
|
|
||||||
{
|
|
||||||
label: "Community",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Links", link: "/community/links" },
|
|
||||||
{ label: "Templates", link: "/community/templates" },
|
|
||||||
{
|
|
||||||
label: "Showcase",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ label: "Overview", link: "/community/showcase" },
|
|
||||||
{
|
|
||||||
label: "Applications",
|
|
||||||
autogenerate: {
|
|
||||||
directory: "community/showcase",
|
|
||||||
collapsed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{ label: "What's New", link: "/whats-new" },
|
|
||||||
{ label: "Status", link: "/status" },
|
|
||||||
{ label: "Changelog", link: "/changelog" },
|
|
||||||
{
|
|
||||||
label: "Sponsor",
|
|
||||||
link: "https://github.com/sponsors/leaanthony",
|
|
||||||
badge: { text: "❤️" },
|
|
||||||
},
|
|
||||||
{ label: "Credits", link: "/credits" },
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
$ astro build
|
|
||||||
10:08:53 [WARN] [starlight-blog-plugin] It looks like you already have a `MarkdownContent` component override in your Starlight configuration.
|
|
||||||
10:08:53 [WARN] [starlight-blog-plugin] To use `starlight-blog`, either remove your override or update it to render the content from `starlight-blog/overrides/MarkdownContent.astro`.
|
|
||||||
10:08:54 [content] Syncing content
|
|
||||||
10:08:54 [WARN] [glob-loader] The base directory "E:\wails\docs\src\content\i18n\" does not exist.
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
10:08:55 [WARN] [astro-expressive-code] Error while loading code block language "pseudo" in document "E:\wails\docs\src\content\docs\DEVELOPER_GUIDE.md". Using "txt" instead. You can add custom languages using the "langs" config option. Error details: Unknown language "pseudo"
|
|
||||||
bad indentation of a mapping entry
|
|
||||||
Location:
|
|
||||||
E:\wails\docs\src\content\docs\learn\context-menu.mdx:3:7
|
|
||||||
Stack trace:
|
|
||||||
at generateError (file:///E:/wails/docs/node_modules/js-yaml/dist/js-yaml.mjs:1273:10)
|
|
||||||
at readBlockMapping (file:///E:/wails/docs/node_modules/js-yaml/dist/js-yaml.mjs:2272:7)
|
|
||||||
at readDocument (file:///E:/wails/docs/node_modules/js-yaml/dist/js-yaml.mjs:2715:3)
|
|
||||||
at load$1 (file:///E:/wails/docs/node_modules/js-yaml/dist/js-yaml.mjs:2804:19)
|
|
||||||
at safeParseFrontmatter (file:///E:/wails/docs/node_modules/@astrojs/mdx/dist/utils.js:33:12)
|
|
||||||
error: script "astro" exited with code 1
|
|
||||||
1560
docs/bun.lock
|
|
@ -1,33 +0,0 @@
|
||||||
$dirs = @(
|
|
||||||
"src/content/docs/quick-start",
|
|
||||||
"src/content/docs/concepts",
|
|
||||||
"src/content/docs/features/windows",
|
|
||||||
"src/content/docs/features/menus",
|
|
||||||
"src/content/docs/features/bindings",
|
|
||||||
"src/content/docs/features/events",
|
|
||||||
"src/content/docs/features/dialogs",
|
|
||||||
"src/content/docs/features/platform",
|
|
||||||
"src/content/docs/guides/dev",
|
|
||||||
"src/content/docs/guides/build",
|
|
||||||
"src/content/docs/guides/distribution",
|
|
||||||
"src/content/docs/guides/patterns",
|
|
||||||
"src/content/docs/guides/advanced",
|
|
||||||
"src/content/docs/reference/application",
|
|
||||||
"src/content/docs/reference/window",
|
|
||||||
"src/content/docs/reference/menu",
|
|
||||||
"src/content/docs/reference/events",
|
|
||||||
"src/content/docs/reference/dialogs",
|
|
||||||
"src/content/docs/reference/runtime",
|
|
||||||
"src/content/docs/reference/cli",
|
|
||||||
"src/content/docs/contributing/architecture",
|
|
||||||
"src/content/docs/contributing/codebase",
|
|
||||||
"src/content/docs/contributing/workflows",
|
|
||||||
"src/content/docs/migration"
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($dir in $dirs) {
|
|
||||||
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
||||||
Write-Host "Created: $dir"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "`nAll directories created successfully!"
|
|
||||||
9344
docs/package-lock.json
generated
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"name": "wails-docs",
|
|
||||||
"type": "module",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "astro dev",
|
|
||||||
"start": "astro dev",
|
|
||||||
"build": "astro check && astro build",
|
|
||||||
"preview": "astro preview",
|
|
||||||
"astro": "astro"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@astrojs/check": "^0.9.4",
|
|
||||||
"@astrojs/react": "^4.1.0",
|
|
||||||
"@astrojs/starlight": "^0.30.0",
|
|
||||||
"@types/react": "^19.0.1",
|
|
||||||
"@types/react-dom": "^19.0.2",
|
|
||||||
"astro": "^5.0.0",
|
|
||||||
"astro-d2": "^0.5.0",
|
|
||||||
"framer-motion": "^11.14.4",
|
|
||||||
"motion": "^11.14.4",
|
|
||||||
"react": "^19.0.0",
|
|
||||||
"react-dom": "^19.0.0",
|
|
||||||
"sharp": "^0.33.5",
|
|
||||||
"starlight-blog": "^0.15.0",
|
|
||||||
"starlight-image-zoom": "^0.9.0",
|
|
||||||
"starlight-links-validator": "^0.13.4",
|
|
||||||
"starlight-showcases": "^0.2.0",
|
|
||||||
"typescript": "^5.7.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1" viewBox="0 0 550 310" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><g><path d="M0.883,-0.081L0.121,0.081L0.256,-0.063L0.883,-0.081Z" transform="matrix(-166.599,4.57132,4.57132,166.599,147.403,167.648)" style="fill:url(#_Linear1);fill-rule:nonzero"/></g><g><path d="M0.878,-0.285L-0.073,0.71L-1.186,0.542L0.015,0.207L-0.846,0.077L0.355,-0.258L-0.505,-0.388L0.649,-0.71L0.878,-0.285Z" transform="matrix(-106.443,-16.0669,-16.0669,106.443,428.19,188.033)" style="fill:url(#_Linear2);fill-rule:nonzero"/></g><g><path d="M0.44,-0.04L0.265,-0.056L0.177,0.437L-0.311,-0.255L0.262,-0.437L0.568,-0.437L0.44,-0.04Z" transform="matrix(-114.484,-162.408,-162.408,114.484,333.291,285.804)" style="fill:url(#_Linear3);fill-rule:nonzero"/></g><g><path d="M0.622,-0.115L0.761,-0.115L0.806,-0.013L0.826,0.182L0.622,-0.115Z" transform="matrix(238.126,298.893,298.893,-238.126,113.516,-150.536)" style="fill:url(#_Linear4);fill-rule:nonzero"/></g><g><path d="M0.467,0.005L0.49,0.062L0.271,-0.062L0.467,0.005Z" transform="matrix(-369.529,-97.4118,-97.4118,369.529,582.38,94.027)" style="fill:url(#_Linear5);fill-rule:nonzero"/></g><g><path d="M0.2,0.001L0.219,-0.018L0.614,0.012L0.519,0.089L0.282,0.068L0.2,0.135L0.463,0.194L0.374,0.266L0.138,0.186L0.047,0.033L-0.131,-0.266L0.2,0.001Z" transform="matrix(-496.156,-53.9751,-53.9751,496.156,367.888,125.085)" style="fill:url(#_Linear6);fill-rule:nonzero"/></g><g><path d="M269.095,104.527L287.764,111.419L263.632,106.75L269.095,104.527Z" transform="matrix(0.436503,-1.22916,4.88651,1.73532,-368.043,253.619)" style="fill:#fff"/></g><defs><linearGradient id="_Linear1" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,-3.46945e-18,3.46945e-18,1,0,-3.05761e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear2" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,0,0,1,0,-2.75467e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear3" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,-1.11022e-16,1.11022e-16,1,0,-2.61861e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear4" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(-0.801899,-0.59746,0.59746,-0.801899,1.3495,0.447457)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear5" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,-2.77556e-17,2.77556e-17,1,0,-1.92826e-06)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient><linearGradient id="_Linear6" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(1,0,0,1,0,9.68429e-07)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e33232;stop-opacity:1"/><stop offset="1" style="stop-color:#6b000d;stop-opacity:1"/></linearGradient></defs></svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 498 KiB |
|
Before Width: | Height: | Size: 8 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 503 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 235 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 177 KiB |
|
Before Width: | Height: | Size: 269 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 24 KiB |