semantic-release-expo icon indicating copy to clipboard operation
semantic-release-expo copied to clipboard

add support for app.config.js manifest

Open zanona opened this issue 4 years ago • 8 comments

Apparently this plugin only caters for app.json manifest format? I am using app.config.js in order to use the extra manifest field. So it would be nice to have this supported.

A workaround is to inherit the version from package.json if using so and under app.config.js have:

import * as pkg from './package.json'

export default {
  name: 'my app',
  version: pkg.version
};

However, I'm not completely clear on whether this semantic-version plugin runs other actions which are useful, besides updating the version on the manifest?

zanona avatar May 28 '20 08:05 zanona

Hi @zanona! I have run into the same issue. Have you made any progression with this incompatibility issue?

TomFrames avatar Aug 18 '20 14:08 TomFrames

Hi, @TomFrames I decided to use https://github.com/google/semantic-release-replace-plugin instead. I'm pasting my release.config.js file in case that's helpful.

module.exports = {
  branches: ['master', {name: 'beta', prerelease: true}, {name: 'alpha', prerelease: true}],
  plugins: [
    '@semantic-release/commit-analyzer',
    '@semantic-release/release-notes-generator',
    [
      '@google/semantic-release-replace-plugin',
      {
        replacements: [
          {
            files: ['app.config.js'],
            from: "version: process.env.APP_VERSION \\|\\| '.*'",
            to: "version: process.env.APP_VERSION || '${nextRelease.version}'",
          },
        ],
      },
    ],
    '@semantic-release/changelog',
    ['@semantic-release/git', {assets: ['CHANGELOG.md', 'app.config.js']}],
    '@semantic-release/gitlab',
  ],
};

update

also adding part of my app.config.js for clarity:

export default {
  name: 'App',
  description: 'description',
  slug: 'app',
  platforms: ['ios', 'android'],
  version: process.env.APP_VERSION || '1.0.0-alpha.8',
  ...
}

zanona avatar Aug 18 '20 19:08 zanona

Great! Thanks for the reference 👍

TomFrames avatar Aug 19 '20 10:08 TomFrames

I've also recently encountered this issue as my app.config.js was inheriting the version number from package.json. So for the time being I simply reverted back to using app.json since semantic-release-expo handles the updating of the version number for me.


However I definitely think this feature is warranted, so I started to take a look at it but it seems a tougher fix that I initially thought.

I started by attempting to modify the readManifest function to account for a .config.js file, using the new dynamic import() syntax

/**
 * Read the Expo manifest content and return the parsed JSON.
 */
export async function readManifest(filename: string): Promise<ManifestMeta> {
	try {
		const isNewAppConfig = filename.includes('config.js');
		const content = isNewAppConfig ? await import(filename) : await readFile(filename, 'utf8');
		const manifest = isNewAppConfig ? content : JSON.parse(content).expo;

		return { filename, content, manifest };
	} catch (error) {
		error.expo = filename;
		throw error;
	}
}

Unfortunately this doesn't work without adding "type": "module" to the package.json inside this repository, which then causes an error as semantic-release uses require() to load it's plugins which isn't compatible with what is now an ES6 Module.

An error occurred while running semantic-release: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/conor/Documents/Projects/Personal/semantic-release-playground/node_modules/semantic-release-expo/build/src/index.js
require() of ES modules is not supported.

@byCedric Happy to help you out with this if you have any suggestions on how to proceed?

RBrNx avatar Mar 30 '21 13:03 RBrNx

Hi, @TomFrames I decided to use https://github.com/google/semantic-release-replace-plugin instead. I'm pasting my release.config.js file in case that's helpful.

module.exports = {
  branches: ['master', {name: 'beta', prerelease: true}, {name: 'alpha', prerelease: true}],
  plugins: [
    '@semantic-release/commit-analyzer',
    '@semantic-release/release-notes-generator',
    [
      '@google/semantic-release-replace-plugin',
      {
        replacements: [
          {
            files: ['app.config.js'],
            from: "version: process.env.APP_VERSION \\|\\| '.*'",
            to: "version: process.env.APP_VERSION || '${nextRelease.version}'",
          },
        ],
      },
    ],
    '@semantic-release/changelog',
    ['@semantic-release/git', {assets: ['CHANGELOG.md', 'app.config.js']}],
    '@semantic-release/gitlab',
  ],
};

update

also adding part of my app.config.js for clarity:

export default {
  name: 'App',
  description: 'description',
  slug: 'app',
  platforms: ['ios', 'android'],
  version: process.env.APP_VERSION || '1.0.0-alpha.8',
  ...
}

Are you handling an Android versionCode? We are hitting a wall trying to auto-increment that.

Borduhh avatar Aug 30 '21 15:08 Borduhh

I took the torch from @zanona and also moved to https://github.com/google/semantic-release-replace-plugin. After a quick PR today, you should be able to update your expo version, apple buildNumber, and Android versionCode with semantic-release now. Here is the config we use:

module.exports = {
  branches: [{ name: 'main' }],
  plugins: [
    '@semantic-release/commit-analyzer',
    '@semantic-release/release-notes-generator',
    [
      '@google/semantic-release-replace-plugin',
      {
        replacements: [
          {
            files: ['app.config.js'],
            from: "version: '.*'", // eslint-disable-line
            to: "version: '${nextRelease.version}'", // eslint-disable-line
          },
          {
            files: ['app.config.js'],
            from: "buildNumber: '.*'", // eslint-disable-line
            to: "buildNumber: '${nextRelease.version}'", // eslint-disable-line
          },
          {
            files: ['app.config.js'],
            from: `versionCode: [^,]*`, // eslint-disable-line
            to: (match) => `versionCode: ${parseInt(match.split(':')[1].trim()) + 1}`, // eslint-disable-line
          },
        ],
      },
    ],
    '@semantic-release/changelog',
    '@semantic-release/npm',
    '@semantic-release/github',
    [
      '@semantic-release/git',
      {
        message: 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}',
        assets: ['CHANGELOG.md', 'package.json', 'package-lock.json', 'app.config.js'],
      },
    ],
  ],
};

Borduhh avatar Aug 30 '21 21:08 Borduhh

I ran into this problem today, but found that you can use app.json along with app.config.js:

You can access and modify incoming config values by exporting a function that returns an object. This is useful if your project also has an app.json. By default, Expo CLI will read the app.json first and send the normalized results to the app.config.js.

See https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs for their code examples

oldskoolfan avatar Dec 06 '21 20:12 oldskoolfan

Not related but might be helpful. If anyone is wondering how to migrate app.json updates from semantic-release-expo to @google/semantic-release-replace-plugin, here's my config:

[
  "@google/semantic-release-replace-plugin",
  {
    replacements: [
      {
        files: ["app.json"],
        from: '"version": ".*"',
        to: '"version": "${nextRelease.version}"',
      },
      {
        files: ["app.json"],
        from: '"buildNumber": ".*"',
        to: '"buildNumber": "${nextRelease.version}"',
      },
      {
        files: ["app.json"],
        from: `"versionCode": .*$`,
        to: (match) => {
          const hadComma = match.includes(",");
          const currVersion = parseInt(match.split(":")[1].trim()) || 0;
          const nextVersion = currVersion + 1;
          return `"versionCode": ${nextVersion}${hadComma ? "," : ""}`;
        },
      },
    ],
  },
],

Bartozzz avatar May 07 '22 13:05 Bartozzz