How do you let multiple developers work on the same Forge app?

Hi there,

I must admit I probably didn’t read all the documentation in full detail, and maybe this is actually documented somewhere - but I have one question: What do we need to do so 2 developers can work on the same forge app?

Our current approach (or rather workaround) is that each developer creates their own forge app and replaces the app.id inside the mainfest.yml locally whenever they want to work on it. This seems a bit odd. Is there a better way?

Cheers,
Sven

11 Likes

I am currently writing myself a mock for forge/api storage and forge/bridge invoke.
So that I can unit-test my app, and can write resolver methods without using the actual forge api. That way one developer can relatively easy work on frontend+backend-mock. The other one on real backend code.

My outline for e.g. custom-resolver.ts:

export class CustomBackendResolver {
  constructor(private resolver: any, private api: any) {
    this.resolver.define("getAllFoo", this.invoke_getAllFoo());
    // ...
  }

  // Only used in frontend forge/bridge mock
  public invoke(key: string, params: any): any {
    if (key === "getAllFoo") {
      return this.invoke_getAllFoo()({ context: {}, payload: params });
    }
    // ...
  }

  // Only used in tests - and in constructor - returns method!
  public invoke_getAllFoo() {
    return async (_ctxpayload: BridgeContextAndPayload): Promise<ErrorOrPayload<RestFoos[]>> => {
      const response = await this.api.asApp().requestJira('/rest/api/3/foo', {
        headers: {
          Accept: 'application/json',
        },
      });
      const errorAndPayload = await transformJiraRestResponse<RestFoos[]>(response);
      // Filter out all foo fields
      /...
      return errorAndPayload;
    };
  }
}

In the actual forge App resolver I do:

import Resolver from '@forge/resolver';
import api from '@forge/api';
import { CustomBackendResolver } from './generated-common/backend-resolver';

const resolver = new Resolver();
new CustomBackendResolver(resolver, api);
export const handler = resolver.getDefinitions();

In the Jest test I can then mock the “resolver” and “api” and return mocked stuff, that also works in custom UI (reactJS). But I am currently in the middle of development of a smart mock, currently hardcoded static JSON is returned.

I am also very interested in this topic :slight_smile: Also about integration tests against some kind of forge-integration local docker instance or something would be great. Where you could define seed data somehow… :slight_smile:

4 Likes

Our current approach (or rather workaround) is that each developer creates their own forge app and replaces the app.id inside the mainfest.yml locally whenever they want to work on it. This seems a bit odd. Is there a better way?

Thinking about it, you could automate that process by using a Git hooks (I’m thinking post-checkout and post-merge and post-commit to write the developer’s id and a pre-commit hook that would revert it to default one). Might be simple enough with husky. But I haven’t tried that.

The other way we’ve used was to use an “API account” we could share. The downside to that is that only one person can effectively work on the project at the same time then, since one’s updates overwrite the other developer’s when deployed… (unless different environments are used :thinking: not optimal, but it could be abused).

If Atlassian would allow the creation of more environments, one could have one dev environment per developer. Then the single API account would suffice for now. :innocent:

Of course, the ultimate solution would be to allow sharing DAC apps + one environment per developer (or something else I didn’t think of yet)

7 Likes

Sharing DAC apps is subject of the App developer permission roadmap issue:

Currently only a single user is recorded as the ‘owner’/‘developer’ of a Forge app and is the only user who is permitted to perform actions such as deploying, tunnelling or viewing logs for the app.

We are planning to enhance Forge so that the developer may grant permissions to other users for their app.

We consider solving this limitation a blocker to providing support for commercial Forge apps via the Marketplace.

Once this is in place, we’d probably base any published app of an “API account/bot” indeed (would not be required if there can be multiple owners). This would reduce the problem to the DX for overwriting the app ID when working on per developer environments.

9 Likes

Oh that looks like the missing piece! So it’s simply not possible yet. Thanks, Steffen! :smiley:

I’m interested in this topic. I hope that Atlassian could bring this soon!

1 Like

I just discovered this - how can Atlassian even consider supporting commercial (Marketplace) apps without supporting multiple developers, DevOps engineers, support engineers (access to logs), etc.?

8 Likes

Any updates on multiple developer approaches for Forge App?

Hey @dur4791, I can’t give you a concrete “yes, this will be done by X date” but I also didn’t want to leave you on “seen”. So, I just want to let you know that the multiple developers ask (aka multi-user app ownership) is high on our priority list and I’m currently looking into this space - it will be a fairly big initiative, but we’re hoping to ship it this financial year. I’ll keep you and the rest of the community updated on how we’re doing as soon as I can share more.

1 Like

This is something that has been bugging me for quite a while now and today I finally came up with a simple and clean solution that seems to work (if you’re using git and on a Linux system) while we’re waiting for Atlassian to provide proper appId sharing.

In the directory where your manifest.yml is, place (or add to if it already exists) a .gitattributes file with the following content:

manifest.yml filter=setid

Then, in your .git/config file, add a block like this:

[filter "setid"]
    clean = sed 's:app/<your-own-appId>:app/<the-appId-in-git>:g'
    smudge = sed 's:app/<the-appId-in-git>:app/<your-own-appId>:g'

This will make git call sed to do a find-and-replace on the appId on every invoke (push, commit, checkout, …). Your own appId will live on your disk, but the committed appId will remain in the git repository.

You can safely commit the .gitattributes file, if git doesn’t find the filter in your config, it just seems to ignore it so this also shouldn’t break any CI/CD you have setup.

This probably won’t work out of the box on Windows or MacOs systems but it should be enough information to get you started.

15 Likes

Hi @Nir :wave: ,

why is the Trello ticket for multi-user app ownership archived? There is no link for new ticket and I cannot find similar ticket. Where can I check progress of this improvemet?

Thanks

@slythe,

See my recent response on another thread:

1 Like

@ibuchanan any updates about this?

This has been possible for a while now.

https://developer.atlassian.com/platform/forge/changelog/#CHANGE-1203

3 Likes