Skip to content

Commit 6376cff

Browse files
authored
Merge pull request #129 from shipth-is/128-feature-warning-users-when-their-export_presetscfg-is-set-to-legacy-build-mode
feature: warning users when their export_presets.cfg is set to "legacy" build mode
2 parents 71871c8 + 5b61eaa commit 6376cff

File tree

18 files changed

+469
-265
lines changed

18 files changed

+469
-265
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Confirm change to export_presets.cfg
2+
3+
**In order to publish your game on Google Play, an edit must be made to your `export_presets.cfg` file to enable the Gradle build method.**
4+
5+
This change is necessary because Google Play requires Android App Bundles (AAB files) for new apps, and the Gradle build method is needed to create AAB files.
6+
7+
You can read more about this in the **ShipThis Documentation** [<%= docsURL %>](<%= docsURL %>)
8+
9+
You are using Godot version **<%= godotVersion %>**, ShipThis will update the **<%= optionKey %>** option in your `export_presets.cfg` file to enable the Gradle build method.
10+
11+
## Do you want to proceed with this change?
12+
13+
Please press **Y** to confirm and proceed with the change or **N** to cancel the operation and exit the Android wizard.

docs/util/android-build-method.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Command: `util android-build-method`
2+
3+
## Description
4+
5+
Gets and sets the Android build method in export_presets.cfg
6+
7+
## Help Output
8+
9+
```help
10+
USAGE
11+
$ shipthis util android-build-method [-l] [-g]
12+
13+
FLAGS
14+
-g, --gradle use gradle build method
15+
-l, --legacy use legacy build method
16+
17+
DESCRIPTION
18+
Gets and sets the Android build method in export_presets.cfg
19+
20+
EXAMPLES
21+
$ shipthis util android-build-method
22+
23+
$ shipthis util android-build-method --legacy
24+
25+
$ shipthis util android-build-method --gradle
26+
```

package-lock.json

