如何在使用Flutter Web和Github Actions时访问密钥

27
我有一个Flutter Web应用程序,为了访问数据库,我在secrets.dart文件中硬编码了一个API密钥,这很好地实现了我的需求。我已将此文件添加到.gitignore以防止它被推送到版本控制。但是,当使用GitHub Actions部署应用程序时,脚本会因为无法检测到secrets文件而失败。
我查看了Github上Encrypted secrets的文档,它可以存储secrets。但似乎只能在yml文件中访问这些secrets。
我想知道如何在我的应用程序中使用此密钥,以便我的脚本成功运行并部署应用程序。
这是我的文件夹结构:
lib/
  services/
     database.dart /// this file uses the APIkey from secrets.dart
  secrets.dart /// contains the APIkey

我想到解决这个问题的一种方法是使用一个.env文件,但我不太熟悉如何通过CI脚本将密钥添加到.env文件中。我相信这也可以解决我的问题。
这是我的CI脚本:
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on merge
"on":
  push:
    branches:
      - master
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1
        with:
          java-version: "12.x"
      - uses: subosito/flutter-action@v1
        with:
          channel: "master"
      - run: flutter pub get
      - run: flutter pub run build_runner build --delete-conflicting-outputs
      - run: flutter build web --release
      - uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: "${{ secrets.GITHUB_TOKEN }}"
          firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_VOCABHUB_34C7F }}"
          channelId: live
          projectId: vocabhub-34c7f
        env:
          FIREBASE_CLI_PREVIEWS: hostingchannels

2个回答

54

你可以在源代码控制被忽略的情况下使用你的secrets.dart文件。

以下是步骤

  1. 在本地机器上,使用base64命令对secrets.dart文件内容进行编码:
  base64 lib/path/to/secrets.dart
  • 将输出复制并粘贴到您的GitHub secrets中,将其命名为$SECRETS_FILE_CONTENT或您想要的任何名称。
  • flutter pub get步骤之前,将此CI步骤添加到您的yaml脚本中。
      # other stuff ...
      - run: echo $SECRETS_FILE_CONTENT | base64 -d > lib/path/to/secrets.dart
        env:
          SECRETS_FILE_CONTENT: ${{ secrets.SECRETS_FILE_CONTENT }}
      - run: flutter pub get
      - run: flutter pub run build_runner build --delete-conflicting-outputs
      - run: flutter build web --release
      # other stuff ...
    
  • 按照以下步骤在GitHub用户界面中添加密钥:

    单击存储库的“设置”选项卡,单击“Secrets”,单击“New repository secret”,不要使用“环境变量 secrets”因为它不起作用

    填写变量名称,例如SECRETS_FILE_CONTENT和其值,例如base-64编码文件内容

    您的秘密应该出现在UI下半部分的“仓库秘密”中,不应出现在“环境秘密”中,因为后者无法与简单的${{ secrets.name_of_variable }}一起使用。

    现在,SECRETS_FILE_CONTENT变量名称应在底部的第二个框中显示

    为了提供更多上下文信息,这是您存储库中的“actions”文件(例如.github/workflows/ci.yml)应该是什么样子的:

    name: CI
    
    on:
      push:
        branches: [ main, dev ]
      pull_request:
        branches: [ main ]
    
      # Allows to run this workflow manually from the Actions tab
      workflow_dispatch:
      
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          - name: Decode base64 secrets
            run: echo $SECRETS_FILE_CONTENTS | base64 -d > lib/path/to/secrets.dart
            env:
              SECRETS_FILE_CONTENTS: ${{ secrets.SECRETS_FILE_CONTENTS }}
          # … put your steps here
            run: flutter pub get
    

    编辑

    这也是在使用Firebase时隐藏google-services.json或签名密钥(key.jkskey.keystore)的相同过程。


    哎呀!看起来好像可以工作了。你能解释一下这个步骤在做什么吗?run: echo $SECRETS_FILE_CONTENT | base64 -d > lib/utils/secrets.dart 它是在创建一个带有内容的文件吗? - Mahesh Jamdade
    是的。该行将解码并将输出写入指定的文件路径。 - xamantra
    非常感谢,这是我见过的最简单和最安全的解决方案之一(据我所知)。我不确定为什么没有人提到这一点。无论如何,我想为这个好答案提供悬赏,我会等待两天。 - Mahesh Jamdade
    恭喜获得赏金。 - Mahesh Jamdade
    谢谢!我不得不使用以下命令: $SECRETS_FILE_CONTENT | base64 -di > lib/utils/secrets.dart 否则,base64 -d 会失败。返回的消息是:无效输入。 - Ghislain Viguier
    显示剩余7条评论

    32
    如果你使用的是环境密钥而不是仓库密钥,你应该定义你将使用的环境,看看这个。
    jobs:
      build:
        environment: **ENVIRONMENT NAME HERE**
    
        steps:
          - name: blah blah
            run: echo blah blah
    

    更新(2022-08-09)

    
    jobs:
        build:
        ...
        environment: Foo
        steps:
            - uses : actions/checkout@v3
            - name : Run some customized action
              env :
                a : ${{ secrets.Bar }}
                b : $ Mona  
                c : ${{ secrets.Lisa }}
              run : |
                echo $a 
                echo $b
                echo $c
    

    自从我回答以来,有很多更新,所以总结一下,现在GitHub有3个秘密

    1. 环境秘密
    2. 操作秘密(仓库秘密)
    3. Dependabot秘密

    Dependabot不在这个范围内。

    环境秘密包括:

    Settings -> Environments -> New Environments -> Environment Secrets
    

    行动秘密是:
    Settings -> Secrets -> Actions -> Repository Secrets
    

    所以,如果我们想要逻辑上访问环境的秘密值,我们需要知道两个任意变量:环境名称和环境秘密名称,例如:EnvironmentName.EnviromentSecretName.EnvironmentSecretValue 正如我所写的,FooEnvironmentNameBarEnvironmentSecretNameMona 是常量
    Lisa 是操作(存储库)秘密名称
    所以,如果我们将环境秘密设置为Mark,存储库秘密设置为Twain 控制台输出将是:
    Mark
    
    Mona
    
    Twain
    

    此外,GitHub将会用"***"来隐藏秘密值,你可以使用https://zellwk.com/blog/debug-github-actions-secret/这个URI来进行调试。

    你能更新运行命令以访问那些变量吗?${{ env.XXX } 似乎只引用我明确使用 env: .... 设置的那些变量。 - Tony
    你让我找到了正确的方向,谢谢。 - Stormsson

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接