{"id":46697211,"url":"https://github.com/cfengine/cf-bottom","last_synced_at":"2026-03-09T05:33:25.955Z","repository":{"id":37899907,"uuid":"130238488","full_name":"cfengine/cf-bottom","owner":"cfengine","description":"__init__","archived":false,"fork":false,"pushed_at":"2025-06-13T14:59:22.000Z","size":372,"stargazers_count":3,"open_issues_count":2,"forks_count":13,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-13T15:51:34.928Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cfengine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-04-19T15:44:52.000Z","updated_at":"2025-06-13T14:59:27.000Z","dependencies_parsed_at":"2026-01-08T19:07:22.019Z","dependency_job_id":null,"html_url":"https://github.com/cfengine/cf-bottom","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cfengine/cf-bottom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfengine%2Fcf-bottom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfengine%2Fcf-bottom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfengine%2Fcf-bottom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfengine%2Fcf-bottom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cfengine","download_url":"https://codeload.github.com/cfengine/cf-bottom/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfengine%2Fcf-bottom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30283934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T02:57:19.223Z","status":"ssl_error","status_checked_at":"2026-03-09T02:56:26.373Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-09T05:33:24.452Z","updated_at":"2026-03-09T05:33:25.936Z","avatar_url":"https://github.com/cfengine.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Northern.tech Bot, Tom\n\nI'm your friendly neighbourhood bot, Tom.\nI trigger pull requests when someone mentions me in a GitHub Pull Request.\n\n## Usage\n\n### Github Pull Requests\n\nMention Tom in a comment with `@cf-bottom` and then include some trigger keywords to start a jenkins/CI build.\n\nIn `tom/bot.py`:\n\n```python\n        trigger_words = [\"jenkins\", \"pipeline\", \"build\", \"test\", \"trigger\"]\n```\n\nOther keywords available in comments are:\n\n* `exotic` - includes exotics platforms such as AIX, HP/UX, Solaris\n* `no test` - don't run tests. This is useful if you only need packages. Tests are resource intensive so use this option often if it makes sense.\n\n### Install dependencies and setup local venv\n\npython3 -m venv venv\n. venv/bin/activate\npip install -r requirements.txt\n\n### Command line\n\nIf you have valid config and secrets in the current working directory, you can run the PR checker feature with:\n\n```\n$ python3 -m tom --directory . --log-level info --interactive\n```\n\n(This assumes running in the repo folder, `.`, and interactive so you will be prompted before any actions are taken).\n\nExample on our (private) Jenkins:\n\n```\n$ ssh ci.cfengine.com\nolehermanse@jenkins:~$ sudo su tom\ntom@jenkins:/home/olehermanse$ cd ~/\ntom@jenkins:/home/tom$ python3 self/tom --log-level INFO\n[INFO] Fetching pull requests for cfengine/documentation\n[INFO] Fetching pull requests for cfengine/starter_pack\n[INFO] Fetching pull requests for cfengine/masterfiles\n[INFO] Fetching pull requests for cfengine/buildscripts\n[INFO] Fetching pull requests for cfengine/core\n[INFO] Fetching pull requests for cf-bottom/self\n[...]\n```\n\n### Update Dependencies\n\nInitially and currently tom is designed to chat via slack to update dependencies but we didn't finish the integration so this must be run on the command line instead.\nGiven that secrets are present as above, run this command:\n\n```\npython3 -m tom -i -t cf-bottom -l info\n\n\u003c@cf-bottom\u003e deps: 3.21.x\n```\n\nNote: in order to submit the PR properly you must edit tom/bot.py and replace Lex-2008 with your github username. https://northerntech.atlassian.net/browse/ENT-12126\n\nNote that this is referred to in the release process doc: https://github.com/NorthernTechHQ/infra/blob/master/files/buildcache/release-scripts/RELEASE_PROCESS.org\n\n### CFEngine policy\n\nSee the [example policy](/tom.cf) for an automated way to update and run Tom.\n\nTo enable tom, add the class `default:tom_enabled` via CMDB or augments.\n\nTo disable running for testing/debugging, create this flag file:\n\n```\n$ cd /home/tom\n$ touch TOM_DISABLED\n```\n\nThe `TOM_DISABLED` file is checked by the policy, not the python code.\n\nTo re-enable:\n\n```\n$ cd /home/tom\n$ rm -f TOM_DISABLED\n```\n\n## Config\n\nSee [our commited config file](/config.json) for an example of what the JSON config file looks like.\nNote that one config file has multiple \"bots\", with unique GitHub usernames.\nEach of those \"bots\" can be configured to use different Jenkins instances, and separate secrets.\n\n### Secrets\n\nSecrets should be kept separate from the rest of the config.\nThe filenames are specified in [`config.json`](/config.json).\nIt is generally recommended to not commit secrets to git repos.\nHere is an example of what the secrets file can look like:\n\n```\n{\n  \"GITHUB_TOKEN\": \"46fb3751dd0d84cb02f8d8fc68d34ffed3247c4b\",\n  \"JENKINS_USER\": \"a10062\",\n  \"JENKINS_TOKEN\": \"de351e7ad2bcb3b2bdca23c5537e054c\",\n  \"JENKINS_CRUMB\": \"814eeba4337de1f669643c1091aecb59\"\n}\n```\n\n(The secrets above are fake).\n\n**Explanation:**\n\n* `GITHUB_TOKEN` - API token generated by GitHub, for the bot username, specified in [`config.json`](/config.json).\n* `JENKINS_USER` - Jenkins username (LDAP username in CFEngine Jenkins).\n* `JENKINS_TOKEN` - API token, generated in Jenkins Settings UI.\n* `JENKINS_CRUMB` - [GET `https://\u003cjenkins\u003e/crumbIssuer/api/xml`](https://stackoverflow.com/questions/16738441/how-to-request-for-the-crumb-issuer-for-jenkins) (for CFEngine: https://ci.cfengine.com/crumbIssuer/api/xml).\n\n## Technical details\n\n### Webhooks / polling\n\nMost of the codebase works by polling open pull requests, rather than having a web server wait for Webhooks.\nThere is one exception, the optional slack bot, which can be triggered from mentions in Slack.\n\n### development / testing\n\nSee run_tests.sh here for a development workflow working with pytest unit tests.\n\nOpen htmlcov/index.html to see python code coverage information after test runs.\n\npass a test name to run_tests.sh and it will only run that one test.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfengine%2Fcf-bottom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcfengine%2Fcf-bottom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfengine%2Fcf-bottom/lists"}