DEV Community

Jonathan Gómez
Jonathan Gómez

Posted on

6 1

🧪 Github Actions for Dart package with Environment variables 🧪

🎉 I just end the configuration and I'm so happy that it work so I'm just gonna throw it here 😅

I'm currently working on a dar wrapper package for the Notion API so I had to add a secret token for testing. I didn't know how to work with environment variables on flutter until today, and to configure a GitHub Action for the package testing was a good challenge to learn and here are the steps I did if you want to make something similar and don't know how.

💡 Also, as I mentioned, I just do this today and I'm still learning so if you know a better way please let me know. And excuse my English hehe.

Now let's get into it in two points:

🔧 Set up Flutter test

- A): By default my variables are set from Platform



String? token = Platform.environment['TOKEN'];
String? testBlockId = Platform.environment['TEST_BLOCK_ID'];


Enter fullscreen mode Exit fullscreen mode

- B): I have a variable to know when the execution environment is a GitHub Action*



String execEnv =
  env['EXEC_ENV'] ?? Platform.environment['EXEC_ENV'] ?? '';

if (execEnv != 'github_actions') {
  // more code here...
}


Enter fullscreen mode Exit fullscreen mode

- C): If the environment is not a GitHub Action then I try to load the .env file



setUpAll(() {
  // load .env variables for all tests
  load();

  // more code here...
});

tearDownAll(() {
  // clean environment after all tests
  clean();
});


Enter fullscreen mode Exit fullscreen mode

- D): I try to set the value of the variables with the following hierarchy from highest to lowest:

  • Value from .env file
  • Value from Platform (initial value by default)
  • An empty string as last option ```dart

token = env['TOKEN'] ?? token ?? '';
testBlockId = env['TEST_BLOCK_ID'] ?? testBlockId ?? '';
// variables declared before, see full example code bellow.


> *At least the `dotenv` package only gets the variables from a file and in GitHub actions the secrets are flushed directly into the environment without occupying an .env file.

**full example code:**
```dart


void main() {
  // (A)
  String? token = Platform.environment['TOKEN'];
  String? testBlockId = Platform.environment['TEST_BLOCK_ID'];

  // (B)
  String execEnv = env['EXEC_ENV'] ?? Platform.environment['EXEC_ENV'] ?? '';

  // (B)
  if (execEnv != 'github_actions') {
    setUpAll(() {
      // (C)
      load();

      // (D)
      token = env['TOKEN'] ?? token ?? '';
      testBlockId = env['TEST_BLOCK_ID'] ?? testBlockId ?? '';
    });

    tearDownAll(() {
      clean();
    });
  }

  group('Notion Block Client', () {
    test('Retrieve block children', () async {
      final NotionBlockClient blocks = NotionBlockClient(token: token);

      var res = await blocks.fetch(testBlockId ?? '');
      expect(res.statusCode, 200);
    });
  });
}


Enter fullscreen mode Exit fullscreen mode

full real code click here

🐙 Set up GitHub Action

Now on GitHub I create a new GitHub Action.

First of all I have to add the environment variables to the secrets on Settings -> Secrets -> Click to New repository secret:

Screen Shot 2021-05-20 at 17.54.58

And then:
- A) First I add flutter SDK



- uses: actions/setup-java@v1
  with:
    java-version: '12.x'
- uses: subosito/flutter-action@v1
  with:
    flutter-version: '2.0.5'


Enter fullscreen mode Exit fullscreen mode

- B) Then I install the dependencies



- name: Install dependencies
  run: flutter pub get


Enter fullscreen mode Exit fullscreen mode

- C) Finally I run the test passing the secrets as environment variables. Note that I set the EXEC_ENV as "github_actions" like I defined on the tests configuration to avoid to try to load the .env file.



- name: Test package
  run: flutter test
  env:
    TOKEN: ${{ secrets.TOKEN }}
    TEST_BLOCK_ID: ${{ secrets.TEST_BLOCK_ID }}
    EXEC_ENV: 'github_actions'


Enter fullscreen mode Exit fullscreen mode

full example code:



name: Test
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
jobs:
  build:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v2
      # (A)
      - uses: actions/setup-java@v1
        with:
          java-version: '12.x'
      - uses: subosito/flutter-action@v1
        with:
          flutter-version: '2.0.5'
      # (B)
      - name: Install dependencies
        run: flutter pub get
      # (C)
      - name: Test package
        run: flutter test
        env:
          TOKEN: ${{ secrets.TOKEN }}
          TEST_BLOCK_ID: ${{ secrets.TEST_BLOCK_ID }}
          EXEC_ENV: 'github_actions'


Enter fullscreen mode Exit fullscreen mode

full real code click here

📚 Resources

I found very useful the next resources:
Main source:
https://medium.com/flutter-community/testing-dart-packages-with-github-actions-4c2c671b1e34
Secondary but necessary source:
https://github.com/subosito/flutter-action

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (1)

Collapse
 
devbirgit profile image
Birgit Pohl 🏡

I believe by the time that this article has been written flutter_dotenv has added an additional feature, where you can merge the dotenv and Platform.environment together. Which would simplify your code. :)

// For example using Platform.environment that contains a CLIENT_ID entry
  await DotEnv.load(mergeWith: Platform.environment);
  print(env["CLIENT_ID"]);
Enter fullscreen mode Exit fullscreen mode

pub.dev/packages/flutter_dotenv

Sentry mobile image

Improving mobile performance, from slow screens to app start time

Based on our experience working with thousands of mobile developer teams, we developed a mobile monitoring maturity curve.

Read more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay