byCedric / semantic-release-expo

An Expo implementation for semantic release, so you don't have to bother.
MIT License
91 stars 11 forks source link

add support for app.config.js manifest #191

Open zanona opened 4 years ago

zanona commented 4 years ago

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?

TomFrames commented 4 years ago

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

zanona commented 4 years ago

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',
  ...
}
TomFrames commented 4 years ago

Great! Thanks for the reference 👍

RBrNx commented 3 years ago

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?

Borduhh commented 3 years ago

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 commented 3 years ago

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'],
      },
    ],
  ],
};
oldskoolfan commented 2 years ago

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

Bartozzz commented 2 years ago

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 ? "," : ""}`;
        },
      },
    ],
  },
],