🧪 Github Actions for Dart package with Environment variables 🧪
Tags: dart, github, testing, environment
Published: 2021-05-20 23:34:44

> 🎉 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](#set-up-flutter-test)
- 🐙 [Set Up GitHub Action](#set-up-github-action)

## 🔧 Set up Flutter test
**- A):** By default my variables are set from Platform
```dart
String? token = Platform.environment['TOKEN'];
String? testBlockId = Platform.environment['TEST_BLOCK_ID'];
```
**- B):** I have a variable to know when the execution environment is a GitHub Action*
```dart
String execEnv =
  env['EXEC_ENV'] ?? Platform.environment['EXEC_ENV'] ?? '';

if (execEnv != 'github_actions') {
  // more code here...
}
```
**- C):** If the environment is not a GitHub Action then I try to load the `.env` file
```dart
setUpAll(() {
  // load .env variables for all tests
  load();

  // more code here...
});

tearDownAll(() {
  // clean environment after all tests
  clean();
});
```
**- 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);
    });
  });
}
```

[full real code click here](https://github.com/jonathangomz/notion_api/blob/main/test/notion_api_test.dart)

## 🐙 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t3s8bkmvo4q6rv3012xh.png)

And then:
**- A)** First I add flutter SDK
```yml
- uses: actions/setup-java@v1
  with:
    java-version: '12.x'
- uses: subosito/flutter-action@v1
  with:
    flutter-version: '2.0.5'
```
**- B)** Then I install the dependencies
```yml
- name: Install dependencies
  run: flutter pub get
```
**- 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.
```yml
- name: Test package
  run: flutter test
  env:
    TOKEN: ${{ secrets.TOKEN }}
    TEST_BLOCK_ID: ${{ secrets.TEST_BLOCK_ID }}
    EXEC_ENV: 'github_actions'
```

full example code:
```yml
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'
```

[full real code click here](https://github.com/jonathangomz/notion_api/blob/main/.github/workflows/main.yml)

## 📚 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