├── .github
└── workflows
│ ├── build.yml
│ └── list-apple-teams.yml
├── .gitignore
├── LICENSE.md
├── Project
├── AndroidResources
│ └── res
│ │ ├── mipmap-anydpi-v26
│ │ └── ic_launcher.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_foreground.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_foreground.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_foreground.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_foreground.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_foreground.png
│ │ └── values
│ │ └── values.xml
├── Icon.png
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-1024.png
│ │ ├── Icon-120.png
│ │ ├── Icon-152.png
│ │ ├── Icon-167.png
│ │ ├── Icon-180.png
│ │ ├── Icon-40.png
│ │ ├── Icon-58.png
│ │ ├── Icon-76.png
│ │ ├── Icon-80.png
│ │ └── Icon-87.png
│ ├── AppIconTV.brandassets
│ │ ├── App Icon - Large.imagestack
│ │ │ ├── Back.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Icon-tvOS-Large-Background.png
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── Front.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Icon-tvOS-Large-LogoA.png
│ │ │ │ └── Contents.json
│ │ │ └── Middle.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── Icon-tvOS-Large-LogoB.png
│ │ │ │ └── Contents.json
│ │ ├── App Icon - Small.imagestack
│ │ │ ├── Back.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── Icon-tvOS-Small-Bg.png
│ │ │ │ │ └── Icon-tvOS-Small-Bg@2x.png
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── Front.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ ├── Icon-tvOS-Small-LogoA.png
│ │ │ │ │ └── Icon-tvOS-Small-LogoA@2x.png
│ │ │ │ └── Contents.json
│ │ │ └── Middle.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Icon-tvOS-Small-LogoB.png
│ │ │ │ └── Icon-tvOS-Small-LogoB@2x.png
│ │ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Top Shelf Image Wide.imageset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-tvOS-TopShelfWide.png
│ │ │ └── Icon-tvOS-TopShelfWide@2x.png
│ │ └── Top Shelf Image.imageset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-tvOS-TopShelf.png
│ │ │ └── Icon-tvOS-TopShelf@2x.png
│ ├── Contents.json
│ └── LaunchImageTV.launchimage
│ │ ├── Contents.json
│ │ ├── Icon-tvOS-Launch.png
│ │ └── Icon-tvOS-Launch@2x.png
├── LaunchScreen.storyboardc
│ ├── 01J-lp-oVM-view-Ze5-6b-2t3.nib
│ ├── Info.plist
│ ├── UIViewController-01J-lp-oVM.nib
│ └── designable.storyboard
├── ReadMe.txt
├── build.settings
├── config.lua
├── main.lua
└── sampleUI
│ ├── back-darkgrey.png
│ ├── back-darkgrey@2x.png
│ ├── back-darkgrey@4x.png
│ ├── infobutton.png
│ ├── infobutton@2x.png
│ ├── infobutton@4x.png
│ └── sampleUI.lua
├── README.md
├── README.ru.md
└── Util
├── build.sh
├── deliver.sh
├── distribution.mobileprovision
├── distribution.p12
└── recipe.lua
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build and Deliver
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | AppVersion:
7 | description: 'Version Name'
8 | required: true
9 | default: '1.0'
10 | Solar2DBuild:
11 | description: 'Solar2D Build Number'
12 | required: true
13 | default: '2024.3706'
14 | Xcode:
15 | description: 'Xcode Version'
16 | required: true
17 | default: '15.2'
18 |
19 |
20 | env:
21 | DEVELOPER_DIR: /Applications/Xcode_${{ github.event.inputs.Xcode }}.app/Contents/Developer # this forces Xcode version
22 | APP_VERSION: ${{ github.event.inputs.AppVersion }}
23 | S2D_BUILD_NAME: ${{ github.event.inputs.Solar2DBuild }}
24 |
25 |
26 | jobs:
27 | build:
28 | runs-on: macos-14
29 | steps:
30 | - uses: actions/checkout@v4
31 | - name: Build
32 | run: bash Util/build.sh
33 | env:
34 | CERT_PASSWORD: ${{ secrets.CertPassword }}
35 | APPLE_USERNAME: ${{ secrets.AppleUser }}
36 | APPLE_PASSWORD: ${{ secrets.ApplePassword }}
37 | APPLE_TEAM_ID: ${{ secrets.AppleTeamId }}
38 | - uses: actions/upload-artifact@v4
39 | with:
40 | name: IPA
41 | path: Util/*.ipa
42 | - name: Deliver
43 | run: bash Util/deliver.sh
44 | env:
45 | APPLE_USERNAME: ${{ secrets.AppleUser }}
46 | APPLE_PASSWORD: ${{ secrets.ApplePassword }}
47 | APPLE_TEAM_ID: ${{ secrets.AppleTeamId }}
48 |
--------------------------------------------------------------------------------
/.github/workflows/list-apple-teams.yml:
--------------------------------------------------------------------------------
1 | name: List Apple Teams
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | list:
8 | runs-on: macos-12
9 | steps:
10 | - name: List Teams
11 | run: |
12 | set -e
13 | function err {
14 | echo "$1" 1>&2
15 | return 1
16 | }
17 | [ "${APPLE_USERNAME}" ] || err "AppleUser secret is required"
18 | [ "${APPLE_PASSWORD}" ] || err "ApplePassword secret is required"
19 | xcrun altool --list-providers -u "${APPLE_USERNAME}" -p "${APPLE_PASSWORD}"
20 | env:
21 | APPLE_USERNAME: ${{ secrets.AppleUser }}
22 | APPLE_PASSWORD: ${{ secrets.ApplePassword }}
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /Util/S2D/
2 | *.dmg
3 | *.ipa
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Solar2D.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/AndroidResources/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Project/AndroidResources/res/values/values.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #15073e
4 |
5 |
--------------------------------------------------------------------------------
/Project/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Icon.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-40.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "idiom" : "iphone",
11 | "size" : "20x20",
12 | "scale" : "3x"
13 | },
14 | {
15 | "size" : "29x29",
16 | "idiom" : "iphone",
17 | "filename" : "Icon-58.png",
18 | "scale" : "2x"
19 | },
20 | {
21 | "size" : "29x29",
22 | "idiom" : "iphone",
23 | "filename" : "Icon-87.png",
24 | "scale" : "3x"
25 | },
26 | {
27 | "size" : "40x40",
28 | "idiom" : "iphone",
29 | "filename" : "Icon-80.png",
30 | "scale" : "2x"
31 | },
32 | {
33 | "idiom" : "iphone",
34 | "size" : "40x40",
35 | "scale" : "3x"
36 | },
37 | {
38 | "size" : "60x60",
39 | "idiom" : "iphone",
40 | "filename" : "Icon-120.png",
41 | "scale" : "2x"
42 | },
43 | {
44 | "size" : "60x60",
45 | "idiom" : "iphone",
46 | "filename" : "Icon-180.png",
47 | "scale" : "3x"
48 | },
49 | {
50 | "idiom" : "ipad",
51 | "size" : "20x20",
52 | "scale" : "1x"
53 | },
54 | {
55 | "idiom" : "ipad",
56 | "size" : "20x20",
57 | "scale" : "2x"
58 | },
59 | {
60 | "idiom" : "ipad",
61 | "size" : "29x29",
62 | "scale" : "1x"
63 | },
64 | {
65 | "idiom" : "ipad",
66 | "size" : "29x29",
67 | "scale" : "2x"
68 | },
69 | {
70 | "idiom" : "ipad",
71 | "size" : "40x40",
72 | "scale" : "1x"
73 | },
74 | {
75 | "idiom" : "ipad",
76 | "size" : "40x40",
77 | "scale" : "2x"
78 | },
79 | {
80 | "size" : "76x76",
81 | "idiom" : "ipad",
82 | "filename" : "Icon-76.png",
83 | "scale" : "1x"
84 | },
85 | {
86 | "size" : "76x76",
87 | "idiom" : "ipad",
88 | "filename" : "Icon-152.png",
89 | "scale" : "2x"
90 | },
91 | {
92 | "size" : "83.5x83.5",
93 | "idiom" : "ipad",
94 | "filename" : "Icon-167.png",
95 | "scale" : "2x"
96 | },
97 | {
98 | "size" : "1024x1024",
99 | "idiom" : "ios-marketing",
100 | "filename" : "Icon-1024.png",
101 | "scale" : "1x"
102 | }
103 | ],
104 | "info" : {
105 | "version" : 1,
106 | "author" : "xcode"
107 | }
108 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-1024.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-120.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-152.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-167.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-180.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-58.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-80.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIcon.appiconset/Icon-87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIcon.appiconset/Icon-87.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-Large-Background.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Icon-tvOS-Large-Background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Icon-tvOS-Large-Background.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-Large-LogoA.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Icon-tvOS-Large-LogoA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Icon-tvOS-Large-LogoA.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-Large-LogoB.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Icon-tvOS-Large-LogoB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Icon-tvOS-Large-LogoB.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-Small-Bg.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "filename" : "Icon-tvOS-Small-Bg@2x.png",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Icon-tvOS-Small-Bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Icon-tvOS-Small-Bg.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Icon-tvOS-Small-Bg@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Icon-tvOS-Small-Bg@2x.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-Small-LogoA.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "filename" : "Icon-tvOS-Small-LogoA@2x.png",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoA.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoA@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoA@2x.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-Small-LogoB.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "filename" : "Icon-tvOS-Small-LogoB@2x.png",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoB.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoB@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Icon-tvOS-Small-LogoB@2x.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "size" : "1280x768",
5 | "idiom" : "tv",
6 | "filename" : "App Icon - Large.imagestack",
7 | "role" : "primary-app-icon"
8 | },
9 | {
10 | "size" : "400x240",
11 | "idiom" : "tv",
12 | "filename" : "App Icon - Small.imagestack",
13 | "role" : "primary-app-icon"
14 | },
15 | {
16 | "size" : "2320x720",
17 | "idiom" : "tv",
18 | "filename" : "Top Shelf Image Wide.imageset",
19 | "role" : "top-shelf-image-wide"
20 | },
21 | {
22 | "size" : "1920x720",
23 | "idiom" : "tv",
24 | "filename" : "Top Shelf Image.imageset",
25 | "role" : "top-shelf-image"
26 | }
27 | ],
28 | "info" : {
29 | "version" : 1,
30 | "author" : "xcode"
31 | }
32 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image Wide.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-TopShelfWide.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "filename" : "Icon-tvOS-TopShelfWide@2x.png",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image Wide.imageset/Icon-tvOS-TopShelfWide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image Wide.imageset/Icon-tvOS-TopShelfWide.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image Wide.imageset/Icon-tvOS-TopShelfWide@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image Wide.imageset/Icon-tvOS-TopShelfWide@2x.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "filename" : "Icon-tvOS-TopShelf.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "tv",
10 | "filename" : "Icon-tvOS-TopShelf@2x.png",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image.imageset/Icon-tvOS-TopShelf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image.imageset/Icon-tvOS-TopShelf.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image.imageset/Icon-tvOS-TopShelf@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/AppIconTV.brandassets/Top Shelf Image.imageset/Icon-tvOS-TopShelf@2x.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/LaunchImageTV.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "landscape",
5 | "idiom" : "tv",
6 | "filename" : "Icon-tvOS-Launch@2x.png",
7 | "extent" : "full-screen",
8 | "minimum-system-version" : "11.0",
9 | "scale" : "2x"
10 | },
11 | {
12 | "orientation" : "landscape",
13 | "idiom" : "tv",
14 | "filename" : "Icon-tvOS-Launch.png",
15 | "extent" : "full-screen",
16 | "minimum-system-version" : "9.0",
17 | "scale" : "1x"
18 | }
19 | ],
20 | "info" : {
21 | "version" : 1,
22 | "author" : "xcode"
23 | }
24 | }
--------------------------------------------------------------------------------
/Project/Images.xcassets/LaunchImageTV.launchimage/Icon-tvOS-Launch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/LaunchImageTV.launchimage/Icon-tvOS-Launch.png
--------------------------------------------------------------------------------
/Project/Images.xcassets/LaunchImageTV.launchimage/Icon-tvOS-Launch@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/Images.xcassets/LaunchImageTV.launchimage/Icon-tvOS-Launch@2x.png
--------------------------------------------------------------------------------
/Project/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
--------------------------------------------------------------------------------
/Project/LaunchScreen.storyboardc/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/LaunchScreen.storyboardc/Info.plist
--------------------------------------------------------------------------------
/Project/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
--------------------------------------------------------------------------------
/Project/LaunchScreen.storyboardc/designable.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Project/ReadMe.txt:
--------------------------------------------------------------------------------
1 | This sample project demonstrates polygonal body constructors and tilt-based gravity effects for Android, iOS, and tvOS.
2 |
3 | Turn the device around (orientation) to see how the objects tumble around as if contained in a tumbler.
4 |
5 | RELATED GUIDES
6 | [Basic Interactivity and Event Detection](https://docs.coronalabs.com/guide/events/detectEvents/index.html)
7 | [Physics Bodies](https://docs.coronalabs.com/guide/physics/physicsBodies/index.html)
8 |
--------------------------------------------------------------------------------
/Project/build.settings:
--------------------------------------------------------------------------------
1 | --
2 | -- For more information on build.settings, see the Project Build Settings guide at:
3 | -- https://docs.coronalabs.com/guide/distribution/buildSettings
4 | --
5 |
6 | settings =
7 | {
8 | orientation =
9 | {
10 | -- Supported values for orientation:
11 | -- portrait, portraitUpsideDown, landscapeLeft, landscapeRight
12 | default = "landscapeRight",
13 | supported = { "landscapeRight" }
14 | },
15 |
16 | iphone =
17 | {
18 | xcassets = "Images.xcassets",
19 | plist =
20 | {
21 | UILaunchStoryboardName = "LaunchScreen",
22 | ITSAppUsesNonExemptEncryption = false, -- This sample doesn't use custom encryption
23 | },
24 | },
25 |
26 | tvos =
27 | {
28 | xcassets = "Images.xcassets",
29 | plist =
30 | {
31 | ITSAppUsesNonExemptEncryption = false, -- This sample doesn't use custom encryption
32 | },
33 | },
34 |
35 | window =
36 | {
37 | titleText =
38 | {
39 | default = "Shape Tumbler",
40 | },
41 | },
42 | }
43 |
--------------------------------------------------------------------------------
/Project/config.lua:
--------------------------------------------------------------------------------
1 |
2 | application =
3 | {
4 | content =
5 | {
6 | fps = 60,
7 | width = 320,
8 | height = 480,
9 | scale = "letterbox",
10 | xAlign = "center",
11 | yAlign = "center",
12 |
13 | imageSuffix =
14 | {
15 | ["@2x"] = 2.000,
16 | ["@4x"] = 4.000
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Project/main.lua:
--------------------------------------------------------------------------------
1 |
2 | -- Abstract: Shape Tumbler
3 | -- Version: 1.1
4 | -- Sample code is MIT licensed; see https://solar2d.com/LICENSE.txt
5 | ---------------------------------------------------------------------------------------
6 |
7 | display.setStatusBar( display.HiddenStatusBar )
8 | math.randomseed( os.time() )
9 |
10 | ------------------------------
11 | -- RENDER THE SAMPLE CODE UI
12 | ------------------------------
13 | local sampleUI = require( "sampleUI.sampleUI" )
14 | sampleUI:newUI( { theme="darkgrey", title="Shape Tumbler", showBuildNum=false } )
15 |
16 | ------------------------------
17 | -- CONFIGURE STAGE
18 | ------------------------------
19 | display.getCurrentStage():insert( sampleUI.backGroup )
20 | local worldGroup = display.newGroup()
21 | display.getCurrentStage():insert( sampleUI.frontGroup )
22 |
23 | ----------------------
24 | -- BEGIN SAMPLE CODE
25 | ----------------------
26 |
27 | -- Set up physics engine
28 | local physics = require( "physics" )
29 | physics.start( true ) -- Pass "true" as first parameter to prevent bodies from sleeping
30 | physics.setGravity( 0, 9.8 ) -- Initial gravity points downwards
31 | physics.setScale( 60 )
32 |
33 | -- Declare initial variables
34 | local letterboxWidth = math.abs(display.screenOriginX)
35 | local letterboxHeight = math.abs(display.screenOriginY)
36 |
37 | -- Create "walls" around screen
38 | local wallL = display.newRect( worldGroup, 0-letterboxWidth, display.contentCenterY, 20, display.actualContentHeight )
39 | wallL.anchorX = 1
40 | physics.addBody( wallL, "static", { bounce=1, friction=0.1 } )
41 |
42 | local wallR = display.newRect( worldGroup, 480+letterboxWidth, display.contentCenterY, 20, display.actualContentHeight )
43 | wallR.anchorX = 0
44 | physics.addBody( wallR, "static", { bounce=1, friction=0.1 } )
45 |
46 | local wallT = display.newRect( worldGroup, display.contentCenterX, 0-letterboxHeight, display.actualContentWidth, 20 )
47 | wallT.anchorY = 1
48 | physics.addBody( wallT, "static", { bounce=0, friction=0 } )
49 |
50 | local wallB = display.newRect( worldGroup, display.contentCenterX, 320+letterboxHeight, display.actualContentWidth, 20 )
51 | wallB.anchorY = 0
52 | physics.addBody( wallB, "static", { bounce=0.4, friction=0.6 } )
53 |
54 | -- Create triangle function
55 | local function createTriangle()
56 | local triangleShape = { 0,-32, 37,32, -37,32 }
57 | local triangle = display.newPolygon( worldGroup, 0, 0, triangleShape )
58 | physics.addBody( triangle, { friction=0.5, bounce=0.3, shape=triangleShape } )
59 | return triangle
60 | end
61 |
62 | -- Create hexagon function
63 | local function createHexagon()
64 | local hexagonShape = { 0,-38, 33,-19, 33,19, 0,38, -33,19, -33,-19 }
65 | local hexagon = display.newPolygon( worldGroup, 0, 0, hexagonShape )
66 | physics.addBody( hexagon, { friction=0.5, bounce=0.4, shape=hexagonShape } )
67 | return hexagon
68 | end
69 |
70 | -- Create small box function
71 | local function createBoxSmall()
72 | local boxSmall = display.newRect( worldGroup, 0, 0, 50, 50 )
73 | physics.addBody( boxSmall, { friction=0.5, bounce=0.4 } )
74 | return boxSmall
75 | end
76 |
77 | -- Create large box function
78 | local function createBoxLarge()
79 | local boxLarge = display.newRect( worldGroup, 0, 0, 75, 75 )
80 | physics.addBody( boxLarge, { friction=0.5, bounce=0.4 } )
81 | return boxLarge
82 | end
83 |
84 | -- Create cell function
85 | local function createCell()
86 | local cellShape = { -30,-10, -25,-15, 25,-15, 30,-10, 30,10, 25,15, -25,15, -30,10 }
87 | local cell = display.newPolygon( worldGroup, 0, 0, cellShape )
88 | physics.addBody( cell, { friction=0.5, bounce=0.4, shape=cellShape } )
89 | return cell
90 | end
91 |
92 | -- Create ball function
93 | local function createBall()
94 | local ball = display.newCircle( worldGroup, 0, 0, 30 )
95 | physics.addBody( ball, { friction=0.5, bounce=0.7, radius=30 } )
96 | return ball
97 | end
98 |
99 | -- Create random object function
100 | local function createRandomObject()
101 | local r = math.random( 1, 6 )
102 | local object
103 |
104 | if ( r == 1 ) then
105 | object = createTriangle()
106 | elseif ( r == 2 ) then
107 | object = createHexagon()
108 | elseif ( r == 3 ) then
109 | object = createBoxSmall()
110 | elseif ( r == 4 ) then
111 | object = createBoxLarge()
112 | elseif ( r == 5 ) then
113 | object = createCell()
114 | elseif ( r == 6 ) then
115 | object = createBall()
116 | end
117 |
118 | return object
119 | end
120 |
121 | -- Fill the content area with some objects
122 | local function spawnObjects()
123 | local xIndex = 0
124 | local yPos = 100
125 |
126 | for i = 1, 8 do
127 | local object = createRandomObject()
128 | object:setFillColor( ( math.random( 4, 8 ) / 10 ), ( math.random( 0, 2 ) / 10 ), ( math.random( 4, 10 ) / 10 ) )
129 |
130 | if ( xIndex == 4 ) then
131 | xIndex = 0
132 | yPos = 220
133 | end
134 |
135 | object.y = yPos + ( math.random( -1, 1 ) * 15 )
136 | object.x = ( xIndex * 120 ) + 60 + ( math.random( -1, 1 ) * 15 )
137 | xIndex = xIndex + 1
138 | end
139 | end
140 |
141 | -- Function to adjust gravity based on accelerometer response
142 | local function onTilt( event )
143 | -- Gravity is in portrait orientation on Android, iOS, and Windows Phone
144 | -- On tvOS, gravity is in the orientation of the device attached to the event
145 | if ( event.device ) then
146 | physics.setGravity( ( 9.8 * event.xGravity ), ( -9.8 * event.yGravity ) )
147 | else
148 | physics.setGravity( ( -9.8 * event.yGravity ), ( -9.8 * event.xGravity ) )
149 | end
150 | end
151 |
152 | -- Detect if accelerometer is supported
153 | if ( system.hasEventSource( "accelerometer" ) ) then
154 | -- Set accelerometer to maximum responsiveness
155 | system.setAccelerometerInterval( 100 )
156 | -- Start listening for accelerometer events
157 | Runtime:addEventListener( "accelerometer", onTilt )
158 | -- Spawn some objects
159 | spawnObjects()
160 | else
161 | local shade = display.newRect( worldGroup, display.contentCenterX, display.contentHeight-display.screenOriginY-18, display.actualContentWidth, 36 )
162 | shade:setFillColor( 0, 0, 0, 0.7 )
163 | local msg = display.newText( worldGroup, "Accelerometer not supported on this platform", display.contentCenterX, shade.y, appFont, 13 )
164 | msg:setFillColor( 1, 0, 0.2 )
165 | end
166 |
--------------------------------------------------------------------------------
/Project/sampleUI/back-darkgrey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/sampleUI/back-darkgrey.png
--------------------------------------------------------------------------------
/Project/sampleUI/back-darkgrey@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/sampleUI/back-darkgrey@2x.png
--------------------------------------------------------------------------------
/Project/sampleUI/back-darkgrey@4x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/sampleUI/back-darkgrey@4x.png
--------------------------------------------------------------------------------
/Project/sampleUI/infobutton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/sampleUI/infobutton.png
--------------------------------------------------------------------------------
/Project/sampleUI/infobutton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/sampleUI/infobutton@2x.png
--------------------------------------------------------------------------------
/Project/sampleUI/infobutton@4x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Project/sampleUI/infobutton@4x.png
--------------------------------------------------------------------------------
/Project/sampleUI/sampleUI.lua:
--------------------------------------------------------------------------------
1 |
2 | -- Version: 1.3
3 | ---------------------------------------------------------------------------------------
4 |
5 | local widget = require( "widget" )
6 |
7 | local M = {}
8 |
9 | local infoShowing = false
10 |
11 | function M:newUI( options )
12 |
13 | local backGroup = display.newGroup()
14 | local frontGroup = display.newGroup()
15 | local textGroupContainer = display.newContainer( 288, 240 ) ; frontGroup:insert( textGroupContainer )
16 | local barContainer = display.newContainer( display.actualContentWidth, 30 )
17 | frontGroup:insert( barContainer )
18 | barContainer.anchorX = 0
19 | barContainer.anchorY = 0
20 | barContainer.anchorChildren = false
21 | barContainer.x = display.screenOriginX
22 | barContainer.y = display.screenOriginY
23 |
24 | local scrollBounds
25 | local infoBoxState = "canOpen"
26 | local transComplete
27 | local themeName = options.theme or "darkgrey"
28 | local sampleCodeTitle = options.title or "Sample"
29 | local buildNum
30 |
31 | -- Read from the ReadMe.txt file
32 | local readMeText = ""
33 | local readMeFilePath = system.pathForFile( "ReadMe.txt", system.ResourceDirectory )
34 | if readMeFilePath then
35 | local readMeFile = io.open( readMeFilePath )
36 | local rt = readMeFile:read( "*a" )
37 | if string.len( rt ) > 0 then readMeText = rt end
38 | io.close( readMeFile ) ; readMeFile = nil ; rt = nil
39 | end
40 |
41 | -- Create background image by theme value
42 | local background = display.newImageRect( backGroup, "sampleUI/back-" .. themeName .. ".png", 360, 640 )
43 | background.x, background.y = display.contentCenterX, display.contentCenterY
44 |
45 | local topBarBack = display.newRect( barContainer, 0, 0, barContainer.contentWidth, barContainer.contentHeight )
46 | topBarBack.anchorX = 0
47 | topBarBack.anchorY = 0
48 | topBarBack:setFillColor( 0,0,0,0.2 )
49 | local topBarOver = display.newRect( barContainer, 0, 0, barContainer.contentWidth, barContainer.contentHeight - 2 )
50 | topBarOver.anchorX = 0
51 | topBarOver.anchorY = 0
52 | topBarOver:setFillColor( { type="gradient", color1={ 0.144 }, color2={ 0.158 } } )
53 | textGroupContainer:toBack()
54 |
55 | -- Check system for font selection
56 | local useFont
57 | if ( "android" == system.getInfo( "platform" ) or "win32" == system.getInfo( "platform" ) ) then
58 | useFont = native.systemFont
59 | else
60 | useFont = "HelveticaNeue-Light"
61 | end
62 | self.appFont = useFont
63 |
64 | -- Place Solar2D title
65 | local siteLink = display.newText( barContainer, "Solar2D", 8, topBarOver.contentHeight / 2, useFont, 14 )
66 | siteLink.anchorX = 0
67 | siteLink:setFillColor( 0.961, 0.494, 0.125 )
68 | if system.canOpenURL( "https://www.solar2d.com" ) then
69 | siteLink:addEventListener( "touch",
70 | function( event )
71 | if event.phase == "began" then
72 | system.openURL( "https://www.solar2d.com" )
73 | end
74 | return true
75 | end )
76 | end
77 |
78 | -- Place sample app title
79 | local title = display.newText( barContainer, sampleCodeTitle, barContainer.contentWidth - 28, topBarOver.contentHeight / 2, useFont, 14 )
80 | title.anchorX = 1
81 |
82 | if options.showBuildNum == true then
83 | buildNum = display.newText( frontGroup, "Build " .. tonumber( system.getInfo( "build" ):sub(-4) ), 0, 0, useFont, 10 )
84 | buildNum.anchorX = 1
85 | buildNum.anchorY = 1
86 | if ( themeName == "darkgrey" or themeName == "mediumgrey" ) then buildNum:setFillColor( 0.8 ) else buildNum:setFillColor( 0.2 ) end
87 | end
88 |
89 | -- Create shade rectangle
90 | local screenShade = display.newRect( frontGroup, 0, 0, display.actualContentWidth, display.actualContentHeight )
91 | screenShade:setFillColor( 0,0,0 ) ; screenShade.alpha = 0
92 | screenShade.x, screenShade.y = display.contentCenterX, display.contentCenterY
93 | screenShade.isHitTestable = false ; screenShade:toBack()
94 |
95 | -- Create info button (initially invisible)
96 | local infoButton = display.newImageRect( barContainer, "sampleUI/infobutton.png", 25, 25 )
97 | infoButton.anchorX = 1
98 | infoButton.x = barContainer.contentWidth - 3
99 | infoButton.y = topBarOver.contentHeight / 2
100 | infoButton.isVisible = false
101 | infoButton.id = "infoButton"
102 |
103 | -- Create table for initial object positions
104 | local objPos = { infoBoxOffY=0, infoBoxDestY=0 }
105 |
106 | -- Resize change handler
107 | local function onResize( event )
108 |
109 | if display.contentHeight >= display.contentWidth then
110 | background.x, background.y, background.rotation = display.contentCenterX, display.contentCenterY, 0
111 | else
112 | background.x, background.y, background.rotation = display.contentCenterX, display.contentCenterY, 90
113 | end
114 |
115 | barContainer.x = display.screenOriginX
116 | barContainer.y = display.screenOriginY
117 | barContainer.width = display.actualContentWidth
118 | topBarBack.width = barContainer.width
119 | topBarOver.width = barContainer.width
120 | title.x = barContainer.contentWidth - 28
121 | infoButton.x = barContainer.contentWidth - 3
122 | screenShade.x = display.contentCenterX
123 | screenShade.y = display.contentCenterY
124 | screenShade.width = display.actualContentWidth
125 | screenShade.height = display.actualContentHeight
126 | textGroupContainer.x = display.contentCenterX
127 | if buildNum then
128 | buildNum.x = display.contentCenterX + (display.actualContentWidth / 2) - 7
129 | buildNum.y = display.contentCenterY + (display.actualContentHeight / 2) - 8
130 | end
131 |
132 | -- If info box is opening or already open, snap it entirely on screen
133 | objPos["infoBoxOffY"] = display.screenOriginY - 130
134 | objPos["infoBoxDestY"] = (barContainer.y + barContainer.contentHeight + 130)
135 | if ( infoBoxState == "opening" or infoBoxState == "canClose" ) then
136 | transition.cancel( "infoBox" )
137 | textGroupContainer.xScale, textGroupContainer.yScale = 1,1
138 | textGroupContainer.y = objPos["infoBoxDestY"]
139 | if scrollBounds then
140 | scrollBounds.x, scrollBounds.y = display.contentCenterX, objPos["infoBoxDestY"]
141 | end
142 | transComplete()
143 | -- If info box is closing or already closed, snap it entirely off screen
144 | elseif ( infoBoxState == "closing" or infoBoxState == "canOpen" ) then
145 | transition.cancel( "infoBox" )
146 | textGroupContainer.y = objPos["infoBoxOffY"]
147 | if scrollBounds then
148 | scrollBounds.x, scrollBounds.y = display.contentCenterX, objPos["infoBoxOffY"]
149 | end
150 | transComplete()
151 | end
152 | end
153 | Runtime:addEventListener( "resize", onResize )
154 |
155 | -- If there is ReadMe.txt content, create needed elements
156 | if readMeText ~= "" then
157 |
158 | -- Create the info box scrollview
159 | scrollBounds = widget.newScrollView
160 | {
161 | x = 160,
162 | y = objPos["infoBoxDestY"],
163 | width = 288,
164 | height = 240,
165 | horizontalScrollDisabled = true,
166 | hideBackground = true,
167 | hideScrollBar = true,
168 | topPadding = 0,
169 | bottomPadding = 0
170 | }
171 | scrollBounds:setIsLocked( true, "vertical" )
172 | scrollBounds.x, scrollBounds.y = display.contentCenterX, objPos["infoBoxOffY"]
173 | frontGroup:insert( scrollBounds )
174 |
175 | local infoBoxBack = display.newRect( 0, 0, 288, 240 )
176 | if themeName == "whiteorange" then infoBoxBack:setFillColor( 0.88 )
177 | elseif themeName == "lightgrey" then infoBoxBack:setFillColor( 0.98 )
178 | else infoBoxBack:setFillColor( 0.78 ) end
179 | textGroupContainer:insert( infoBoxBack )
180 |
181 | -- Create the info text group
182 | local infoTextGroup = display.newGroup()
183 | textGroupContainer:insert( infoTextGroup )
184 |
185 | -- Find and then sub out documentation links
186 | local docLinks = {}
187 | for linkTitle, linkURL in string.gmatch( readMeText, "%[([%w\%s\%p\%—]-)%]%(([%w\%p]-)%)" ) do
188 | docLinks[#docLinks+1] = { linkTitle, linkURL }
189 | end
190 | readMeText = string.gsub( readMeText, "%[([%w\%s\%p\%—]-)%]%(([%w\%p]-)%)", "" )
191 |
192 | -- Create the info text and anchoring box
193 | local infoText = display.newText( infoTextGroup, "", 0, 0, 260, 0, useFont, 12 )
194 | infoText:setFillColor( 0 )
195 | local function trimString( s )
196 | return string.match( s, "^()%s*$" ) and "" or string.match( s, "^%s*(.*%S)" )
197 | end
198 | readMeText = trimString( readMeText )
199 | infoText.text = "\n" .. readMeText
200 | infoText.anchorX = 0
201 | infoText.anchorY = 0
202 | infoText.x = -130
203 |
204 | -- Add documentation links as additional clickable text objects below main text
205 | if #docLinks > 0 then
206 | for i = 1,#docLinks do
207 | local docLink = display.newText( docLinks[i][1], 0, 0, useFont, 12 )
208 | docLink:setFillColor( 0.9, 0.1, 0.2 )
209 | docLink.anchorX = 0
210 | docLink.anchorY = 0
211 | docLink.x = -130
212 | docLink.y = infoTextGroup.contentBounds.yMax + 5
213 | infoTextGroup:insert( docLink )
214 | if system.canOpenURL( docLinks[i][2] ) then
215 | docLink:addEventListener( "tap",
216 | function( event )
217 | system.openURL( docLinks[i][2] )
218 | return true
219 | end )
220 | end
221 | end
222 | end
223 | local spacer = display.newRect( infoTextGroup, 0, infoTextGroup.contentBounds.yMax, 10, 15 )
224 | spacer.anchorY = 0 ; spacer.isVisible = false
225 |
226 | local infoTextAnchorBox = display.newRect( infoTextGroup, 0, 0, 288, math.max( 240, infoTextGroup.height ) )
227 | infoTextAnchorBox.anchorY = 0
228 | infoTextAnchorBox.isVisible = false
229 |
230 | -- Set anchor point on info text group
231 | local anc = infoTextGroup.height/120
232 | infoTextGroup.anchorChildren = true
233 | infoTextGroup.anchorY = 1/anc
234 |
235 | -- Initially set info objects to invisible
236 | infoTextGroup.isVisible = false
237 | textGroupContainer.isVisible = false
238 |
239 | transComplete = function()
240 |
241 | if infoBoxState == "opening" then
242 | scrollBounds:insert( infoTextGroup )
243 | infoTextGroup.x = 144 ; infoTextGroup.y = 120
244 | scrollBounds:setIsLocked( false, "vertical" )
245 | scrollBounds.x, scrollBounds.y = display.contentCenterX, objPos["infoBoxDestY"]
246 | infoBoxState = "canClose"
247 | infoShowing = true
248 | if self.onInfoEvent then
249 | self.onInfoEvent( { action="show", phase="did" } )
250 | end
251 | elseif infoBoxState == "closing" then
252 | infoTextGroup.isVisible = false
253 | textGroupContainer.isVisible = false
254 | scrollBounds.x, scrollBounds.y = display.contentCenterX, objPos["infoBoxOffY"]
255 | screenShade.isHitTestable = false
256 | infoBoxState = "canOpen"
257 | infoShowing = false
258 | if self.onInfoEvent then
259 | self.onInfoEvent( { action="hide", phase="did" } )
260 | end
261 | end
262 | end
263 |
264 | local function controlInfoBox( event )
265 | if event.phase == "began" then
266 | if infoBoxState == "canOpen" then
267 | infoBoxState = "opening"
268 | infoShowing = true
269 | if self.onInfoEvent then
270 | self.onInfoEvent( { action="show", phase="will" } )
271 | end
272 | textGroupContainer.x = display.contentCenterX
273 | textGroupContainer.y = objPos["infoBoxOffY"]
274 | textGroupContainer:insert( infoTextGroup )
275 | infoTextGroup.isVisible = true
276 | textGroupContainer.isVisible = true
277 | textGroupContainer.xScale = 0.96 ; textGroupContainer.yScale = 0.96
278 | screenShade.isHitTestable = true
279 | transition.cancel( "infoBox" )
280 | transition.to( screenShade, { time=400, tag="infoBox", alpha=0.75, transition=easing.outQuad } )
281 | transition.to( textGroupContainer, { time=900, tag="infoBox", y=objPos["infoBoxDestY"], transition=easing.outCubic } )
282 | transition.to( textGroupContainer, { time=400, tag="infoBox", delay=750, xScale=1, yScale=1, transition=easing.outQuad, onComplete=transComplete } )
283 |
284 | elseif infoBoxState == "canClose" then
285 | infoBoxState = "closing"
286 | infoShowing = false
287 | if self.onInfoEvent then
288 | self.onInfoEvent( { action="hide", phase="will" } )
289 | end
290 | textGroupContainer:insert( infoTextGroup )
291 | local scrollX, scrollY = scrollBounds:getContentPosition()
292 | infoTextGroup.x = 0 ; infoTextGroup.y = scrollY
293 | scrollBounds:setIsLocked( true, "vertical" )
294 | transition.cancel( "infoBox" )
295 | transition.to( screenShade, { time=400, tag="infoBox", alpha=0, transition=easing.outQuad } )
296 | transition.to( textGroupContainer, { time=400, tag="infoBox", xScale=0.96, yScale=0.96, transition=easing.outQuad } )
297 | transition.to( textGroupContainer, { time=700, tag="infoBox", delay=200, y=objPos["infoBoxOffY"], transition=easing.inCubic, onComplete=transComplete } )
298 | end
299 | end
300 | return true
301 | end
302 |
303 | -- Set info button tap listener
304 | infoButton.isVisible = true
305 | infoButton:addEventListener( "touch", controlInfoBox )
306 | infoButton.listener = controlInfoBox
307 | screenShade:addEventListener( "touch", controlInfoBox )
308 | end
309 |
310 | self.infoButton = infoButton
311 | self.titleBarBottom = barContainer.y + barContainer.contentHeight - 2
312 | backGroup:toBack() ; self.backGroup = backGroup
313 | frontGroup:toFront() ; self.frontGroup = frontGroup
314 | onResize()
315 | end
316 |
317 | function M:isInfoShowing()
318 | return infoShowing
319 | end
320 |
321 | return M
322 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Solar2D → AppStore; macOS not needed
2 |
3 | All you need is a web browser (sic).
4 |
5 | The whole setup should take about 20 minutes. I tried to write as much detail as possible so do not be daunted by the size of this guide, it's just very detailed to make the process easier.
6 |
7 | # Prerequisites
8 |
9 | - Apple account with active [Apple Development Program](http://developer.apple.com/account/) subscription, enrolled as individual or part of a team
10 | - GitHub account
11 | - Google account
12 | - iOS Device with [TestFlight](https://itunes.apple.com/us/app/testflight/id899247664?mt=8) installed for testing
13 |
14 | # General overview
15 |
16 | Here is a quick summary of what we are about to do:
17 |
18 | - Clone the GitHub repository and set it up
19 | - Generate Apple signing credentials and replace placeholders in the repo
20 |
21 | ### 1. Preparing the repo
22 |
23 | 1. Log in to [GitHub](http://github.com/) and press the ➕ button in the top right corner, then select "Import repository". We import the repository instead of forking it so that there's an option to set your repository to private. GitHub forks of public repositories can only be set to public. [⏯](https://i.imgur.com/btddTj3.gif)
24 | 2. Paste the clone url: `https://github.com/solar2d/demo-app-store-automation.git`, pick a name for your repo, (e.g. "Solar2Demo"), and choose a visibility. This particular project does not contain any unencrypted sensitive information but if you plan to extend it, make it private. You can change the visibility later.
25 | 3. In your repo press "⚙ Settings" in the menu bar and pick "Secrets" in the sidebar.
26 | 4. Press "New Repository Secret" and type the following Name and Value pairs into their corresponding fields, clicking "Add secret" for each. [⏯](https://i.imgur.com/yLcgLO6.gif):
27 | 1. Name: `AppleUser`
28 | Value: Your Apple ID user email.
29 | 2. Name: `ApplePassword`
30 | Value: Your Apple ID password. Most likely you have two-factor authentication set up, in which case don't use your actual password; Head to [https://appleid.apple.com/](https://appleid.apple.com/account/manage) and log in, generate an "app-specific password" to use instead.
31 | 5. If your Apple Account is enrolled in the development program as part of a team then you have to specify an `AppleTeamId` secret. This step is otherwise optional. [⏯](https://i.imgur.com/QEvOSJo.gif)
32 | 1. Click on "Actions" in the menu bar and select "List Apple Teams" from the sidebar.
33 | 2. Click on the "Run Workflow" button and confirm by clicking the green button.
34 | 3. Wait a moment for the workflow to appear on the list. After some time, the symbol next to it should become a check mark ✓. Click on "List Apple Teams" near the check mark.
35 | 4. Click "list" in the sidebar and then "List Teams" from the main page area. This should expand an ASCII table.
36 | 5. Locate the desired team short name from the ProviderShortname column and save it as `AppleTeamId` in "Settings" → "Secrets".
37 | 6. This action log can contain some sensitive information, such as your name, accessible by anyone who has access to the repo, so I recommend deleting it. To do that, head back to the Actions tab and in the main page area click on the ⋯ button next to "List Apple Teams". Run and select "Delete workflow run". [⏯](https://i.imgur.com/KSyEKI7.gif)
38 | 6. You may want to edit your app name. For that:
39 | 1. Click on "Code" in the menu bar, and navigate to the "Util" directory.
40 | 2. Click on the "recipe.lua" file and then the ✎ pencil button to edit it.
41 | 3. Change the name in quotes, (currently "Solar2Demo"), in the editor and click the "Commit changes" button to save the file.
42 | 4. I would strongly advise against using anything but basic English letters, or changing anything else in this file, unless you are very certain of what you are doing.
43 |
44 | ### 2. Creating an App ID
45 |
46 | 1. Log in to the Apple Developer Web Portal: [http://developer.apple.com/account/](http://developer.apple.com/account/)
47 | 2. Select "Certificates, Identifiers & Profiles".
48 | 3. In the sidebar, select "Identifiers" and click ➕ to create one.
49 | 4. You want to create an "App ID" of the type "App".
50 | 5. Fill out the form for this app:
51 | 1. Description: Something you will recognize your app by, e.g. `Solar2D Demo App`.
52 | 2. App prefix: I usually select one which says "Team ID", but it doesn't matter much.
53 | 3. Explicit bundle id: e.g. `com.solar2d.solar2demo`. You would have to change the company name to something else since this must be unique.
54 | 4. Default capabilities usually work just fine. You can edit them later.
55 |
56 | ### 3. Creating a signing certificate
57 |
58 | Apple requires applications to be cryptographically signed. To do that you need two things: certificate and provisioning profile. Certificate identify your team and created created per account (same certificate is shared for all your projects). Xcode automates this process, but we will instead use command line utilities provided for free by Google Cloud Shell. [⏯](https://i.imgur.com/6BoMPFi.mp4)
59 |
60 | 1. Follow this: [link](https://shell.cloud.google.com/?hl=en_US&fromcloudshell=true&show=terminal). It should open a new terminal session for you.
61 | 2. Run: `rm -f key.key distribution*; openssl req -newkey rsa:2048 -keyout key.key -out request.csr -nodes -subj "/C=CA/ST=/L=/O=/CN=Solar2D"; cloudshell dl request.csr`
62 | 3. This should prompt downloading a "request.csr" file. Accept it and do not close the terminal, you'll need it again in a minute.
63 | 4. In the [Apple Developer](https://developer.apple.com/account/resources/certificates/list) portal, go to "Certificates" → "IDs & Profiles" → "Certificates".
64 | 5. Hit the ➕ button to start the process of creating a certificate.
65 | 6. Select "Apple Distribution".
66 | 7. Hit "Choose File" and select the "request.csr" file we just downloaded.
67 | 8. Hit "Create" and then "Download" to get the "distribution.cer" certificate file.
68 | 9. Return to the Cloud Shell window and upload the certificate. You can do this by dragging and dropping the "distribution.cer" file to the console or by selecting it via "Upload Files" in the ⋮ (More) menu.
69 | 10. Run: `openssl x509 -legacy -inform DER -in distribution.cer -out distribution.crt && openssl pkcs12 -legacy -export -out distribution.p12 -inkey key.key -in distribution.crt && cloudshell dl distribution.p12 && rm -f key.key request.csr distribution.c*`
70 | 11. When prompted for a password I suggest using a strong [randomly generated password](https://passwordsgenerator.net/?length=22&symbols=0&numbers=1&lowercase=1&uppercase=1&similar=0&ambiguous=0&client=1&autoselect=1).
71 | 12. Save the password in your GitHub repo as `CertPassword` secret, (we added other secrets in the [previous](#secret-create) section). You will also need this password if you decide to use an actual Mac and import the certificate there.
72 | 13. Accept the p12 bundle, containing encrypted signing certificates.
73 | 14. In your GitHub repo, navigate to "Code", then click on the "Util" directory.
74 | 15. Press the "Add file" button and select "Upload files".
75 | 16. Select the downloaded "distribution.p12" file and click the "Commit changes" button.
76 |
77 | In your next project jump right to step 12 and reuse this password and `distribution.p12` file.
78 |
79 | ### 4. Creating a provisioning profile
80 |
81 | Second part involved in signing is a provisioning profile. It identifies your application and its capabilities, so it has to be created for each project individually.
82 |
83 | 1. Head to [Developer Portal](https://developer.apple.com/account/resources/profiles/list), select "Profiles" and click ➕ to create one.
84 | 2. Select "App Store" from the Distribution section.
85 | 3. Select the app ID we created earlier, ("com.solar2d.solar2demo" in my case).
86 | 4. On the next page select the certificate we just created. If you have multiple then pick one with an expiry date exactly one year forward.
87 | 5. On the next page type in the name "distribution" and hit "Generate".
88 | 6. Download the generated profile. If your file is named differently, make sure you rename it to `distribution.mobileprovision` as the build script expects the file to be named as such.
89 | 7. Upload the file to replace a placeholder in the "Util" directory of your GitHub repository, as per the end of the previous section.
90 |
91 | ### 5. Creating an App listing
92 |
93 | We have to create an App listing in order to upload and test the app.
94 |
95 | 1. Head to the App Store Connect website: [https://appstoreconnect.apple.com/](https://appstoreconnect.apple.com/)
96 | 2. Log in, read, and accept any user agreements.
97 | 3. Select "My Apps".
98 | 4. In the menu near "Apps" click the ➕ button and select "New App".
99 | 5. In the popup:
100 | 1. Select iOS as the platform.
101 | 2. Name your app, e.g. "Solar2Demo".
102 | 3. Choose a language, e.g. "English (U.S.)".
103 | 4. Set the Bundle ID we created previously. For me it is "Solar2D Demo App - com.solar2d.solar2demo".
104 | 5. Set an SKU to identify the app for yourself, e.g. "Solar2Demo".
105 | 6. Select "Full Access" and click "Create".
106 | 6. After a few moments you will have the App listing page.
107 | 7. You will need this browser window later to set up testers, so keep it around.
108 |
109 | ## Quick check-up
110 |
111 | When all is done you should have the following:
112 |
113 | - 4 Secrets in GitHub repository settings [⏯](https://i.imgur.com/zB92Fjr.png):
114 | - [x] `AppleUser`
115 | - [x] `ApplePassword`
116 | - [x] `AppleTeamId` *(Optional)*
117 | - [x] `CertPassword`
118 | - 2 files replaced in `Util` directory [⏯](https://i.imgur.com/6b9xcZS.png):
119 | - [x] `Util/distribution.p12`
120 | - [x] `Util/distribution.mobileprovision`
121 |
122 | # Building and uploading the App
123 |
124 | Now for the fun part; Building and uploading the app:
125 |
126 | 1. Navigate to your GitHub repo and select "Actions" from the menu bar.
127 | 2. Select "Build and Deliver" in the workflows sidebar.
128 | 3. Select "Run Workflow", leave all parameters as default and confirm by pressing the green button.
129 |
130 | Done!
131 |
132 | This will start a build. It should succeed in about 3-10 minutes, but it will also upload the built app to the App Store Connect, where it will undergo automatic processing. This may take some time.
133 |
134 | ## Testing your app
135 |
136 | Right after the GitHub action submitted a build, you can set up testing. To do that:
137 |
138 | 1. Head back to the [App Store Connect](https://appstoreconnect.apple.com/) portal, and navigate to your app in "My Apps".
139 | 2. In the top menu select "TestFlight" and then select "App Store Connect Users" in the sidebar under the "Internal Group" section.
140 | 3. Hit ➕ near "Testers" and add at least yourself. This will send you an email.
141 | 4. You have to open this email on your iOS device and click the button in it. The TestFlight app should open and prompt you to accept app testing.
142 |
143 | When the build process is complete, you will get an email and/or push notification with a status update. Use TestFlight on the device to install your app and test it.
144 |
145 | ### Consecutive builds
146 |
147 | With repository and TestFlight already set up, all you have to do is push your code, navigate to "Build and Deliver" in your repo Actions, and run the workflow.
148 |
149 | Then wait for a notification and use TestFlight to get the update.
150 |
151 | # What's next
152 |
153 | Replace the project in the "Project" directory with your creation. Clone the repository to your computer, replace or modify contents, commit changes, and make new builds. When the update is ready, update your app with TestFlight.
154 |
155 | Another option is to modify scripts and integrate them into your existing projects hosted on GitHub. Check out [`.github/workflows/build.yml`](.github/workflows/build.yml) and [`Util/build.sh`](Util/build.sh) for that.
156 |
157 | ## Show some love ❤️ (free)
158 |
159 | If you enjoyed this template and guide, make sure you "Star" these projects on GitHub:
160 |
161 | - Solar2D Game Engine: [https://github.com/coronalabs/corona](https://github.com/coronalabs/corona)
162 | - This template: [https://github.com/solar2d/demo-app-store-automation](https://github.com/solar2d/demo-app-store-automation)
163 |
164 | ## Support the project
165 |
166 | Solar2D is a fully open source game engine which relies on user donations to exist. Consider [supporting](http://github.com/coronalabs/corona?sponsor=1) the project on [Patreon](https://patreon.com/shchvova).
167 |
168 | ### Side notes
169 |
170 | GitHub Actions has [usage limits](https://docs.github.com/en/free-pro-team@latest/github/setting-up-and-managing-billing-and-payments-on-github/about-billing-for-github-actions), especially for private repositories, so make sure you check them out. Today free users get 200 macOS minutes and incur costs of ¢8/minute over that limit. This is more than enough for pushing a build once or twice a week. You don't have to set up billing details until you run out of free minutes, and even then it is hard to beat their pricing.
171 |
172 | ## Questions/Issues
173 |
174 | If you have any questions report them to [https://github.com/solar2d/demo-app-store-automation/issues](https://github.com/solar2d/demo-app-store-automation/issues).
175 |
176 | Enjoy and create some awesome Solar2D games!
177 |
178 | 
179 |
--------------------------------------------------------------------------------
/README.ru.md:
--------------------------------------------------------------------------------
1 | # Solar2D → App Store; macOS не требуется
2 |
3 | Собственно все, что вам нужно, - это браузер.
4 |
5 | Вся настройка займет около 20 минут. Я постарался написать детальные инструкции с пояснениями, поэтому не пугайтесь большого размера руководства. Оно очень подробное, что должно упрощать, а не пугать и усложнять.
6 |
7 | # Требования
8 |
9 | - Активная учетная запись в [Apple Development Program](http://developer.apple.com/account/) для создания и загрузки приложений. Вы можете быть зарегистрироваться как частное лицо или как часть команды с активной подпиской
10 | - Аккаунт GitHub
11 | - Устройство iOS с приложением [TestFlight](https://itunes.apple.com/us/app/testflight/id899247664?mt=8), если вы хотите тестировать свое приложение
12 | - Аккаунт Google
13 |
14 | # Настройка
15 |
16 | Вот краткое изложение того, что мы собираемся сделать, без инструкций, просто для обзора:
17 |
18 | - Клонировать и настроить репозиторий в GitHub
19 | - Создать сертификаты для подписи iOS приложений и загрузить их в репозиторий вместо шаблонов
20 |
21 | ### 1. Подготовка репозитория
22 |
23 | 1. Войдите в [GitHub](http://github.com/) и нажмите кнопку ➕ в правом верхнем углу, выберите «Import repository». Мы импортируем репозиторий вместо форка, потому что так у вас будет возможность сделать вашу копию закрытой. На GitHub форки публичных репозиториев могут быть только публичными [⏯](https://i.imgur.com/btddTj3.gif)
24 | 2. Вставьте адрес `https://github.com/solar2d/demo-app-store-automation.git`, выберите имя для вашего репозитория (например, Solar2Demo) и видимость. Этот конкретный проект не содержит конфиденциальной информации, или конфиденциальная информация зашифрована. Но если вы хотите расширить его и сделать свой проект на его основе, возможно, есть смысл сделать его приватным. Вы можете изменить настройки приватности позже
25 | 3. В репозитории в строке меню нажмите «⚙ Settings» и на боковой панели выберите «Secrets»
26 | 4. Нажмите «New Repository Secret». Введите следующие пары Name и Value в соответствующие поля и нажмите «Add secret» для каждой пары [⏯](https://i.imgur.com/yLcgLO6.gif):
27 | 1. Name: `AppleUser`
28 | Value: ваш адрес электронной почты пользователя Apple ID
29 | 2. Name: `ApplePassword`
30 | Value: ваш пароль Apple ID. Скорее всего, у вас настроена двухфакторная аутентификация. В этом случае не используйте свой настоящий пароль. Перейдите на [https://appleid.apple.com/](https://appleid.apple.com/account/manage) и войдите в систему. Создайте пароль для приложения «app-specific password» и используйте его
31 | 5. Если ваша учетная запись Apple включена в программу разработки как часть команды, а не как индивидуальный разработчик, вам также необходимо указать секрет `AppleTeamId`. Вы также можете указывать его как индивидуальный разработчик, но это необязательно. Чтобы получить его [⏯](https://i.imgur.com/QEvOSJo.gif):
32 | 1. Нажмите «Actions» в строке заголовка GitHub репозитория и выберите «List Apple Teams» на боковой панели
33 | 2. Нажмите кнопку «Run Workflow» и подтвердите, нажав зеленую кнопку
34 | 3. Подождите. Процесс должен появиться в списке посреди окна. Через некоторое время символ рядом с ним должен стать галочкой ✓. Нажмите «List Apple Teams» рядом с галочкой
35 | 4. Щелкните в боковой панели выберите «list», потом в основной области щелкните на «List Teams». Через некоторое время должна появится текстовая таблица
36 | 5. Найдите желаемое короткое название команды (столбец ProviderShortname) и сохраните его как `AppleTeamId` в «Settings» → «Secrets»
37 | 6. После получения идентификатора группы вы можете удалить лог, щелкнув ⋯ в списке процессов во вкладке «Actions» и выбрав «Delete workflow run». Я рекомендую это сделать, поскольку логи доступны всем, кто имеет доступ к репозиторию. Эти логи могут содержать ваше настоящее имя и другую конфиденциальную информацию [⏯](https://i.imgur.com/KSyEKI7.gif)
38 | 6. При желании вы можете изменить название вашего приложения, для этого:
39 | 1. Нажмите «Code» в строке меню и перейдите в каталог «Util»
40 | 2. Щелкните файл recipe.lua и нажмите кнопку с иконкой карандаша ✎, чтобы отредактировать его
41 | 3. Измените имя в кавычках (Solar2Demo) в редакторе и нажмите кнопку «Commit changes»
42 | 4. Я настоятельно не рекомендую использовать что-либо, кроме простой латиницы, или изменять что-либо еще в этом файле, если вы не очень уверены в том что делаете
43 |
44 | ### 2. Создание идентификатора приложения
45 |
46 | 1. Войдите в веб-портал разработчика Apple: [http://developer.apple.com/account/](http://developer.apple.com/account/)
47 | 2. Выберите «Certificates, Identifiers & Profiles»
48 | 3. На боковой панели выберите «Identifiers» и нажмите ➕, чтобы создать его
49 | 4. Вам нужен «App ID» для типа «App»
50 | 5. Заполните форму
51 | 1. Description, описание, по которому вы узнаете свое приложение, например «Solar2D Demo App»
52 | 2. App prefix, я обычно выбираю тот в котором есть «Team ID», но это не имеет большого значения
53 | 3. Explicit bundle id, например «com.solar2d.solar2demo». Вам придется изменить название компании на другое, поскольку идентификаторы приложений должны быть уникальны
54 | 4. Capabilities, возможности по умолчанию обычно подходят, вы можете отредактировать их позже (в таком случае вам придется перевыпустить профиль подготовки (provisioning profile))
55 |
56 | ### 3. Создание сертификата подписи
57 |
58 | Apple требует криптографической подписи приложений. Для подписи нужны две вещи: сертификат и профиль подготовки (provisioning profile). Сертификат идентифицирует команду, и создается один на все ваши приложения. Xcode автоматизирует этот процесс, но мы будем использовать утилиты командной строки, предоставляемые Google Cloud Shell бесплатно [⏯](https://i.imgur.com/6BoMPFi.mp4)
59 |
60 | 1. Перейдите по этой [ссылке](https://shell.cloud.google.com/?hl=en_US&fromcloudshell=true&show=terminal). Она должен открыть для вас новый сеанс терминала
61 | 2. Выполните: `rm -f key.key distribution*; openssl req -newkey rsa:2048 -keyout key.key -out request.csr -nodes -subj "/C=CA/ST=/L=/O=/CN=Solar2D"; cloudshell dl request.csr`
62 | 3. Это должно вызвать загрузку файла «request.csr». Скачайте его и не закрывайте терминал, он еще понадобится
63 | 4. На портале [Apple Developer](https://developer.apple.com/account/resources/certificates/list) перейдите в раздел «Certificates, Identifiers & Profiles», Certificates
64 | 5. Нажмите ➕, чтобы начать процесс создания сертификата
65 | 6. Выберите «Apple Distribution»
66 | 7. Нажмите «Choose File» и выберите только что скачанный «request.csr»
67 | 8. Нажмите «Create» и «Download». Должен скачаться файл «distribution.cer»
68 | 9. Вернитесь в окно Cloud Shell и загрузите сертификат. Вы можете сделать это, перетащив файл «distribution.cer» на консоль или выбрав его через «Upload Files» в меню ⋮ (More)
69 | 10. Запустите: `openssl x509 -legacy -inform DER -in distribution.cer -out distribution.crt && openssl pkcs12 -legacy -export -out distribution.p12 -inkey key.key -in distribution.crt && cloudshell dl distribution.p12 && rm -f key.key request.csr distribution.c*`
70 | 11. При запросе пароля я советую использовать надежный случайно сгенерированный пароль, например, [отсюда](https://passwordsgenerator.net/?length=22&symbols=0&numbers=1&lowercase=1&uppercase=1&similar=0&ambiguous=0&client=1&autoselect=1)
71 | 12. Сохраните пароль в репозитории GitHub как секрет `CertPassword` (мы уже добавляли секреты [выше](#secret-create)). Вам также понадобится этот пароль если вы решите использовать сертификат на настоящем маке
72 | 13. Скачайте пакет p12, содержащий зашифрованный сертификат и ключ подписи
73 | 14. В репозитории GitHub перейдите в раздел «Code», затем щелкните каталог «Util»
74 | 15. Нажмите кнопку «Add file» и выберите «Upload files»
75 | 16. Выберите загруженный файл «distribution.p12» и нажмите кнопку «Commit changes»
76 |
77 | В ваших последующих проектах сразу переходите к пункту 12 и переиспользуйте пароль и файл `distribution.p12`.
78 |
79 | ### 4. Создание профиля подготовки (provisioning profile)
80 |
81 | Вторая часть необходимая для подписи приложения это профиль подготовки. Он идентифицирует приложение и его возможности, то есть создается для каждого приложения отдельно.
82 |
83 | 1. Перейдите на [портал разработчика Apple](https://developer.apple.com/account/resources/profiles/list), выберите «Profiles» и нажмите ➕
84 | 2. Выберите «App Store» в разделе «Distribution»
85 | 3. Выберите идентификатор приложения, который мы создали ранее (у меня com.solar2d.solar2demo)
86 | 4. На следующей странице выберите сертификат, который мы только что создали. Единственный способ который я знаю чтобы их отличать - это по дате истечения годности - должен быть ровно год от даты создания
87 | 5. На следующей странице введите имя «distribution» и нажмите «Generate»
88 | 6. Скачайте сгенерированный профиль. Если ваш файл назван по-другому, обязательно переименуйте его в `distribution.mobileprovision`, так как инструменты сборки ожидают, что файл будет именно так называться
89 | 7. Загрузите файл, заменив шаблон в каталоге Util в вашем репозитории, как в конце предыдущего раздела
90 |
91 | ### 5. Создание приложений в App Store
92 |
93 | Нам нужно создать приложение в App Store чтобы загружать и тестировать его
94 |
95 | 1. Перейдите на сайт App Store Connect: [https://appstoreconnect.apple.com/](https://appstoreconnect.apple.com/)
96 | 2. Войдите в систему, прочтите и примите все пользовательские соглашения
97 | 3. Выберите «My Apps»
98 | 4. В заголовке рядом с «Apps» нажмите кнопку ➕ и выберите «New App»
99 | 5. Во всплывающем окне:
100 | 1. Выберите iOS в качестве платформы
101 | 2. Назовите свое приложение, например, Solar2Demo
102 | 3. Выберите язык, который вам подходит, например, English (U.S.)
103 | 4. Идентификатор приложения, который мы создали ранее (для меня это «Solar2D Demo App - com.solar2d.solar2demo»)
104 | 5. Какой-то SKU для идентификации приложения, например Solar2Demo
105 | 6. Выберите «Full Access» и нажмите «Create»
106 | 6. Через несколько секунд откроется страница со списком приложений
107 | 7. Это окно браузера понадобится вам позже для настройки тестировщиков, так что оставьте его открытым
108 |
109 | ## Проверка
110 |
111 | На этот момент, у вас должно быть следующее:
112 |
113 | - 4 секрета в настройках репозитория [⏯](https://i.imgur.com/zB92Fjr.png):
114 | - [x] `AppleUser`
115 | - [x] `ApplePassword`
116 | - [x] `AppleTeamId` *(Необязательно)*
117 | - [x] `CertPassword`
118 | - В каталоге `Util` заменены 2 файла [⏯](https://i.imgur.com/6b9xcZS.png):
119 | - [x] `Util/distribution.p12`
120 | - [x] `Util/distribution.mobileprovision`
121 |
122 | # Сборка и загрузка приложения
123 |
124 | Теперь самое интересное. Сборка и загрузка приложения
125 |
126 | 1. Перейдите в репозиторий GitHub и выберите «Actions» в строке меню
127 | 2. Выберите «Build and Deliver» на боковой панели
128 | 3. Выберите «Run Workflow», оставьте все параметры по умолчанию и подтвердите, нажав зеленую кнопку
129 |
130 | Готово!
131 |
132 | Это запустит сборку. Сама сборка должна завершится примерно за 3-10 минут, она также загрузит созданное в App Store Connect, где оно будет проходить автоматическую обработку. Иногда это может занять довольно много времени
133 |
134 | ## Тестирование
135 |
136 | Сразу после того, как GitHub отправило сборку, вы можете настроить тестирование. Для этого:
137 |
138 | 1. Перейдите на портал [App Store Connect](https://appstoreconnect.apple.com/), выберите «My Apps» и щелкните свое приложение
139 | 2. В верхнем меню выберите «TestFlight», а затем на боковой панели в разделе «Internal Group» выберите «App Store Connect Users»
140 | 3. Нажмите ➕ возле «Testers» и добавьте хотя бы себя
141 | 4. Вам будет отправлено электронное письмо. Откройте это письмо на iOS устройстве и нажмите на кнопку в нем. Должно запуститься приложение TestFlight и предложить вам присоединиться к тестированию приложения
142 |
143 | Когда обработка сборки будет завершена, вы получите электронное письмо. Используйте TestFlight, чтобы установить приложение и тестируйте его на своем устройстве
144 |
145 | ### Последующие сборки
146 |
147 | Когда сборка и TestFlight уже настроены, все, что вам нужно сделать, - это закоммитить свой код, перейти к «Build and Deliver» в Actions вашего репозитория и нажать «Run Workflow»
148 |
149 | Затем дождитесь уведомления и обновите приложение в TestFlight. Эту же сборку потом можно опубликовать в App Store
150 |
151 | # Что дальше
152 |
153 | Замените проект в каталоге Project своими творениями. Как правило, рекомендуется использовать систему управления версиями, такую как Git, чтобы иметь историю изменений в вашем проекте и не потерять весь код из-за какой-то странной аварии. Вы можете клонировать репозиторий на свой компьютер, изменять содержимое, комитить изменения и создавать новые сборки. Когда обновление будет готово, тестируйте его при помощи TestFlight
154 |
155 | Другой вариант - интегрировать скрипты в ваши существующие проекты на GitHub. Все, что вам нужно, находится в файлах [`.github/workflows/build.yml`](.github/workflows/build.yml) и [`Util/build.sh`](Util/build.sh)
156 |
157 | ## Скажите спасибо ❤️ (бесплатно, без СМС)
158 |
159 | Если вам нравится этот шаблон и руководство, не забудьте отметить проекты звездочкой на GitHub:
160 |
161 | - Игровой движок Solar2D: [https://github.com/coronalabs/corona](https://github.com/coronalabs/corona)
162 | - Этот шаблон: [https://github.com/solar2d/demo-app-store-automation](https://github.com/solar2d/demo-app-store-automation)
163 |
164 | ## Поддержите проект
165 |
166 | Solar2D - это игровой движок с полностью открытым исходным кодом, для существования которого требуются пожертвования пользователей. Рассмотрите возможность [поддержки](http://github.com/coronalabs/corona?sponsor=1) проекта на [Patreon](https://patreon.com/shchvova)
167 |
168 | ### Примечания
169 |
170 | GitHub Actions имеют [ограничения на использование](https://docs.github.com/en/free-pro-team@latest/github/setting-up-and-managing-billing-and-payments-on-github/about-billing-for-github-actions), особенно для проектов в приватных репозиториях. Обязательно ознакомьтесь с ними. На данный момент минута для macOS равна 10 бесплатных минут для Linux и стоит 8 центов после превышения бесплатного лимита. Итого, в настоящее время у вас есть 200 бесплатных минут для сборки в приватных репозиториях. Этого более чем достаточно, чтобы билдить один или два раза в неделю. Вам не нужно вводить кредитную карту или что-то еще, пока у вас не закончатся бесплатные минуты, но даже если вы это сделаете, эту цену трудно превзойти
171 |
172 | ## Вопросы/пожелания
173 |
174 | Если у вас есть какие-либо вопросы, сообщите о них на [https://github.com/solar2d/demo-app-store-automation/issues](https://github.com/solar2d/demo-app-store-automation/issues)
175 |
176 | Наслаждайтесь и создавайте потрясающие игры с Solar2D!
177 |
178 | 
179 |
--------------------------------------------------------------------------------
/Util/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | (
3 | set -e
4 | cd "$(dirname "$0")/.."
5 | WORKSPACE=${GITHUB_WORKSPACE:="$(pwd)"}
6 | export WORKSPACE
7 |
8 | function err {
9 | echo "$1" 1>&2
10 | return 1
11 | }
12 |
13 | echo "Verifying input parameters"
14 |
15 | S2D_BUILD_NUMBER="$(echo "$S2D_BUILD_NAME." | cut -d. -f2 )"
16 | [ "${APP_VERSION}" ] || err "AppVersion, required Action parameter is not set"
17 | [ "${S2D_BUILD_NAME}" ] || err "Solar2DBuild, required action parameter is not set"
18 | [ "${S2D_BUILD_NUMBER}" ] || err "Solar2DBuild, required action parameter has invalid format (i.e. 2020.3635)"
19 | [ "${CERT_PASSWORD}" ] || err "CertPassword secret is required"
20 | [ "${APPLE_USERNAME}" ] || err "AppleUser secret is required"
21 | [ "${APPLE_PASSWORD}" ] || err "ApplePassword secret is required"
22 | [ "${APPLE_TEAM_ID}" ] || echo "Warning AppleTeamId secret is not set. It is optional but may cause errors. To get your team ID run List Apple Teams workflow"
23 |
24 | # Setting op code signing only on CI not to screw with local Keychain if run on own machine
25 | if [ "$CI" ]
26 | then
27 | echo "Seting up code signing"
28 |
29 | security delete-keychain build.keychain || true
30 | security create-keychain -p 'Password123' build.keychain
31 | security default-keychain -s build.keychain
32 | security import "Util/distribution.p12" -A -P "$CERT_PASSWORD"
33 | security unlock-keychain -p 'Password123' build.keychain
34 | security set-keychain-settings build.keychain
35 | security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k 'Password123' build.keychain > /dev/null
36 | fi
37 |
38 | S2D_DMG="Util/S2D-${S2D_BUILD_NUMBER}.dmg"
39 | if [ ! -f "${S2D_DMG}" ]
40 | then
41 | echo "Downloading Solar2D"
42 | curl -L "https://github.com/coronalabs/corona/releases/download/${S2D_BUILD_NUMBER}/Solar2D-macOS-${S2D_BUILD_NAME}.dmg" -o "${S2D_DMG}"
43 | fi
44 |
45 | hdiutil attach "${S2D_DMG}" -noautoopen -mount required -mountpoint Util/S2D
46 |
47 | echo "Building the app"
48 | BUILDER="Util/S2D/Corona-${S2D_BUILD_NUMBER}/Native/Corona/mac/bin/CoronaBuilder.app/Contents/MacOS/CoronaBuilder"
49 | "$BUILDER" build --lua "Util/recipe.lua"
50 |
51 | hdiutil detach Util/S2D
52 | )
--------------------------------------------------------------------------------
/Util/deliver.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | (
3 | set -e
4 |
5 | echo "Uploading the app"
6 | if [ -z "${APPLE_TEAM_ID}" ]
7 | then
8 | xcrun altool --upload-app --type=ios -f Util/*.ipa -u "${APPLE_USERNAME}" -p "${APPLE_PASSWORD}" -asc_provider "${APPLE_TEAM_ID}"
9 | else
10 | xcrun altool --upload-app --type=ios -f Util/*.ipa -u "${APPLE_USERNAME}" -p "${APPLE_PASSWORD}"
11 | fi
12 | )
13 |
--------------------------------------------------------------------------------
/Util/distribution.mobileprovision:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Util/distribution.mobileprovision
--------------------------------------------------------------------------------
/Util/distribution.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/solar2d/demo-app-store-automation/dbce1daff28e60483ae947b2891c78b82149df8c/Util/distribution.p12
--------------------------------------------------------------------------------
/Util/recipe.lua:
--------------------------------------------------------------------------------
1 |
2 | local root = os.getenv('GITHUB_WORKSPACE') or os.getenv('WORKSPACE')
3 |
4 | return {
5 | appName = "Solar2Demo",
6 | platform = "ios",
7 | appVersion = os.getenv('APP_VERSION') or "1.0",
8 | projectPath = root .. "/Project",
9 | dstPath = root .. '/Util',
10 | certificatePath = root .. "/Util/distribution.mobileprovision",
11 | customTemplate = "-angle",
12 | }
13 |
--------------------------------------------------------------------------------