github-actionssecret-key

Update a github repository secret from a github action


I have a website fetching the facebook events of one of my webpage thanks to a ruby script.

The script is executed within a github action before the build.

Unfortunately, the facebook token has a limited validity. I managed to find a way to renew it but I'm wondering if it is possible to update my FACEBOOK_TOKEN repository secret from a Github action ?

Of course I'm open to alternative like finding a way to have a permanent token!


Solution

  • With the actions/github-script@v6 action you can do this very easily through the actions API. You will also need a custom personal access token with the repo scope.

    jobs:
      update-token:
        env:
          GITHUB_TOKEN: ${{ secrets.GHPAT_TOKEN || github.token }}
        runs-on: ubuntu-latest
        steps:
          - uses: actions/setup-node@v3
            with:
              node-version: 20
          - run: |
              npm install --global sodium-native@4.0.4
              echo "NODE_PATH=$(npm root -g)" >> $GITHUB_ENV
          - name: Update FB Token
            uses: actions/github-script@v6
            env:
              FACEBOOK_TOKEN: ${{ 'REPLACE ME WITH TOKEN' }}
            with:
              result-encoding: string
              github-token: ${{ env.GITHUB_TOKEN }}
              script: |
                const sodium = require('sodium-native');
                const { data: {key: publicKey, key_id: keyId} } = await github.rest.actions.getRepoPublicKey({...context.repo});
                if (publicKey) {
                  const key = Buffer.from(publicKey, 'base64');
                  const message = Buffer.from(process.env.FACEBOOK_TOKEN);
                  const ciphertext = Buffer.alloc(message.length + sodium.crypto_box_SEALBYTES);
    
                  sodium.crypto_box_seal(ciphertext, message, key);
                  const encryptedToken = ciphertext.toString('base64');
    
                  await github.rest.actions.createOrUpdateRepoSecret({
                    ...context.repo, 
                    secret_name: 'FACEBOOK_TOKEN',
                    encrypted_value: encryptedToken,
                    key_id: keyId,
                  });
                } else {
                  core.error('Failed to fetch the public key. Unable to update secret');
                }
    

    See the docs on Encrypting secrets for the REST API.


    Note: In order to continue to have FACEBOOK_TOKEN be a secret, you might want to mask it's content either by using the ::add-mask::... command, or using core.setSecret('token content').