Lines changed: 10 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@
2020
"axios": "^1.7.7",
2121
"chalk": "^5.4.1",
2222
"crypto-js": "^4.2.0",
23-
"deepmerge": "^4.3.1",
2423
"fast-glob": "^3.3.2",
2524
"fs-extra": "^11.2.0",
2625
"fullscreen-ink": "^0.1.0",
27-
"ini": "^5.0.0",
26+
"godot-export-presets": "^0.1.6",
2827
"ink": "^5.0.1",
2928
"ink-spinner": "^5.0.0",
3029
"isomorphic-git": "^1.27.1",
@@ -54,7 +53,6 @@
5453
"@types/crypto-js": "^4.2.2",
5554
"@types/ejs": "^3.1.5",
5655
"@types/fs-extra": "^11.0.4",
57-
"@types/ini": "^4.1.1",
5856
"@types/jsonwebtoken": "^9.0.6",
5957
"@types/luxon": "^3.4.2",
6058
"@types/mocha": "^10",
@@ -108,6 +106,7 @@
108106
"exports": [
109107
"./dist/utils/help.js",
110108
"./dist/commands/util/glass.js",
109+
"./dist/commands/util/android-build-method.js",
111110
"./dist/commands/apple/apiKey/export.js",
112111
"./dist/commands/apple/apiKey/create.js",
113112
"./dist/commands/apple/apiKey/status.js",

src/baseCommands/baseGameAndroidCommand.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ export abstract class BaseGameAndroidCommand<T extends typeof Command> extends B
3939
protected async getAndroidPackageName(gameId: string): Promise<string> {
4040
const game = await this.getGame()
4141
const generated = generatePackageName(game.name)
42-
const suggested = game.details?.iosBundleId || getGodotAndroidPackageName() || generated || 'com.example.game'
42+
const godotPackageName = await getGodotAndroidPackageName()
43+
const suggested = game.details?.iosBundleId || godotPackageName || generated || 'com.example.game'
4344
const question = `Please enter the Android Package Name, or press enter to use ${suggested}: `
4445
const entered = await getInput(question)
4546
return entered || suggested

src/commands/game/ios/app/create.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ export default class GameIosAppCreate extends BaseGameCommand<typeof GameIosAppC
4040
const getBundleIdentifier = async (): Promise<string> => {
4141
if (bundleId) return bundleId
4242
const generatedBundleId = generatePackageName(game.name)
43+
const godotBundleId = await getGodotAppleBundleIdentifier()
4344
const suggestedBundleId =
44-
game.details?.iosBundleId || getGodotAppleBundleIdentifier() || generatedBundleId || 'com.example.game'
45+
game.details?.iosBundleId || godotBundleId || generatedBundleId || 'com.example.game'
4546
const question = `Please enter the BundleId in the Apple Developer Portal, or press enter to use ${suggestedBundleId}: `
4647
const enteredBundleId = await getInput(question)
4748
return enteredBundleId || suggestedBundleId
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {Flags} from '@oclif/core'
2+
3+
import {BaseCommand} from '@cli/baseCommands/index.js'
4+
import {isGradleBuildEnabled, setGradleBuildEnabled} from '@cli/utils/godot.js'
5+
6+
export default class UtilAndroidBuildMethod extends BaseCommand<typeof UtilAndroidBuildMethod> {
7+
static override args = {}
8+
static override description = 'Gets and sets the Android build method in export_presets.cfg'
9+
static override examples = [
10+
'<%= config.bin %> <%= command.id %>',
11+
'<%= config.bin %> <%= command.id %> --legacy',
12+
'<%= config.bin %> <%= command.id %> --gradle',
13+
]
14+
15+
static override flags = {
16+
legacy: Flags.boolean({char: 'l', description: 'use legacy build method'}),
17+
gradle: Flags.boolean({char: 'g', description: 'use gradle build method'}),
18+
}
19+
20+
public async run(): Promise<void> {
21+
const {flags} = await this.parse(UtilAndroidBuildMethod)
22+
23+
if (flags.legacy && flags.gradle) {
24+
this.error('Cannot use both --legacy and --gradle flags together')
25+
}
26+
27+
if (!flags.legacy && !flags.gradle) {
28+
// Show current build method
29+
const buildMethod = (await isGradleBuildEnabled()) ? 'gradle' : 'legacy'
30+
this.log(`Current Android build method: ${buildMethod}`)
31+
return
32+
}
33+
34+
const isGradle = flags.gradle ? true : false
35+
const buildMethod = flags.legacy ? 'legacy' : 'gradle'
36+
this.log(`Setting Android build method to: ${buildMethod}`)
37+
// Set the build method in the export presets file
38+
await setGradleBuildEnabled(isGradle)
39+
}
40+
}

src/components/JobFollow.tsx

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Job, JobLogEntry, LogLevel} from '@cli/types/api.js'
22
import {useJobWatching} from '@cli/utils/index.js'
3+
import { useStderr, useStdout } from 'ink'
34

45
interface JobFollowProps {
56
jobId: string
@@ -9,18 +10,40 @@ interface JobFollowProps {
910
}
1011

1112
// Outputs job logs to stdout/stderr as they come in
12-
export const JobFollow = ({jobId, onComplete, onFailure, projectId}: JobFollowProps) => {
13+
export const JobFollow = ({
14+
jobId,
15+
onComplete,
16+
onFailure,
17+
projectId,
18+
}: JobFollowProps) => {
19+
const {stdout, write: writeOut} = useStdout();
20+
const {stderr, write: writeErr} = useStderr();
21+
22+
// Only emit ANSI when we're actually writing to a TTY.
23+
const useAnsi = Boolean((stderr as any).isTTY ?? (stdout as any).isTTY);
24+
25+
const yellow = useAnsi ? '\x1b[33m' : '';
26+
const red = useAnsi ? '\x1b[31m' : '';
27+
const reset = useAnsi ? '\x1b[0m' : '';
28+
1329
useJobWatching({
1430
isWatching: true,
1531
jobId,
1632
onComplete,
1733
onFailure,
1834
onNewLogEntry(logEntry: JobLogEntry) {
19-
if (logEntry.level === LogLevel.ERROR) console.error(logEntry.message)
20-
else console.log(logEntry.message)
35+
const msg = logEntry.message + '\n';
36+
37+
if (logEntry.level === LogLevel.ERROR) {
38+
writeErr(`${red}${msg}${reset}`);
39+
} else if (logEntry.level === LogLevel.WARN) {
40+
writeErr(`${yellow}${msg}${reset}`);
41+
} else {
42+
writeOut(msg);
43+
}
2144
},
2245
projectId,
23-
})
46+
});
2447

25-
return null
26-
}
48+
return null;
49+
};

src/components/JobLogTail.tsx

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,24 @@
1-
import {Box, Text} from 'ink'
1+
import {Box} from 'ink'
22
import Spinner from 'ink-spinner'
33

44
import {JobLogEntry} from '@cli/types'
55
import {JobLogTailProps, useJobLogTail} from '@cli/utils/hooks/index.js'
6-
import {getMessageColor, getShortTime, getStageColor} from '@cli/utils/index.js'
76

87
import {Title} from './common/Title.js'
9-
import {TruncatedText} from './common/TruncatedText.js'
8+
9+
import {JobLogLine} from './common/JobLogLine.js'
1010

1111
export const JobLogTail = (props: JobLogTailProps) => {
1212
const {data, isLoading} = useJobLogTail(props)
1313

14-
// TODO: the <TruncatedText> is causing issues
1514
return (
1615
<Box flexDirection="column">
1716
<Title>Job Logs</Title>
1817
{isLoading && <Spinner type="dots" />}
1918
<Box flexDirection="column">
20-
{data.map((log: JobLogEntry) => {
21-
const stageColor = getStageColor(log.stage)
22-
const messageColor = getMessageColor(log.level)
23-
return (
24-
<Box flexDirection="row" height={1} key={log.id} overflow="hidden">
25-
<Box>
26-
<Text>{getShortTime(log.sentAt)}</Text>
27-
</Box>
28-
<Box justifyContent="flex-start" marginLeft={1} width={9}>
29-
<Text color={stageColor}>{log.stage}</Text>
30-
</Box>
31-
<Box height={1} marginLeft={1} marginRight={2} overflow="hidden">
32-
<TruncatedText color={messageColor}>{log.message}</TruncatedText>
33-
</Box>
34-
</Box>
35-
)
36-
})}
19+
{data.map((log: JobLogEntry) => (
20+
<JobLogLine key={log.id} log={log} />
21+
))}
3722
</Box>
3823
</Box>
3924
)

src/components/android/AndroidWizard/utils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {getGoogleStatus, getProject, getProjectCredentials} from '@cli/api/index.js'
22
import {BaseCommand} from '@cli/baseCommands/baseCommand.js'
3-
import {CredentialsType, Platform} from '@cli/types/index.js'
3+
import {BuildType, CredentialsType, Platform} from '@cli/types/index.js'
44
import {KeyTestError, KeyTestStatus, fetchKeyTestResult, queryBuilds} from '@cli/utils/index.js'
55

66
export enum StepStatus {
@@ -91,7 +91,9 @@ export const getStatusFlags = async (cmd: BaseCommand<any>): Promise<StatusFlags
9191
)
9292

9393
const buildsResponse = projectId && hasShipThisProject ? await queryBuilds({pageNumber: 0, projectId: `${projectId}`}) : null
94-
const hasInitialBuild = Boolean(buildsResponse?.data?.some((build) => build.platform === Platform.ANDROID))
94+
const hasInitialBuild = Boolean(
95+
buildsResponse?.data?.some((build) => build.platform === Platform.ANDROID && build.buildType === BuildType.AAB),
96+
)
9597

9698
const testResult = projectId ? await fetchKeyTestResult({projectId}) : null
9799

0 commit comments

Comments
 (0)