github actions can not find package.json - github

I'm trying to set-up some basic GitHub action to write comments on the PRs.
Action is published on github and looks like this:
action.yml file:
name: !!name!!
description: !!description!!
author: !!me!!
inputs:
token:
description: "Github token"
required: true
runs:
using: "node12"
main: "index.js"
index.js file:
const core = require("#actions/core");
const { execSync } = require("child_process");
const { GitHub, context } = require("#actions/github");
const main = async () => {
const repoName = context.repo.repo;
const repoOwner = context.repo.owner;
const token = core.getInput("token");
const testCommand = "yarn test --watchAll=false";
const prNumber = context.payload.number;
const githubClient = new GitHub(token);
const reportAsString = execSync(testCommand).toString();
const commentBody = `<div><h2>Test report</h2>
<p>
<pre>${reportAsString}</pre>
</p>
</div>`;
await githubClient.issues.createComment({
repo: repoName,
owner: repoOwner,
body: commentBody,
issue_number: prNumber,
});
};
main().catch((err) => core.setFailed(err.message));
In the project, I've added action through github, like this
.github/workflows/main.yml file:
on: [push]
jobs:
start_tests:
runs-on: ubuntu-latest
name: A test job
steps:
- name: !!name!!
uses: !!link to my action on github with version!!
with:
token: ${{ secrets.GITHUB_TOKEN }}
However, my PRs actions are failing and this is the reason:
error Couldn't find a package.json file in "/home/runner/work/!!project_name!!/!!project_name!!"
##[error]Command failed: yarn test --watchAll=false
error Couldn't find a package.json file in "/home/runner/work/!!project_name!!/!!project_name!!"
So, anyone has an idea what am I doing wrong here? I tried to google the solution but erm... unsuccessfully :(
Thanks for your time!

package.json file has to be present to run yarn test command. As we can see in error there is no such file just because there is no project folder at all. It means that job doesn't know anything about project to work with. So, you have to do one of the following changes:
in case your action is published to marketplace
on: [push]
jobs:
start_tests:
runs-on: ubuntu-latest
name: A test job
steps:
- uses: actions/checkout#v2.1.0
- name: !!name!!
uses: !!link to my action on github with version!!
with:
token: ${{ secrets.GITHUB_TOKEN }}
in case your action is not published yet or you just want to run it "locally"
on: [push]
jobs:
start_tests:
runs-on: ubuntu-latest
name: A test job
steps:
- name: !!name!!
uses: ./
with:
token: ${{ secrets.GITHUB_TOKEN }}

If you have a similar structure in your github repo, docker/build-push-action#v3 file and context properties should be set appropriately in your workflow file.

Related

How do I create a Github Action that will convert my markdown files into a single .json file

I am trying to create a Github Action that will take multiple markdown files and convert them into a single .json file. I tried the following and it did not work.
I used this found script.
// filename: buildJson.js
const fs = require("fs");
const path = require("path");
const matter = require("gray-matter");
const getAll = dir => {
// Read files at _posts/{directory}
const directory = path.join(process.cwd(), `content/${dir}`);
const fileNames = fs.readdirSync(directory);
// Get the content of the files as JSON
const content = fileNames.map((fileName, index) => {
const slug = fileName.replace(/\.md$/, "");
const fullPath = path.join(directory, fileName);
const fileContents = fs.readFileSync(fullPath, "utf8");
const matterResult = matter(fileContents);
return {
id: index + 1, slug, ...matterResult
};
});
// Return a big array of JSON
return JSON.stringify(content);
};
const allPosts = getAll("blog");
const postFileContents = `${allPosts}`;
// Create the cache folder if it doesn't exist
try {
fs.readdirSync("public/cache");
} catch (e) {
fs.mkdirSync("public/cache");
}
// Create our cached posts JSON
fs.writeFile("public/cache/posts.json", postFileContents, err => {
if (err) return console.log(err);
console.log("Posts cached.");
});
and this yml file in .github/workflows
name: create-json
on: [push]
jobs:
create-json:
runs-on: macos-latest
steps:
- uses: actions/checkout#v3
- uses: actions/setup-node#v3
with:
node-version: '18'
- run: npm install
- run: node buildJson.js
The script ran in Github Actions, it outputted the conole.log message I left myself, it did not create the .json file.

GitHub action: How to check if PR creator is part of a specific team?

I want to run a Github action that checks if the PR creator is a member of GitHub team "My cool Team" and if so do something.
I'm having trouble understanding how I can leverage the octokit team endpoint "Get team membership for a user" https://octokit.github.io/rest.js/v18#teams
The docs explain that the response for https://docs.github.com/en/rest/teams/members#get-team-membership-for-a-user
is
{
"url": "https://api.github.com/teams/1/memberships/octocat",
"role": "maintainer",
"state": "active"
}
if the user is in the team otherwise it returns 404 which i also don't know how to handle?
This is what I wrote:
on: pull_request_target
jobs:
my_job:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script#v6
with:
script: |
// If user is member of my_team team do nothing else do something
// See: https://octokit.github.io/rest.js/v18#teams
const creator = context.payload.sender.login
const opts = github.rest.teams.getMembershipForUserInOrg.endpoint.merge({
org: 'my_org',
team_slug: 'My cool Team',
username: ???? #How do I get the username of who opened the PR?
})
const response = await github.paginate(opts)
if (response.state <> "active") {
return
}
// User is not in the team continue to do something...
Any thoughts how I can do that?
From your code snippet
const creator = context.payload.sender.login
The creator variable is the username of who opened the PR. Also, await for the result of getMembershipForUserInOrg() could be enough for your need. Something like:
const creator = context.payload.sender.login
const result = await github.rest.teams.getMembershipForUserInOrg({
org: context.repo.owner,
team_slug: 'my-cool-team',
username: creator
})
console.log(creator, result) // do whatever you want

ReferenceError: TextEncoder is not defined in Github Actions Jest Script

I have an error that's only happening in my Github Actions workflow (when I run my Jest script locally, it's fine). I've only found this SO answer and this one but error still persists. Any thoughts on what to check next?
Here's the error:
> jest server/test/test --config=server/test/jest.config.js
FAIL server/test/test.js
● Test suite failed to run
ReferenceError: TextEncoder is not defined
at Object.<anonymous> (../../node_modules/mongodb-connection-string-url/node_modules/whatwg-url/dist/encoding.js:2:21)
at Object.<anonymous> (../../node_modules/mongodb-connection-string-url/node_modules/whatwg-url/dist/url-state-machine.js:5:34)
Here's my Jest config and script:
jest.config.js
module.exports = {
preset: '#shelf/jest-mongodb'
};
test.js
const dotenv = require('dotenv');
const path = require('path');
process.env = dotenv.config({path: path.resolve(__dirname, '.env')}).parsed;
const request = require('supertest');
const {app, server} = require('../server');
const { MongoClient } = require('mongodb');
const { TextEncoder } = require('util');
global.TextEncoder = TextEncoder;
describe('GET /', () => {
let mongoClient;
beforeAll(async () => {
app.locals.mongoClient = mongoClient = await MongoClient.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true });;
});
afterAll(async () => {
await mongoClient.close();
server.close();
});
it('responds with path of /', (done) => {
request(app).get('/').expect(JSON.stringify({path: '/'}), done);
});
});
My Github Actions workflow is erroring at the npm run test-server step:
name: cicd
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 10.x, 12.x, 14.x, 15.x ]
fail-fast: false
steps:
- uses: actions/checkout#v2
- name: Create environment variables
run: |
touch server/test/.env
echo MONGODB_URI=${{ secrets.QA_MONGODB_URI }} >> server/test/.env
- name: Node.js ${{ matrix.node-version }}
uses: actions/setup-node#v2
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present
- run: npm run test-server
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- uses: akhileshns/heroku-deploy#v3.12.12
with:
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
heroku_app_name: "my-app-name"
heroku_email: "my-email"
I had the same problem and a just inserted the two lines at the top
global.TextEncoder = require("util").TextEncoder;
global.TextDecoder = require("util").TextDecoder;
reference: ReferenceError: TextEncoder is not defined with mongodb nodes
global.TextEncoder = require("util").TextEncoder;
global.TextDecoder = require("util").TextDecoder;
import { MongoMemoryServer } from 'mongodb-memory-server';
import mongoose from 'mongoose';
let mongod: MongoMemoryServer;
beforeAll(async () => {
const mongod = await MongoMemoryServer.create();
const mongoUri = mongod.getUri();
await mongoose.connect(mongoUri);
});
beforeEach(async () => {
const collections = await mongoose.connection.db.collections();
for (let collection of collections) {
await collection.deleteMany({});
}
});
afterAll(async () => {
await mongod.stop(true);
await mongoose.connection.close();
});

