工作流文件错误,未提供密码

Joh*_*ohn 3 ruby-on-rails github github-actions

我已经设置了一个 Github Action 来运行我的 Rails 应用程序的测试,但我一直收到这个错误:

Run bundle exec rails db:prepare
rails aborted!
PG::ConnectionBad: fe_sendauth: no password supplied
Run Code Online (Sandbox Code Playgroud)

这是工作流 yml 文件:

name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      db:
        image: postgres:11
        env:
          POSTGRES_USER: postgres
          POSTGRES_DB: bb_test
          POSTGRES_PASSWORD: postgres
        ports: ['5432:5432']
      redis:
        image: redis
        ports: ['6379:6379']
        options: --entrypoint redis-server

    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Install missing libs
        run: sudo apt-get -yqq install libpq-dev
      - name: Setup Ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6.x
      - name: Install gems
        run: |
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: 10.13.0
      - uses: borales/actions-yarn@v2.0.0
        with:
          cmd: install
      - name: Setup test database and run tests
        env:
          DATABASE_URL: postgres://postgres:@localhost:5432/bb_test
          REDIS_URL: redis://localhost:6379/0
          RAILS_ENV: test
          RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        run: |
          bundle exec rails db:prepare
          bundle exec rails test
Run Code Online (Sandbox Code Playgroud)

虽然问题似乎很明显,但看起来我已经提供了密码。那么我的 yml 文件有什么问题呢?

Dan*_*nyB 5

正如我们在评论讨论中发现的那样,这是由于database.yml没有提交到存储库的事实,因此导致 rails 不了解要使用哪个数据库,以及使用什么凭据。

我在这里发布这个答案的原因是分享我们如何致力于database.yml生产,同时仍然保持“不将机密提交给源代码控制”的必要安全准则。

由于所有 Rails 配置文件都支持 ERB,因此您可以使用它来使用环境变量定义机密。例如:

password: <%= ENV['POSTGRES_PASSWORD'] %>
Run Code Online (Sandbox Code Playgroud)

而且,为了完整起见,这是我们的database.yml- 它允许您使用单个DATABASE_URL变量简单地定义生产凭据,或者将环境变量留空,并且仍然具有用于开发和测试环境的合理默认值:

# config/database.yml
<%
  host = 'localhost'
  username = 'appname_user'
  password = 'dev_password_123'
  database = nil

  if ENV['DATABASE_URL']
    matches = ENV['DATABASE_URL'].match(/:\/\/(?<username>.+):(?<password>.+)@(?<host>.+)\/(?<database>.+)$/)
    if matches
      host     = matches[:host]
      username = matches[:username]
      password = matches[:password]
      database = matches[:database]
    end
  end
%>

pg: &default
  adapter: postgresql
  encoding: unicode
  host: <%= host %>
  pool: 5
  username: <%= username %>
  password: <%= password %>

development:
  <<: *default
  database: <%= database || 'appname_dev' %>

test: &test
  <<: *default
  database: <%= database || 'appname_test' %>

production:
  <<: *default
  database: <%= database || 'appname' %>
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,很好的解释! (2认同)