GitHub Actions create or update a Git Tag

Each time I commit to a Pull Request branch I want to tag it like 0.0.0-pr1
The below action works on initial commit.
But not on subsequent commits I get Error: Unhandled error: HttpError: Reference already exists
Is there a create or update Ref API I could use?
env:
PR_NUMBER: ${{ github.event.number }}
steps:
- name: Create Git tag for PR
uses: actions/github-script#v4
with:
script: |
github.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: "refs/tags/0.0.0-pr${{env.PR_NUMBER}}",
sha: context.sha
})
You can simply use EndBug/latest-tag GitHub action from Marketplace that adds (or updates) your custom tag:
env:
PR_NUMBER: ${{ github.event.number }}
steps:
# make sure you checkout first
- name: "⏬ Check out repository code"
uses: actions/checkout#v3
- name: "🏷️ Push tag"
uses: EndBug/latest-tag#latest
with:
# You can change the name of the tag with this input.
# Default: 'latest'
tag-name: ${{env.PR_NUMBER}}
# If a description is provided, the action will use it to create an annotated tag. If none is given, the action will create a lightweight tag.
#description: Description for the tag
As you can see, I had an existent tag (2.0.0-41) which got overwritten
Here is a possible solution
jobs:
tag:
runs-on: ubuntu-latest
name: "Tag Releases"
steps:
- uses: actions/github-script#v2
env:
CLIENT_PAYLOAD: ${{ toJSON(github.event.client_payload) }}
with:
script: |
const { owner, repo } = context.repo;
const { sha, releases } = JSON.parse(process.env.CLIENT_PAYLOAD);
for (const release of releases) {
const tagName = `${release.module}/${release.newVersion}`;
let ref = `refs/tags/${tagName}`;
console.log('Tagging', tagName, 'as', sha);
await github.git.createRef({ owner, repo, ref, sha });
const releaseVersion = `${release.newVersion}`;
const module = `${release.module}`;
try {
ref = "tags/" + module + "/v" + releaseVersion.split(".")[0]
console.log('Updating existing tag', ref, 'as', sha);
await github.git.updateRef({ owner, repo, ref, sha });
}
catch {
ref = "refs/tags/" + module + "/v" + releaseVersion.split(".")[0]
console.log('Creating new tag', ref, 'as', sha);
await github.git.createRef({ owner, repo, ref, sha });
}
}
In this case I have a monorepo which contains several terraform modules and they are versioned as modulename/SemVer and also moduleName/MajorVersion
console output:
Tagging monorepo-release-template/1.0.1 as 42b.....
Updating existing tag tags/monorepo-release-template/v1 as 42b....
```

Deploy VuePress to GitHub pages

Trying to deploy this docs:
https://github.com/aitormendez/democracia/tree/master/docs
to GitHub page: https://aitormendez.github.io/democracia/
I get something different in local dev and Github.
This is the look in local dev:
And this is the look at GithHub:
Also, .vuepress/dist/index.html looks like:
this is the config.js:
https://github.com/aitormendez/democracia/blob/master/docs/.vuepress/config.js
module.exports = {
home: true,
title: 'Democracia. Manual de uso web',
base: '/democracia/',
themeConfig: {
nav: [
{text: 'Democracia', link: 'https://democracia.com.es'}
],
sidebar: [
{
title: 'Contenido',
collapsable: false,
children: [
'/',
'front-page',
]
},
]
}
}
package.json:
https://github.com/aitormendez/democracia/blob/master/package.json
{
"devDependencies": {
"vuepress": "^1.4.1"
},
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
And deploy.sh
#!/usr/bin/env sh
set -e
npm run docs:build
cd docs/.vuepress/dist
git init
git add -A
git commit -m 'deploy'
git push -f git#github.com:aitormendez/democracia.git master:gh-pages
cd -
AFAIK, I've followed the deploy to Github steps: https://vuepress.vuejs.org/guide/deploy.html#github-pages
What am I doing wrong?
Had a similar issue. You need to set the correct base in docs/.vuepress/config.js.
Let's say your repository is at https://github.com/[USERNAME]/[REPO], then you need to set base to "/[REPO]/". In other words when you go to Settings>Pages and you see a message: "Your site is published at https://xxxxxx77.github.io/xxxxxGuide/" - you need to set /xxxxxGuide/ as your base.
This is how my config.js looks like :
module.exports = {
title: 'xxxxx',
description: 'xxxxxx',
base: "/xxxxGuide/"
}
The github options were wrong. It was necessary to specify the gh-pages branch as source.