Compare commits

..

2 Commits

Author SHA1 Message Date
ea543a1353 docs(readme): update legacy readme message
add warning message at top of readme explaining the discontinuation of the legacy app
2025-05-31 03:48:57 -07:00
03025c13fd docs(readme): update with warning message 2025-05-31 03:47:04 -07:00
13801 changed files with 4116 additions and 185208 deletions

27
.all-contributorsrc Executable file → Normal file
View File

@@ -1,11 +1,9 @@
{
"projectName": "tvapp2",
"projectName": "thetvapp-docker",
"projectOwner": "Aetherinox",
"repoType": "github",
"repoHost": "https://github.com",
"files": [
"README.md"
],
"files": ["README.md"],
"imageSize": 40,
"commit": true,
"commitConvention": "angular",
@@ -14,22 +12,15 @@
"login": "Aetherinox",
"name": "Aetherinox",
"avatar_url": "https://avatars.githubusercontent.com/u/118329232?v=4",
"profile": "https://github.com/Aetherinox",
"contributions": ["code"]
"profile": "https://gitlab.com/Aetherinox",
"contributions": ["code", "projectManagement"]
},
{
"login": "iFlip721",
"name": "iFlip721",
"avatar_url": "https://avatars.githubusercontent.com/u/28721588?v=4",
"profile": "https://github.com/iFlip721",
"contributions": ["code"]
},
{
"login": "Optx",
"name": "Optx",
"avatar_url": "https://avatars.githubusercontent.com/u/32874812?v=4",
"profile": "https://github.com/Nvmdfth",
"contributions": ["code"]
"login": "dtankdempse",
"name": "dtankdempse",
"avatar_url": "https://avatars.githubusercontent.com/u/175421607?v=4",
"profile": "https://gitlab.com/dtankdempse",
"contributions": ["tools"]
}
],
"contributorsPerLine": 7,

6
.dockerignore Normal file
View File

@@ -0,0 +1,6 @@
.git
.gitignore
.github
.gitattributes
READMETEMPLATE.md
README.md

28
.editorconfig Executable file → Normal file
View File

@@ -1,21 +1,9 @@
# #
# @file .editorconfig
# @author Aetherinox
# @repo https://github.com/TheBinaryNinja/tvapp2
# https://git.binaryninja.net/Aetherinox
# @ref http://editorconfig.org
# #
# #
# Is top-most EditorConfig file
# #
# http://editorconfig.org
# is top-most EditorConfig file
root = true
# #
# All Files
# #
# All Files
[*]
indent_style = space
indent_size = 4
@@ -24,17 +12,11 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# #
# Markdown Files
# #
# Markdown Files
[*.md]
trim_trailing_whitespace = false
# #
# Other
# #
# Other
[{*.nsh,*.yml,*.yaml,*.json}]
indent_style = space
indent_size = 2

41
.gitattributes vendored Executable file → Normal file
View File

@@ -1,32 +1,17 @@
# #
# @file .gitattritutes
# @author Aetherinox https://github.com/Aetherinox
# https://git.binaryninja.net/Aetherinox
# #
# #
# Auto detect text files and set LF
# #
# Auto detect text files and perform LF normalization
* text=auto
# #
# Visual Studio
# #
# Custom for Visual Studio
*.cs diff=csharp
# #
# msysgit
# #
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

10
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
custom: ["https://buymeacoffee.com/aetherinox"]
github: # [repo-name, aetherinox]
patreon: # Replace with a single Patreon username
open_collective: # name
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username

View File

@@ -10,10 +10,8 @@ body:
value: |
1. Please speak `English`.
2. Make sure you are using the latest version and take a moment to check that your issue hasn't been reported before.
3. It's really important to provide pertinent details and logs, incomplete details will be handled as an invalid report.
4. Before creating this bug report, ensure you updated your applications to the latest versions.
Check your configurations to ensure there are no typos or errors.
Docker users should attempt to re-pull the TVApp2 image to ensure caching is not the cause of an issue.
3. It's really important to provide pertinent details and logs,
incomplete details will be handled as an invalid report.
<br />
@@ -41,12 +39,11 @@ body:
required: true
- type: input
id: version-tvapp2
id: version-thetvapp
attributes:
label: "Version - Tag"
description: |
Version / tag you are pulling for `TVApp2`.
You can view your build version in terminal by typing `docker inspect tvapp2 | grep BUILDVERSION`
Version / tag you are pulling for `thetvapp`
placeholder: "Ex: 1.0.0"
validations:
required: true
@@ -61,50 +58,15 @@ body:
required: true
- type: dropdown
id: image-registry
id: image-source
attributes:
label: Docker Image Registry
label: Docker Image Source
description: |
Select which docker image you are pulling from.
If you custom built your image, ensure it's not a problem with your code before submitting this bug report.
Select which docker image you are pulling from
options:
- "Dockerhub"
- "Gitea"
- "Github"
- "Manual Build"
validations:
required: true
- type: dropdown
id: app-parent
attributes:
label: Parent App
description: |
Select the application you are using TVApp2 with. Jellyfin, Plex, Emby, etc.
options:
- "Dim"
- "Emby"
- "Jellyfin"
- "KODI"
- "Plex"
- "Other (specify in description)"
validations:
required: true
- type: dropdown
id: app-proxy
attributes:
label: Proxy App
description: |
Select the plugin / app (if any) you are using as a m3u "Proxy" between your parent streaming app and TVApp2.
options:
- "❌ No Proxy"
- "Cabernet"
- "IPTVBoss"
- "IPTV-Solution"
- "Threadfin"
- "xTeVe"
- "Other (specify in description)"
- "Dockerhub"
- "Custom Built"
validations:
required: true
@@ -136,7 +98,7 @@ body:
label: Logs
description: |
Paste your docker logs here.
You can get your docker logs by opening terminal and running `docker logs tvapp2`
Paste logs from inside mounted volume `/config/log/*`
- type: textarea
id: screenshots

View File

@@ -1 +0,0 @@
blank_issues_enabled: true

View File

@@ -1,69 +0,0 @@
name: "🗺️ Roadmap"
description: Planned projects in the future to do. (⚠️ For contributors only)
title: "🗺️ Roadmap: <title>"
labels: [
"Type ◦ Roadmap"
]
body:
- type: markdown
attributes:
value: |
1. This issue type is different from feature requests.
2. This issue type is typically used by the developers of this repository to create and track new features
that have been planned in a future version of TVApp2.
3. Only use this issue type if you have been instructed to do so by a repository contributor.
4. Describe the benefits of this plan, and what needs to be taken into consideration during implementation.
5. Be detailed but to the point.
<br />
- type: input
id: roadmap-version-target
attributes:
label: Target Version
description: |
Which version are we aiming to introduce this into TVApp2?
placeholder: "v1.0.0"
validations:
required: true
- type: dropdown
id: roadmap-category
attributes:
label: Category
description: |
Select which aspect of TVApp2 this roadmap is designed for.
options:
- API
- Build Process
- CI (Continuous integration)
- Dependency / NodeJS Package
- Distribution
- Documentation
- M3U / EPG Functionality
- Repository
- S6-Overlay
default: 0
validations:
required: true
- type: textarea
id: roadmap-details
attributes:
label: Roadmap Details
description: |
Explain the vital steps in a bullet-point breakdown
placeholder: |
- Requires package update
- Must first integrate item A
validations:
required: true
- type: textarea
id: roadmap-screenshots
attributes:
label: 'Additional Info / Examples / Screenshots'
description: |
If available, provide mockups or examples.
Any further details you want to add.
Example snippets of code.

9
.github/PULL_REQUEST_TEMPLATE.md vendored Executable file → Normal file
View File

@@ -7,16 +7,15 @@
This text will remain hidden when you submit your pull request.
For your pull request title, use the format:
[BUG]: Brief title of the bug being fixed
[FEATURE]: Brief title of the feature being added
[DOCS]: Brief title of the feature being added
[BUG]: Brief title of the bug being fixed
[FEATURE]: Brief title of the feature being added
Failure to follow the above title format will result in your PR being ignored.
-->
# Pull Request
<small>Select which topic best describes your contribution:</small>
<small>Checkmark which topic best describes your contribution:</small>
- [ ] Feature
- [ ] Bug
@@ -44,7 +43,7 @@
### Before You Submit
<small>Please ensure you check the following items to indicate that you've read this section and completed each task</small>
- [ ] My code follows the [Contribution Guidelines](https://github.com/TheBinaryNinja/tvapp2/blob/main/CONTRIBUTING.md)
- [ ] My code follows the [Contribution Guidelines](https://github.com/Aetherinox/thetvapp-docker/blob/main/CONTRIBUTING.md)
- [ ] I give expressed consent for my work to be used in this repo
- [ ] I have tested my work and it functions as intended
- [ ] I have included documentation if the change requires such

0
.github/changelog-configuration.json vendored Executable file → Normal file
View File

2
.github/dependabot.yml vendored Executable file → Normal file
View File

@@ -1,7 +1,7 @@
# #
# MIT License
#
# Copyright (c) 2024-2025 Aetherinox
# Copyright (c) 2025 Aetherinox
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal

24
.github/labeler.yml vendored Executable file → Normal file
View File

@@ -1,27 +1,3 @@
# #
# MIT License
#
# Copyright (c) 2024-2025 Aetherinox
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# #
# Number of labels to fetch (optional). Defaults to 100
numLabels: 40
# These labels will not be used even if the issue contains them (optional).

264
.github/workflows/deploy-clean.yml vendored Executable file → Normal file
View File

@@ -1,91 +1,90 @@
# #
# @type github workflow
# @desc cleans up the list of deployments in the environment history
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage cleans up the list of deployments in the environment history
# edit the 'environment:' to determine which deployment to keep clean
# - can be ran manually
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_TOKEN org github personal access token (fine-grained)
# secrets.ORG_TOKEN_CL org github personal access token (classic)
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
#
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/deploy-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/deploy-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
# #
name: '🧹 Deployments Clean'
run-name: '🧹 Deployments Clean'
name: "⚙️ Deploy Clean"
run-name: "⚙️ Deploy Clean"
# #
# triggers
# #
on:
# #
# Trigger > Workflow Dispatch
# #
workflow_dispatch:
inputs:
# #
# Deployment Environment Name
#
# this is the name of the deployment item
# #
DEPLOYMENT_ENV:
description: '📦 Deployment Environment'
required: true
default: 'orion'
type: string
# #
# Delay
#
# Milliseconds to wait between cleaning up each action in history. Avoids secondary rate limit. Default: 500
# #
DEPLOYMENT_DELAY:
description: '🕛 Delete Delay'
required: true
default: '1000'
type: string
# #
# environment variables
# #
env:
DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }}
DEPLOYMENT_DELAY: ${{ github.event.inputs.DEPLOYMENT_DELAY || '1000' }}
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
BOT_NAME_1: AdminServ
BOT_NAME_2: AdminServX
BOT_NAME_3: EuropaServ
BOT_NAME_DEPENDABOT: dependabot[bot]
LABELS_JSON: |
[
{ "name": "AC Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
{ "name": "AC Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
{ "name": "AC Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
{ "name": "AC Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
{ "name": "AC Passed", "color": "146b4a", "description": "Ready to be reviewed" },
{ "name": "AC Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
{ "name": "AC Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
{ "name": "AC Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
{ "name": "Type ◦ Bug", "color": "9a2c2c", "description": "Something isn't working" },
{ "name": "Type ◦ Dependency", "color": "243759", "description": "Item is associated to dependency" },
{ "name": "Type ◦ Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
{ "name": "Type ◦ Feature", "color": "3c4e93", "description": "Feature request" },
{ "name": "Type ◦ Git Action", "color": "030406", "description": "GitHub Action / workflow" },
{ "name": "Type ◦ Pull Request", "color": "8F1784", "description": "Normal pull request" },
{ "name": "Type ◦ Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
{ "name": "Type ◦ Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
{ "name": "Build ◦ Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
{ "name": "Build ◦ Linux", "color": "c7ca4a", "description": "Specific to Linux" },
{ "name": "Build ◦ MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
{ "name": "Build ◦ Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
{ "name": "Build ◦ Web", "color": "c7ca4a", "description": "Specific to web" },
{ "name": "Build ◦ Windows", "color": "c7ca4a", "description": "Specific to Windows" },
{ "name": " API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
{ "name": " Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
{ "name": " Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
{ "name": " Customization", "color": "E3F0FC", "description": "Customizations: plugins, themes, configs" },
{ "name": " Design", "color": "FA70DE", "description": "Design related queries" },
{ "name": " Dist", "color": "FA70DE", "description": "Installers and other forms of software distribution" },
{ "name": " Enterprise", "color": "11447a", "description": "Issues about collaboration, administration, and so on" },
{ "name": " Hardware", "color": "5a7503", "description": "YubiKey, other tokens, biometrics" },
{ "name": " Import/Export", "color": "F5FFCC", "description": "Import from and export to different file formats" },
{ "name": " Improvement", "color": "185c98", "description": "Enhance an existing feature" },
{ "name": " Performance", "color": "006b75", "description": "Web and desktop performance issues" },
{ "name": " Plugin Request", "color": "FCE9CA", "description": "Requested changes should be implemented as a plugin" },
{ "name": " Security", "color": "F75D39", "description": "Security issues" },
{ "name": " Self-Hosting", "color": "fad8c7", "description": "Self-hosting installations and configs" },
{ "name": " Storage", "color": "5319e7", "description": "Storage providers: Dropbox, Google, WebDAV, etc." },
{ "name": " Updater", "color": "1BADDE", "description": "Auto-updater issues" },
{ "name": " UX", "color": "1BADDE", "description": "UX and usability" },
{ "name": " Website", "color": "fef2c0", "description": "Website related issues" },
{ "name": "⚠ Urgent", "color": "a8740e", "description": "Requires urgent attention" },
{ "name": "⚠ Announcement", "color": "DB4712", "description": "Announcements" },
{ "name": "📰 Progress Report", "color": "392297", "description": "Development updates" },
{ "name": "📦 Release", "color": "277542", "description": "Release announcements" },
{ "name": "✔️ Poll", "color": "972255", "description": "Community polls" },
{ "name": "❔ Question", "color": "FFFFFF", "description": "All questions" }
]
# #
# jobs
@@ -93,136 +92,15 @@ env:
jobs:
cleanup:
name: >-
🧹 Deployments Clean
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 5
runs-on: ubuntu-latest
permissions: write-all
steps:
# #
# Cleanup Set Env Variables
# #
- name: >-
🕛 Get Timestamp
id: task_cleanup_set_timestamp
run: |
echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# Release Github Checkout Arm64
# #
- name: >-
✅ Checkout
id: task_cleanup_gh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Cleanup Start
# #
- name: >-
⚙️ Deployments Clean
id: task_cleanup_start
uses: Aetherinox/delete-deploy-env-action@v3
with:
token: ${{ secrets.SELF_TOKEN_CL }}
environment: '${{ env.DEPLOYMENT_ENV }}'
environment: orion
onlyRemoveDeployments: true
delay: "${{ env.DEPLOYMENT_DELAY }}"
# #
# Cleanup Get Weekly Commits
# #
- name: >-
🕛 Get Weekly Commit List
id: task_cleanup_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Cleanup Notify Github Success
# #
- name: >-
🔔 Send Discord Webhook Message (Success)
id: task_cleanup_notify_discord_success
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 📦 Deployment Cleanup ${{ job.status == 'success' && '✅' || '❌' }}
A **successful** deployment cleanup was triggered on your repository. The history for this environment has been wiped
and will no longer list previous deployments you've made.
- Environment: `${{ env.DEPLOYMENT_ENV }}`
- Cleanup Delay: `${{ env.DEPLOYMENT_DELAY }}`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
# #
# Cleanup Notify Github Failure
# #
- name: >-
🔔 Send Discord Webhook Message (Failure)
id: task_cleanup_notify_discord_failure
uses: tsickert/discord-webhook@v7.0.0
if: failure()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 📦 Deployment Cleanup ${{ job.status == 'success' && '✅' || '❌' }}
A **failed** deployment cleanup was triggered on your repository. Since the action failed; no entries of your repo's
deployment history have been removed.
- Environment: `${{ env.DEPLOYMENT_ENV }}`
- Cleanup Delay: `${{ env.DEPLOYMENT_DELAY }}`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
delay: "1000"

File diff suppressed because it is too large Load Diff

View File

@@ -1,674 +0,0 @@
# #
# @type github workflow
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage deploys docker container to Dockerhub and send message to discord
# upload this workflow to both the `main` branch of the tvapp2 repository
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/deploy-docker-dockerhub.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/deploy-docker-dockerhub.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: "📦 Deploy Docker Dockerhub"
run-name: "📦 Deploy Docker Dockerhub"
# #
# Triggers
# #
on:
# #
# Trigger Workflow Dispatch
#
# If any values are not provided, will use fallback env variable
# #
workflow_dispatch:
inputs:
# #
# Image Name
#
# used in dockerhub image path
# ${{ env.IMAGE_DOCKERHUB_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_NAME:
description: '📦 Image Name'
required: true
default: 'tvapp2'
type: string
# #
# Image Version
#
# used to create new release tag, and add version to docker image name
# #
IMAGE_VERSION:
description: '🏷️ Image Version'
required: true
default: '1.0.0'
type: string
# #
# Dockerhub Author
#
# used in dockerhub image path
# hub.docker.com/r/${{ env.IMAGE_DOCKERHUB_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_DOCKERHUB_AUTHOR:
description: '🪪 Image Author'
required: true
default: 'TheBinaryNinja'
type: string
# #
# Dockerhub Username
#
# this is the user to sign into Dockerhub as.
# this username MUST be lowercase or you will get `unauthorized: incorrect username or password`
# #
IMAGE_DOCKERHUB_USERNAME:
description: '🪪 Dockerhub Username'
required: true
default: 'thebinaryninja'
type: string
# #
# true no changes to the repo will be made
# false workflow will behave normally, and push any changes detected to the files
# #
DRY_RUN:
description: '🐛 Dry Run (Debug)'
required: true
default: false
type: boolean
# #
# true released version will be marked as a development build and will have the v1.x.x-development tag instead of -latest
# false release version will be marked with -latest docker tag
# #
DEV_RELEASE:
description: '🧪 Development Release'
required: true
default: false
type: boolean
# #
# Trigger Push
# #
push:
tags:
- '*'
# #
# Environment Vars
# #
env:
IMAGE_NAME: ${{ github.event.inputs.IMAGE_NAME || 'tvapp2' }}
IMAGE_VERSION: ${{ github.event.inputs.IMAGE_VERSION || '1.0.0' }}
IMAGE_DOCKERHUB_AUTHOR: ${{ github.event.inputs.IMAGE_DOCKERHUB_AUTHOR || 'thebinaryninja' }}
IMAGE_DOCKERHUB_USERNAME: ${{ github.event.inputs.IMAGE_DOCKERHUB_USERNAME || 'thebinaryninja' }}
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
# #
# Jobs
#
# The way pushed docker containers on Dockerhub work, the most recent image built goes at the top.
# We will use the order below which builds the :latest image last so that it appears at the very
# top of the packages page.
# #
jobs:
# #
# Job Create Tag
# #
job-docker-release-tags-create:
name: >-
📦 Release Create Tag
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 4
permissions:
contents: write
packages: write
attestations: write
id-token: write
steps:
# #
# Release Tags Start
# #
- name: '🏳️ Start'
id: task_release_tags_start
run: |
echo "Creating Tag"
# #
# Release Tags Checkout
# #
- name: '✅ Checkout'
id: task_release_tags_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Tags Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_tags_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Tags Create Tag
#
# only called in dispatch mode
# #
- uses: rickstaa/action-create-tag@v1
id: task_release_tags_create
if: ( github.event_name != 'workflow_dispatch' && inputs.DRY_RUN == false )
with:
tag: "${{ env.IMAGE_VERSION }}"
tag_exists_error: false
message: '${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}'
gpg_private_key: ${{ secrets.ADMINSERV_GPG_KEY_ASC }}
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
# #
# Job Docker Release Dockerhub
# #
job-docker-release-dockerhub:
name: >-
📦 Release Dockerhub
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 10
permissions:
contents: write
packages: write
attestations: write
id-token: write
needs: [ job-docker-release-tags-create ]
steps:
# #
# Release Dockerhub Start Amd64
# #
- name: '🏳️ Start'
id: task_release_dh_start
run: |
echo "Starting Dockerhub docker release"
# #
# Release Dockerhub Checkout Amd64
# #
- name: '✅ Checkout'
id: task_release_gh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Dockerhub Get Timestamp
# #
- name: '🕛 Get Timestamp'
id: task_release_set_timestamp
run: |
echo "IMAGE_VERSION_1DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1`" >> ${GITHUB_ENV} # 1
echo "IMAGE_VERSION_2DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-2`" >> ${GITHUB_ENV} # 1.0
echo "REGISTRY_REPO_ORG_AUTHOR_LC=`echo ${{ env.IMAGE_DOCKERHUB_AUTHOR }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # thebinaryninja/tvapp2
echo "REGISTRY_REPO_AUTHOR_LC=`echo ${{ env.IMAGE_DOCKERHUB_AUTHOR }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # thebinaryninja
echo "DOCKER_SHA=${GITHUB_SHA}" >> $GITHUB_ENV # 71fad013cfce9116ec62779e4a7e627fe4c33627
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV # 02-25-2025 12:49:48
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV # 02-25-2025
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV # 02-25-2025 12:49
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV # 20250225
echo "NOW_DOCKER_TS=$(date -u +'%FT%T.%3NZ')" >> $GITHUB_ENV # 2025-02-25T12:50:11.569Z
# #
# Release Dockerhub Install Dependencies
# #
- name: '📦 Install Dependencies'
id: task_release_dh_dependencies
run:
sudo apt-get install -qq dos2unix
# #
# Release Dockerhub Execute dos2unix
# #
- name: '🔐 Apply dos2unix'
id: task_release_dh_dos2unix
run: |
echo "⚠️⚠️⚠️ Running DOS2UNIX ⚠️⚠️⚠️"
find ./ \( -path "./.git" -o -path "./docs" -o -path "./.github" -o -path "*.png" -o -path "*.jpg" \) -prune -o -name '*' -print | xargs dos2unix --
echo "✅✅✅ Completed DOS2UNIX ✅✅✅"
# #
# Release Dockerhub Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_dh_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Dockerhub QEMU Amd64
# #
- name: '⚙️ Set up QEMU'
id: task_release_dh_qemu
uses: docker/setup-qemu-action@v3
# #
# Release Dockerhub Setup BuildX Amd64
# #
- name: '⚙️ Setup Buildx'
id: task_release_dh_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:latest'
# #
# Release Dockerhub Registry Login Amd64
# #
- name: '⚙️ Login to Dockerhub'
id: task_release_dh_registry
uses: docker/login-action@v3
with:
username: ${{ env.IMAGE_DOCKERHUB_USERNAME }}
password: ${{ secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN }}
# #
# Release Dockerhub Read Readme
#
# @usage org.opencontainers.image.description=${{ steps.task_release_dh_readme_cache.outputs.content }}
# #
- name: '📄 Cache README.md'
id: task_release_dh_readme_cache
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ORG_BINARYNINJA_TOKEN_CL }}
script: |
'use strict'
const { promises: fs } = require('fs')
const main = async () => {
const path = "README.md"
let content = await fs.readFile(path, 'utf8')
core.setOutput('content', content)
}
main().catch(err => core.setFailed(err.message))
# #
# Release Dockerhub Meta
#
# this version of meta does not need one for amd64 and one for arm64 because both
# platforms are combined into one release, all sharing the same tags
# #
- name: '🔨 Dockerhub: Meta'
id: task_release_dh_meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
tags: |
# tag latest = yes ( no dev )
type=raw,value=latest,enable=${{ !inputs.DEV_RELEASE }}
# tag add pr tag ( PR or push only )
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=,event=tag
# tag add 1.0.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=450,prefix=,suffix=,value=${{ env.IMAGE_VERSION }}
# tag add 1.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=425,prefix=,suffix=,value=${{ env.IMAGE_VERSION_2DIGIT }}
# tag add 1 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=400,prefix=,suffix=,value=${{ env.IMAGE_VERSION_1DIGIT }}
# tag add development ( dispatch only + only dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=,value=development
# tag add development ( amd64 + only dev )
type=raw,enable=${{ inputs.DEV_RELEASE }},priority=400,prefix=,suffix=,value=development
flavor: |
latest=false
labels: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=dockerhub
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
annotations: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=dockerhub
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
# #
# Release Dockerhub Build and Push Amd64
# #
- name: '📦 Build & Push (linux/amd64)'
id: task_release_dh_push_amd64
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
labels: ${{ steps.task_release_dh_meta.outputs.labels }}
tags: |
${{ steps.task_release_dh_meta.outputs.tags }}
provenance: false
sbom: false
build-args: |-
ARCH=amd64
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
VERSION=${{ env.IMAGE_VERSION }}
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
# #
# Release Dockerhub Export Digest Amd64
# #
- name: '📄 Export Digest (linux/amd64)'
id: task_release_dh_digest_export_amd64
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
run: |
mkdir -p /tmp/build-digest-amd64
digest="${{ steps.task_release_dh_push_amd64.outputs.digest }}"
digest="${digest#sha256:}"
touch "/tmp/build-digest-amd64/$digest"
shell: bash
# #
# Release Dockerhub Upload Digest Amd64
# #
- name: '🔼 Upload Digest (linux/amd64)'
id: task_release_dh_digest_upload_amd64
uses: actions/upload-artifact@v4
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
name: digest-amd64
path: /tmp/build-digest-amd64/*
if-no-files-found: error
retention-days: 10
# #
# Release Dockerhub Build and Push Arm64
# #
- name: '📦 Build & Push (linux/arm64)'
id: task_release_dh_push_arm64
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile
platforms: linux/arm64
push: ${{ github.event_name != 'pull_request' }}
labels: ${{ steps.task_release_dh_meta.outputs.labels }}
tags: |
${{ steps.task_release_dh_meta.outputs.tags }}
provenance: false
sbom: false
build-args: |-
ARCH=arm64
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
VERSION=${{ env.IMAGE_VERSION }}
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
# #
# Release Dockerhub Export Digest Arm64
# #
- name: '📄 Export Digest (linux/arm64)'
id: task_release_dh_digest_export_arm64
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
run: |
mkdir -p /tmp/build-digest-arm64
digest="${{ steps.task_release_dh_push_arm64.outputs.digest }}"
digest="${digest#sha256:}"
touch "/tmp/build-digest-arm64/$digest"
shell: bash
# #
# Release Dockerhub Upload Digest Arm64
# #
- name: '🔼 Upload Digest (linux/arm64)'
id: task_release_dh_digest_upload_arm64
uses: actions/upload-artifact@v4
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
name: digest-arm64
path: /tmp/build-digest-arm64/*
if-no-files-found: error
retention-days: 10
# #
# Release Dockerhub Push Manifest
# #
- name: '📦 Push Manifest'
id: task_release_dh_manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ steps.task_release_dh_meta.outputs.tags }}
sources: |
${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_dh_push_amd64.outputs.digest }}
${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_dh_push_arm64.outputs.digest }}
index-annotations: |
${{ steps.task_release_dh_meta.outputs.labels }}
# #
# Release Dockerhub Checkpoint Amd64
# #
- name: '⚠️ Checkpoint'
id: task_release_dh_checkpoint
run: |
echo ""
echo "[ GITHUB ] ---------------------------------------------------------------------------------------------"
echo "github.actor.............................. ${{ github.actor }}"
echo "github.ref ............................... ${{ github.ref }}"
echo "github.ref_name .......................... ${{ github.ref_name }}"
echo "github.event_name ........................ ${{ github.event_name }}"
echo "github.repository_owner .................. ${{ github.repository_owner }}"
echo "github.repository ........................ ${{ github.repository }}"
echo ""
echo "[ INPUTS ] ---------------------------------------------------------------------------------------------"
echo "inputs.IMAGE_NAME ........................ ${{ inputs.IMAGE_NAME }}"
echo "inputs.IMAGE_VERSION ..................... ${{ inputs.IMAGE_VERSION }}"
echo "inputs.IMAGE_DOCKERHUB_AUTHOR ............ ${{ inputs.IMAGE_DOCKERHUB_AUTHOR }}"
echo "inputs.IMAGE_DOCKERHUB_USERNAME .......... ${{ inputs.IMAGE_DOCKERHUB_USERNAME }}"
echo "inputs.DEV_RELEASE ....................... ${{ inputs.DEV_RELEASE }}"
echo "inputs.DRY_RUN ........................... ${{ inputs.DRY_RUN }}"
echo ""
echo "[ ENV ] ------------------------------------------------------------------------------------------------"
echo "env.IMAGE_NAME ........................... ${{ env.IMAGE_NAME }}"
echo "env.IMAGE_VERSION ........................ ${{ env.IMAGE_VERSION }}"
echo "env.IMAGE_VERSION_1DIGIT ................. ${{ env.IMAGE_VERSION_1DIGIT }}"
echo "env.IMAGE_VERSION_2DIGIT ................. ${{ env.IMAGE_VERSION_2DIGIT }}"
echo "env.IMAGE_DOCKERHUB_AUTHOR ............... ${{ env.IMAGE_DOCKERHUB_AUTHOR }}"
echo "env.IMAGE_DOCKERHUB_USERNAME ............. ${{ env.IMAGE_DOCKERHUB_USERNAME }}"
echo "env.NOW .................................. ${{ env.NOW }}"
echo "env.NOW_SHORT ............................ ${{ env.NOW_SHORT }}"
echo "env.NOW_LONG ............................. ${{ env.NOW_LONG }}"
echo "env.NOW_DOCKER_LABEL ..................... ${{ env.NOW_DOCKER_LABEL }}"
echo "env.NOW_DOCKER_TS ........................ ${{ env.NOW_DOCKER_TS }}"
echo "env.REGISTRY_REPO_ORG_AUTHOR_LC .......... ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}"
echo "env.REGISTRY_REPO_AUTHOR_LC .............. ${{ env.REGISTRY_REPO_AUTHOR_LC }}"
echo "env.DOCKER_SHA ........................... ${{ env.DOCKER_SHA }}"
echo ""
echo "[ DOCKER IMAGES ] --------------------------------------------------------------------------------------"
echo "registry ................................. Dockerhub"
echo "tags ..................................... ${{ steps.task_release_dh_meta.outputs.tags }}"
echo "labels ................................... ${{ steps.task_release_dh_meta.outputs.labels }}"
echo "digest ................................... ${{ steps.task_release_dh_push_amd64.outputs.digest }}"
echo ""
echo "(release) tags ........................... ${{ steps.task_release_dh_meta.outputs.tags }}"
echo "(release) labels ......................... ${{ steps.task_release_dh_meta.outputs.labels }}"
echo ""
echo "[ DOCKER DIGESTS ] -------------------------------------------------------------------------------------"
echo "docker image id (amd64) .................. ${{ steps.task_release_dh_push_amd64.outputs.imageid }}"
echo "docker digest (amd64) .................... ${{ steps.task_release_dh_push_amd64.outputs.digest }}"
echo "docker image id (arm64) .................. ${{ steps.task_release_dh_push_arm64.outputs.imageid }}"
echo "docker digest (arm64) .................... ${{ steps.task_release_dh_push_arm64.outputs.digest }}"
# #
# Release Dockerhub Get Weekly Commits
# #
- name: '🕛 Get Weekly Commit List'
id: task_release_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Release Dockerhub Notify Github
# #
- name: '🔔 Send Discord Webhook Message'
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
### 📦 Deploy (Dockerhub) ${{ job.status == 'success' && '✅' || '❌' }} `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
${{ inputs.DEV_RELEASE == true && '### ⚠️⚠️ Development / Pre-release ⚠️⚠️' || '' }}
A new version of the docker container `${{ env.IMAGE_NAME }}` has been released from Github to Dockerhub. The image is available at:
- https://hub.docker.com/r/${{ env.IMAGE_DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}
- Version: `${{ env.IMAGE_VERSION }}`
- Release Type: `${{ inputs.DEV_RELEASE == true && '⚠️⚠️ Development / Pre-release ⚠️⚠️' || 'Stable' }}`
- Pull: `docker pull ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}:${{ inputs.DEV_RELEASE == true && 'development' || env.IMAGE_VERSION }}`
- Pull (amd64): `docker pull ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_dh_push_amd64.outputs.digest }}`
- Pull (arm64): `docker pull ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_dh_push_arm64.outputs.digest }}`
- Dry Run: `${{ inputs.DRY_RUN }}`
- Source: `Dockerhub` https://hub.docker.com/r/${{ env.IMAGE_DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}
- Docker Image: `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
- Branch: `${{ github.ref_name }}`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
### Tags
-# This docker image will use the following tags:
```
${{ steps.task_release_dh_meta.outputs.tags }}
```
### Labels
-# This docker image embeds the following labels:
```
${{ steps.task_release_dh_meta.outputs.labels }}
```
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"

View File

@@ -1,804 +0,0 @@
# #
# @type github workflow
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage deploys docker container to Gitea and send message to discord
# upload this workflow to both the `main` branch of the tvapp2 repository
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/deploy-docker-gitea.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/deploy-docker-gitea.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: "📦 Deploy Docker Gitea"
run-name: "📦 Deploy Docker Gitea"
# #
# Triggers
# #
on:
# #
# Trigger Workflow Dispatch
#
# If any values are not provided, will use fallback env variable
# #
workflow_dispatch:
inputs:
# #
# Image Name
#
# used in github image path
# git.binaryninja.net/${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_NAME:
description: '📦 Image Name'
required: true
default: 'tvapp2'
type: string
# #
# Image Version
#
# used to create new release tag, and add version to docker image name
# #
IMAGE_VERSION:
description: '🏷️ Image Version'
required: true
default: '1.0.0'
type: string
# #
# Gitea Author
#
# used in github image path
# git.binaryninja.net/${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_GITEA_AUTHOR:
description: '🪪 Image Author'
required: true
default: 'BinaryNinja'
type: string
# #
# Gitea Username
#
# this is the user to sign into gitea as.
# #
IMAGE_GITEA_USERNAME:
description: '🪪 Gitea Username'
required: true
default: 'aetherinox'
type: string
# #
# Gitea Website
#
# this is the gitea website / url to push to
# #
IMAGE_GITEA_WEBSITE:
description: '🌎 Gitea Website'
required: true
default: 'git.binaryninja.net'
type: string
# #
# true no changes to the repo will be made
# false workflow will behave normally, and push any changes detected to the files
# #
DRY_RUN:
description: '🐛 Dry Run (Debug)'
required: true
default: false
type: boolean
# #
# true released version will be marked as a development build and will have the v1.x.x-development tag instead of -latest
# false release version will be marked with -latest docker tag
# #
DEV_RELEASE:
description: '🧪 Development Release'
required: true
default: false
type: boolean
# #
# Trigger Push
# #
push:
tags:
- '*'
# #
# Environment Vars
# #
env:
IMAGE_NAME: ${{ github.event.inputs.IMAGE_NAME || 'tvapp2' }}
IMAGE_VERSION: ${{ github.event.inputs.IMAGE_VERSION || '1.0.0' }}
IMAGE_GITEA_AUTHOR: ${{ github.event.inputs.IMAGE_GITEA_AUTHOR || 'BinaryNinja' }}
IMAGE_GITEA_USERNAME: ${{ github.event.inputs.IMAGE_GITEA_USERNAME || 'BinaryNinja' }}
IMAGE_GITEA_WEBSITE: ${{ github.event.inputs.IMAGE_GITEA_WEBSITE || 'git.binaryninja.net' }}
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
# #
# Jobs
#
# The way pushed docker containers on Gitea work, the most recent image built goes at the top.
# We will use the order below which builds the :latest image last so that it appears at the very
# top of the packages page.
# #
jobs:
# #
# Job Create Tag
# #
job-docker-release-tags-create:
name: >-
📦 Release Create Tag
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 4
permissions:
contents: write
packages: write
attestations: write
id-token: write
steps:
# #
# Release Tags Start
# #
- name: '🏳️ Start'
id: task_release_tags_start
run: |
echo "Creating Tag"
# #
# Release Tags Checkout
# #
- name: '✅ Checkout'
id: task_release_tags_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Tags Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_tags_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Tags Create Tag
#
# only called in dispatch mode
# #
- uses: rickstaa/action-create-tag@v1
id: task_release_tags_create
if: ( github.event_name != 'workflow_dispatch' && inputs.DRY_RUN == false )
with:
tag: "${{ env.IMAGE_VERSION }}"
tag_exists_error: false
message: '${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}'
gpg_private_key: ${{ secrets.ADMINSERV_GPG_KEY_ASC }}
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
# #
# Job Docker Release Gitea
# #
job-docker-release-gitea:
name: >-
📦 Release Gitea
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 10
permissions:
contents: write
packages: write
attestations: write
id-token: write
needs: [ job-docker-release-tags-create ]
steps:
# #
# Release Gitea Start Amd64
# #
- name: '🏳️ Start'
id: task_release_gi_start
run: |
echo "Starting Gitea docker release"
# #
# Release Gitea Checkout
# #
- name: '✅ Checkout'
id: task_release_gh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Gitea Get Timestamp
# #
- name: '🕛 Get Timestamp'
id: task_release_set_timestamp
run: |
echo "IMAGE_VERSION_1DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1`" >> ${GITHUB_ENV} # 1
echo "IMAGE_VERSION_2DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-2`" >> ${GITHUB_ENV} # 1.0
echo "REGISTRY_REPO_ORG_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # thebinaryninja/tvapp2
echo "REGISTRY_REPO_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # thebinaryninja
echo "DOCKER_SHA=${GITHUB_SHA}" >> $GITHUB_ENV # 71fad013cfce9116ec62779e4a7e627fe4c33627
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV # 02-25-2025 12:49:48
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV # 02-25-2025
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV # 02-25-2025 12:49
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV # 20250225
echo "NOW_DOCKER_TS=$(date -u +'%FT%T.%3NZ')" >> $GITHUB_ENV # 2025-02-25T12:50:11.569Z
# #
# Release Gitea Install Dependencies
# #
- name: '📦 Install Dependencies'
id: task_release_gi_dependencies
run:
sudo apt-get install -qq dos2unix
# #
# Release Gitea Execute dos2unix
# #
- name: '🔐 Apply dos2unix'
id: task_release_gi_dos2unix
run: |
echo "⚠️⚠️⚠️ Running DOS2UNIX ⚠️⚠️⚠️"
find ./ \( -path "./.git" -o -path "./docs" -o -path "./.github" -o -path "*.png" -o -path "*.jpg" \) -prune -o -name '*' -print | xargs dos2unix --
echo "✅✅✅ Completed DOS2UNIX ✅✅✅"
# #
# Release Gitea Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_gi_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Gitea QEMU Amd64
# #
- name: '⚙️ Set up QEMU'
id: task_release_gi_qemu
uses: docker/setup-qemu-action@v3
# #
# Release Gitea Setup BuildX Amd64
# #
- name: '⚙️ Setup Buildx'
id: task_release_gi_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:latest'
# #
# Release Gitea Registry Login Amd64
# #
- name: '⚙️ Login to Gitea'
id: task_release_gi_registry
uses: docker/login-action@v3
with:
registry: ${{ env.IMAGE_GITEA_WEBSITE }}
username: ${{ env.IMAGE_GITEA_USERNAME }}
password: ${{ secrets.ORG_BINARYNINJA_GITEA_TOKEN }}
# #
# Release Gitea Read Readme
#
# @usage org.opencontainers.image.description=${{ steps.task_release_gi_readme_cache.outputs.content }}
# #
- name: '📄 Cache README.md'
id: task_release_gi_readme_cache
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ORG_BINARYNINJA_TOKEN_CL }}
script: |
'use strict'
const { promises: fs } = require('fs')
const main = async () => {
const path = "README.md"
let content = await fs.readFile(path, 'utf8')
core.setOutput('content', content)
}
main().catch(err => core.setFailed(err.message))
# #
# Release Gitea Meta amd64
#
# this version of meta needs one entry for amd64 and one for arm64 because each
# image needs to be uploaded manually, and then merged into a single platform.
# #
- name: '🔨 Gitea: Meta amd64'
id: task_release_gi_meta_amd64
uses: docker/metadata-action@v5
with:
images: |
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
tags: |
# tag latest = yes ( no dev )
type=raw,value=latest,enable=${{ !inputs.DEV_RELEASE }}
# tag add tag-amd64 ( PR or push only )
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=-amd64,event=tag
# tag add 1.0.0-amd64 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=500,prefix=,suffix=-amd64,value=${{ env.IMAGE_VERSION }}
# tag add 1.0.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=450,prefix=,suffix=,value=${{ env.IMAGE_VERSION }}
# tag add 1.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=425,prefix=,suffix=,value=${{ env.IMAGE_VERSION_2DIGIT }}
# tag add 1 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=400,prefix=,suffix=,value=${{ env.IMAGE_VERSION_1DIGIT }}
# dispatch add development-amd64 ( dispatch only + only dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=development-,suffix=,value=amd64
# tag add development ( amd64 + only dev )
type=raw,enable=${{ inputs.DEV_RELEASE }},priority=400,prefix=,suffix=,value=development
flavor: |
latest=false
labels: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=gitea
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
annotations: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=gitea
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
# #
# Release Gitea Meta arm64
#
# this version of meta needs one entry for amd64 and one for arm64 because each
# image needs to be uploaded manually, and then merged into a single platform.
# #
- name: '🔨 Gitea: Meta arm64'
id: task_release_gi_meta_arm64
uses: docker/metadata-action@v5
with:
images: |
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
tags: |
# tag latest = no
type=raw,value=latest,enable=false
# tag add tag-arm64
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=-arm64,event=tag
# tag add 1.0.0-arm64 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=500,prefix=,suffix=-arm64,value=${{ env.IMAGE_VERSION }}
# dispatch add development-arm64 ( dispatch only + only dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=-arm64,value=development
flavor: |
latest=false
labels: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=gitea
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
annotations: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=gitea
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
# #
# Release Gitea Meta Release
#
# this version of meta needs one entry for amd64 and one for arm64 because each
# image needs to be uploaded manually, and then merged into a single platform.
#
# this meta action is for the final image; which has both platforms merged and
# will be the final release.
# #
- name: '🔨 Gitea: Meta Release'
id: task_release_gi_meta_release
uses: docker/metadata-action@v5
with:
images: |
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
tags: |
# tag latest = yes ( no dev )
type=raw,value=latest,enable=${{ !inputs.DEV_RELEASE }}
# tag add pr tag ( PR or push only )
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=,event=tag
# tag add 1.0.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=450,prefix=,suffix=,value=${{ env.IMAGE_VERSION }}
# tag add 1.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=425,prefix=,suffix=,value=${{ env.IMAGE_VERSION_2DIGIT }}
# tag add 1 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=400,prefix=,suffix=,value=${{ env.IMAGE_VERSION_1DIGIT }}
# tag add development ( dispatch only + only dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=,value=development
# tag add development ( amd64 + only dev )
type=raw,enable=${{ inputs.DEV_RELEASE }},priority=400,prefix=,suffix=,value=development
flavor: |
latest=false
labels: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=gitea
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
annotations: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=gitea
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
# #
# Release Gitea Build and Push Amd64
# #
- name: '📦 Build & Push (linux/amd64)'
id: task_release_gi_push_amd64
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
labels: ${{ steps.task_release_gi_meta_amd64.outputs.labels }}
tags: |
${{ steps.task_release_gi_meta_amd64.outputs.tags }}
provenance: false
sbom: false
build-args: |-
ARCH=amd64
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
VERSION=${{ env.IMAGE_VERSION }}
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
# #
# Release Gitea Export Digest Amd64
# #
- name: '📄 Export Digest (linux/amd64)'
id: task_release_gi_digest_export_amd64
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
run: |
mkdir -p /tmp/build-digest-amd64
digest="${{ steps.task_release_gi_push_amd64.outputs.digest }}"
digest="${digest#sha256:}"
touch "/tmp/build-digest-amd64/$digest"
shell: bash
# #
# Release Gitea Upload Digest Amd64
# #
- name: '🔼 Upload Digest (linux/amd64)'
id: task_release_gi_digest_upload_amd64
uses: actions/upload-artifact@v4
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
name: digest-amd64
path: /tmp/build-digest-amd64/*
if-no-files-found: error
retention-days: 10
# #
# Release Gitea Build and Push Arm64
# #
- name: '📦 Build & Push (linux/arm64)'
id: task_release_gi_push_arm64
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile
platforms: linux/arm64
push: ${{ github.event_name != 'pull_request' }}
labels: ${{ steps.task_release_gi_meta_arm64.outputs.labels }}
tags: |
${{ steps.task_release_gi_meta_arm64.outputs.tags }}
provenance: false
sbom: false
build-args: |-
ARCH=arm64
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
VERSION=${{ env.IMAGE_VERSION }}
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
# #
# Release Gitea Export Digest Arm64
# #
- name: '📄 Export Digest (linux/arm64)'
id: task_release_gi_digest_export_arm64
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
run: |
mkdir -p /tmp/build-digest-arm64
digest="${{ steps.task_release_gi_push_arm64.outputs.digest }}"
digest="${digest#sha256:}"
touch "/tmp/build-digest-arm64/$digest"
shell: bash
# #
# Release Gitea Upload Digest Arm64
# #
- name: '🔼 Upload Digest (linux/arm64)'
id: task_release_gi_digest_upload_arm64
uses: actions/upload-artifact@v4
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
name: digest-arm64
path: /tmp/build-digest-arm64/*
if-no-files-found: error
retention-days: 10
# #
# Release Gitea Push Manifest
# #
- name: '📦 Push Manifest'
id: task_release_gi_manifest
uses: int128/docker-manifest-create-action@v2
with:
tags: |
${{ steps.task_release_gi_meta_release.outputs.tags }}
sources: |
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push_amd64.outputs.digest }}
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push_arm64.outputs.digest }}
index-annotations: |
${{ steps.task_release_gi_meta_release.outputs.labels }}
# #
# Release Gitea Checkpoint
# #
- name: '⚠️ Checkpoint'
id: task_release_gi_checkpoint
run: |
echo ""
echo "[ GITHUB ] ---------------------------------------------------------------------------------------------"
echo "github.actor.............................. ${{ github.actor }}"
echo "github.ref ............................... ${{ github.ref }}"
echo "github.ref_name .......................... ${{ github.ref_name }}"
echo "github.event_name ........................ ${{ github.event_name }}"
echo "github.repository_owner .................. ${{ github.repository_owner }}"
echo "github.repository ........................ ${{ github.repository }}"
echo ""
echo "[ INPUTS ] ---------------------------------------------------------------------------------------------"
echo "inputs.IMAGE_NAME ........................ ${{ inputs.IMAGE_NAME }}"
echo "inputs.IMAGE_VERSION ..................... ${{ inputs.IMAGE_VERSION }}"
echo "inputs.IMAGE_GITEA_USERNAME .............. ${{ inputs.IMAGE_GITEA_AUTHOR }}"
echo "inputs.IMAGE_GITEA_USERNAME .............. ${{ inputs.IMAGE_GITEA_USERNAME }}"
echo "inputs.IMAGE_GITEA_WEBSITE ............... ${{ inputs.IMAGE_GITEA_WEBSITE }}"
echo "inputs.DEV_RELEASE ....................... ${{ inputs.DEV_RELEASE }}"
echo "inputs.DRY_RUN ........................... ${{ inputs.DRY_RUN }}"
echo ""
echo "[ ENV ] ------------------------------------------------------------------------------------------------"
echo "env.IMAGE_NAME ........................... ${{ env.IMAGE_NAME }}"
echo "env.IMAGE_VERSION ........................ ${{ env.IMAGE_VERSION }}"
echo "env.IMAGE_VERSION_1DIGIT ................. ${{ env.IMAGE_VERSION_1DIGIT }}"
echo "env.IMAGE_VERSION_2DIGIT ................. ${{ env.IMAGE_VERSION_2DIGIT }}"
echo "env.IMAGE_GITEA_AUTHOR ................... ${{ env.IMAGE_GITEA_AUTHOR }}"
echo "env.IMAGE_GITEA_USERNAME ................. ${{ env.IMAGE_GITEA_USERNAME }}"
echo "env.IMAGE_GITEA_WEBSITE .................. ${{ env.IMAGE_GITEA_WEBSITE }}"
echo "env.NOW .................................. ${{ env.NOW }}"
echo "env.NOW_SHORT ............................ ${{ env.NOW_SHORT }}"
echo "env.NOW_LONG ............................. ${{ env.NOW_LONG }}"
echo "env.NOW_DOCKER_LABEL ..................... ${{ env.NOW_DOCKER_LABEL }}"
echo "env.NOW_DOCKER_TS ........................ ${{ env.NOW_DOCKER_TS }}"
echo "env.REGISTRY_REPO_ORG_AUTHOR_LC .......... ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}"
echo "env.REGISTRY_REPO_AUTHOR_LC .............. ${{ env.REGISTRY_REPO_AUTHOR_LC }}"
echo "env.DOCKER_SHA ........................... ${{ env.DOCKER_SHA }}"
echo ""
echo "[ DOCKER IMAGES ] --------------------------------------------------------------------------------------"
echo "registry ................................. Gitea"
echo "(amd64) tags ............................. ${{ steps.task_release_gi_meta_amd64.outputs.tags }}"
echo "(amd64) labels ........................... ${{ steps.task_release_gi_meta_amd64.outputs.labels }}"
echo "(amd64) digest ........................... ${{ steps.task_release_gi_push_amd64.outputs.digest }}"
echo ""
echo "(arm64) tags ............................. ${{ steps.task_release_gi_meta_arm64.outputs.tags }}"
echo "(arm64) labels ........................... ${{ steps.task_release_gi_meta_arm64.outputs.labels }}"
echo "(arm64) digest ........................... ${{ steps.task_release_gi_push_arm64.outputs.digest }}"
echo ""
echo "(release) tags ........................... ${{ steps.task_release_gi_meta_release.outputs.tags }}"
echo "(release) labels ......................... ${{ steps.task_release_gi_meta_release.outputs.labels }}"
echo ""
echo "[ DOCKER DIGESTS ] -------------------------------------------------------------------------------------"
echo "docker image id (amd64) .................. ${{ steps.task_release_gi_push_amd64.outputs.imageid }}"
echo "docker digest (amd64) .................... ${{ steps.task_release_gi_push_amd64.outputs.digest }}"
echo "docker image id (arm64) .................. ${{ steps.task_release_gi_push_arm64.outputs.imageid }}"
echo "docker digest (arm64) .................... ${{ steps.task_release_gi_push_arm64.outputs.digest }}"
# #
# Release Gitea Get Weekly Commits
# #
- name: '🕛 Get Weekly Commit List'
id: task_release_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Release Gitea Notify Gitea
# #
- name: '🔔 Send Discord Webhook Message'
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
### 📦 Deploy (Gitea) ${{ job.status == 'success' && '✅' || '❌' }} `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
${{ inputs.DEV_RELEASE == true && '### ⚠️⚠️ Development / Pre-release ⚠️⚠️' || '' }}
A new version of the docker container `${{ env.IMAGE_NAME }}` has been released from Github to Gitea. The image is available at:
- https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
- Version: `${{ env.IMAGE_VERSION }}`
- Release Type: `${{ inputs.DEV_RELEASE == true && '⚠️⚠️ Development / Pre-release ⚠️⚠️' || 'Stable' }}`
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}:${{ inputs.DEV_RELEASE == true && 'development' || env.IMAGE_VERSION }}`
- Pull (amd64): `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push_amd64.outputs.digest }}`
- Pull (arm64): `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push_arm64.outputs.digest }}`
- Dry Run: `${{ inputs.DRY_RUN }}`
- Source: `Gitea` https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
- Docker Image: `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
- Branch: `${{ github.ref_name }}`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
### Tags
-# This docker image will use the following tags:
```
${{ steps.task_release_gi_meta_amd64.outputs.tags }}
```
### Labels
-# This docker image embeds the following labels:
```
${{ steps.task_release_gi_meta_amd64.outputs.labels }}
```
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"

View File

@@ -1,783 +0,0 @@
# #
# @type github workflow
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage deploys docker container to Gitea.com and send message to discord
# upload this workflow to both the `main` branch of the tvapp2 repository
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/deploy-docker-giteacom.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/deploy-docker-giteacom.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: "📦 Deploy Docker Gitea.com"
run-name: "📦 Deploy Docker Gitea.com"
# #
# Triggers
# #
on:
# #
# Trigger Workflow Dispatch
#
# If any values are not provided, will use fallback env variable
# #
workflow_dispatch:
inputs:
# #
# Image Name
#
# used in github image path
# gitea.com/${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_NAME:
description: '📦 Image Name'
required: true
default: 'tvapp2'
type: string
# #
# Image Version
#
# used to create new release tag, and add version to docker image name
# #
IMAGE_VERSION:
description: '🏷️ Image Version'
required: true
default: '1.0.0'
type: string
# #
# Gitea Author
#
# used in github image path
# gitea.com/${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_GITEA_AUTHOR:
description: '🪪 Image Author'
required: true
default: 'BinaryNinja'
type: string
# #
# Gitea Username
#
# this is the user to sign into gitea as.
# #
IMAGE_GITEA_USERNAME:
description: '🪪 Gitea Username'
required: true
default: 'aetherinox'
type: string
# #
# Gitea Website
#
# this is the gitea website / url to push to
# #
IMAGE_GITEA_WEBSITE:
description: '🌎 Gitea Website'
required: true
default: 'gitea.com'
type: string
# #
# true no changes to the repo will be made
# false workflow will behave normally, and push any changes detected to the files
# #
DRY_RUN:
description: '🐛 Dry Run (Debug)'
required: true
default: false
type: boolean
# #
# true released version will be marked as a development build and will have the v1.x.x-development tag instead of -latest
# false release version will be marked with -latest docker tag
# #
DEV_RELEASE:
description: '🧪 Development Release'
required: true
default: false
type: boolean
# #
# Trigger Push
# #
push:
tags:
- '*'
# #
# Environment Vars
# #
env:
IMAGE_NAME: ${{ github.event.inputs.IMAGE_NAME || 'tvapp2' }}
IMAGE_VERSION: ${{ github.event.inputs.IMAGE_VERSION || '1.0.0' }}
IMAGE_GITEA_AUTHOR: ${{ github.event.inputs.IMAGE_GITEA_AUTHOR || 'BinaryNinja' }}
IMAGE_GITEA_USERNAME: ${{ github.event.inputs.IMAGE_GITEA_USERNAME || 'BinaryNinja' }}
IMAGE_GITEA_WEBSITE: ${{ github.event.inputs.IMAGE_GITEA_WEBSITE || 'gitea.com' }}
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
# #
# Jobs
#
# The way pushed docker containers on Gitea work, the most recent image built goes at the top.
# We will use the order below which builds the :latest image last so that it appears at the very
# top of the packages page.
# #
jobs:
# #
# Job Create Tag
# #
job-docker-release-tags-create:
name: >-
📦 Release Create Tag
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 4
permissions:
contents: write
packages: write
attestations: write
id-token: write
steps:
# #
# Release Tags Start
# #
- name: '🏳️ Start'
id: task_release_tags_start
run: |
echo "Generating Docker Image on ${{ env.IMAGE_GITEA_WEBSITE }}"
echo "Using original Gitea workflow without manifest"
# #
# Release Tags Checkout
# #
- name: '✅ Checkout'
id: task_release_tags_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Tags Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_tags_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Tags Create Tag
#
# only called in dispatch mode
# #
- uses: rickstaa/action-create-tag@v1
id: task_release_tags_create
if: ( github.event_name != 'workflow_dispatch' && inputs.DRY_RUN == false )
with:
tag: "${{ env.IMAGE_VERSION }}"
tag_exists_error: false
message: '${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}'
gpg_private_key: ${{ secrets.ADMINSERV_GPG_KEY_ASC }}
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
# #
# Job Docker Release Gitea Arm64
# #
job-docker-release-gitea-arm64:
name: >-
📦 Release Gitea Arm64
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 10
needs: [ job-docker-release-tags-create ]
permissions:
contents: write
packages: write
attestations: write
id-token: write
steps:
# #
# Release Gitea Start Arm64
# #
- name: '🏳️ Start'
id: task_release_gi_start
run: |
echo "Generating Docker Image on ${{ env.IMAGE_GITEA_WEBSITE }} arm64"
echo "Using original Gitea workflow without manifest"
# #
# Release Gitea Checkout Arm64
# #
- name: '✅ Checkout'
id: task_release_gh_checkout
uses: actions/checkout@v4
# #
# Release Gitea Get Timestamp
# #
- name: '🕛 Get Timestamp'
id: task_release_set_timestamp
run: |
echo "IMAGE_VERSION_1DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1`" >> ${GITHUB_ENV} # 1
echo "IMAGE_VERSION_2DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-2`" >> ${GITHUB_ENV} # 1.0
echo "REGISTRY_REPO_ORG_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja/tvapp2
echo "REGISTRY_REPO_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja
echo "DOCKER_SHA=${GITHUB_SHA}" >> $GITHUB_ENV # 71fad013cfce9116ec62779e4a7e627fe4c33627
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV # 02-25-2025 12:49:48
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV # 02-25-2025
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV # 02-25-2025 12:49
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV # 20250225
echo "NOW_DOCKER_TS=$(date -u +'%FT%T.%3NZ')" >> $GITHUB_ENV # 2025-02-25T12:50:11.569Z
# #
# Release Gitea Install Dependencies
# #
- name: '📦 Install Dependencies'
id: task_release_gi_dependencies
run:
sudo apt-get install -qq dos2unix
# #
# Release Gitea Execute dos2unix
# #
- name: '🔐 Apply dos2unix'
id: task_release_gi_dos2unix
run: |
echo "⚠️⚠️⚠️ Running DOS2UNIX ⚠️⚠️⚠️"
find ./ \( -path "./.git" -o -path "./docs" -o -path "./.github" -o -path "*.png" -o -path "*.jpg" \) -prune -o -name '*' -print | xargs dos2unix --
echo "✅✅✅ Completed DOS2UNIX ✅✅✅"
# #
# Release Gitea Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_gi_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Gitea QEMU Arm64
# #
- name: '⚙️ Set up QEMU'
id: task_release_gi_qemu
uses: docker/setup-qemu-action@v3
# #
# Release Gitea Setup BuildX Arm64
# #
- name: '⚙️ Setup Buildx'
id: task_release_gi_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:latest'
# #
# Release Gitea Registry Login Arm64
# #
- name: '⚙️ Login to Gitea'
id: task_release_gi_registry
uses: docker/login-action@v3
with:
registry: ${{ env.IMAGE_GITEA_WEBSITE }}
username: ${{ env.IMAGE_GITEA_USERNAME }}
password: ${{ secrets.ORG_BINARYNINJA_GITEACOM_TOKEN }}
# #
# Release Gitea Meta Arm64
# #
- name: '🔨 Gitea: Meta - Arm64'
id: task_release_gi_meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
tags: |
# latest no
type=raw,value=latest,enable=false
# tag add arm64
# type=raw,enable=true,priority=1000,value=arm64
# dispatch add x1.x.x-arm64
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=300,prefix=,suffix=-arm64,value=${{ env.IMAGE_VERSION }}
# dispatch add arm64-development
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=-arm64,value=development
# tag add tag-arm64
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=-arm64,event=tag
flavor: |
latest=false
labels: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
# #
# Release Gitea Build and Push Arm64
# #
- name: '📦 Build & Push (linux/arm64)'
id: task_release_gi_push
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile.aarch64
platforms: linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.task_release_gi_meta.outputs.tags }}
labels: ${{ steps.task_release_gi_meta.outputs.labels }}
provenance: false
# #
# Release Gitea Checkpoint Arm64
# #
- name: '⚠️ Checkpoint'
id: task_release_gi_checkpoint
run: |
echo "registry ................................. Gitea"
echo "github.actor.............................. ${{ github.actor }}"
echo "github.ref ............................... ${{ github.ref }}"
echo "github.ref_name .......................... ${{ github.ref_name }}"
echo "github.event_name ........................ ${{ github.event_name }}"
echo "github.repository_owner .................. ${{ github.repository_owner }}"
echo "github.repository ........................ ${{ github.repository }}"
echo "inputs.DRY_RUN ........................... ${{ inputs.DRY_RUN }}"
echo "env.AUTHOR ............................... ${{ env.REGISTRY_REPO_AUTHOR_LC }}"
echo "tags ..................................... ${{ steps.task_release_gi_meta.outputs.tags }}"
echo "labels ................................... ${{ steps.task_release_gi_meta.outputs.labels }}"
echo "docker image ............................. ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}"
echo "docker sha ............................... ${{ env.DOCKER_SHA }}"
echo "docker image id .......................... ${{ steps.task_release_gi_push.outputs.imageid }}"
echo "docker digest ............................ ${{ steps.task_release_gi_push.outputs.digest }}"
# #
# Release Gitea Get Weekly Commits
# #
- name: '🕛 Get Weekly Commit List'
id: task_release_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Release Gitea Notify Gitea
# #
- name: '🔔 Send Discord Webhook Message'
id: task_release_notifications_discord_send
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 📦 Docker Deploy (Gitea) ${{ job.status == 'success' && '✅' || '❌' }} `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
${{ inputs.DEV_RELEASE == true && '### ⚠️⚠️ Development / Pre-release ⚠️⚠️' || '' }}
A new version of the docker container `${{ env.IMAGE_NAME }}` has been released from Github to Gitea. The image is available at:
- https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
- Release Type: `${{ inputs.DEV_RELEASE == true && '⚠️⚠️ Development / Pre-release ⚠️⚠️' || 'Stable' }}`
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}:${{ inputs.DEV_RELEASE == true && 'development' || env.IMAGE_VERSION }}-arm64`
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push.outputs.digest }}`
- Dry Run: `${{ inputs.DRY_RUN }}`
- Source: `Gitea` https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
- Docker Image: `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
- Version: `${{ env.IMAGE_VERSION }}`
- Branch: `${{ github.ref_name }}`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
### Tags
-# This docker image will use the following tags:
```
${{ steps.task_release_gi_meta.outputs.tags }}
```
### Labels
-# This docker image embeds the following labels:
```
${{ steps.task_release_gi_meta.outputs.labels }}
```
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
# #
# Job Docker Release Gitea Amd64
# #
job-docker-release-gitea-amd64:
name: >-
📦 Release Gitea Amd64
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 10
permissions:
contents: write
packages: write
attestations: write
id-token: write
needs: [ job-docker-release-tags-create, job-docker-release-gitea-arm64 ]
steps:
# #
# Release Gitea Start Amd64
# #
- name: '🏳️ Start'
id: task_release_gi_start
run: |
echo "Generating Docker Image on ${{ env.IMAGE_GITEA_WEBSITE }} amd64"
echo "Using original Gitea workflow without manifest"
# #
# Release Gitea Checkout
# #
- name: '✅ Checkout'
id: task_release_gh_checkout
uses: actions/checkout@v4
# #
# Release Gitea Get Timestamp
# #
- name: '🕛 Get Timestamp'
id: task_release_set_timestamp
run: |
echo "IMAGE_VERSION_1DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1`" >> ${GITHUB_ENV} # 1
echo "IMAGE_VERSION_2DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-2`" >> ${GITHUB_ENV} # 1.0
echo "REGISTRY_REPO_ORG_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja/tvapp2
echo "REGISTRY_REPO_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja
echo "DOCKER_SHA=${GITHUB_SHA}" >> $GITHUB_ENV # 71fad013cfce9116ec62779e4a7e627fe4c33627
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV # 02-25-2025 12:49:48
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV # 02-25-2025
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV # 02-25-2025 12:49
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV # 20250225
echo "NOW_DOCKER_TS=$(date -u +'%FT%T.%3NZ')" >> $GITHUB_ENV # 2025-02-25T12:50:11.569Z
# #
# Release Gitea Install Dependencies
# #
- name: '📦 Install Dependencies'
id: task_release_gi_dependencies
run:
sudo apt-get install -qq dos2unix
# #
# Release Gitea Execute dos2unix
# #
- name: '🔐 Apply dos2unix'
id: task_release_gi_dos2unix
run: |
find ./ \( -path "./.git" -o -path "./docs" -o -path "./.github" -o -path "*.png" -o -path "*.jpg" \) -prune -o -name '*' -print | xargs dos2unix --
# #
# Release Gitea Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_gi_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Gitea QEMU Amd64
# #
- name: '⚙️ Set up QEMU'
id: task_release_gi_qemu
uses: docker/setup-qemu-action@v3
# #
# Release Gitea Setup BuildX Amd64
# #
- name: '⚙️ Setup Buildx'
id: task_release_gi_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:latest'
# #
# Release Gitea Registry Login Amd64
# #
- name: '⚙️ Login to Gitea'
id: task_release_gi_registry
uses: docker/login-action@v3
with:
registry: ${{ env.IMAGE_GITEA_WEBSITE }}
username: ${{ env.IMAGE_GITEA_USERNAME }}
password: ${{ secrets.ORG_BINARYNINJA_GITEACOM_TOKEN }}
# #
# Release Gitea Meta Amd64
# #
- name: '🔨 Gitea: Meta - Amd64'
id: task_release_gi_meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
tags: |
# latest yes
type=raw,value=latest,enable=${{ !inputs.DEV_RELEASE }}
# tag add amd64
# type=raw,enable=true,priority=1000,value=amd64
# dispatch add x1.x.x-amd64
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=300,prefix=,suffix=-amd64,value=${{ env.IMAGE_VERSION }}
# dispatch add amd64-development
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=-amd64,value=development
# tag add tag-amd64
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=-amd64,event=tag
# add development tag to default architecture (amd64)
type=raw,enable=${{ inputs.DEV_RELEASE }},priority=400,prefix=,suffix=,value=development
flavor: |
latest=false
labels: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
annotations: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
# #
# Release Gitea Build and Push Amd64
# #
- name: '📦 Build & Push (linux/amd64)'
id: task_release_gi_push
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.task_release_gi_meta.outputs.tags }}
labels: ${{ steps.task_release_gi_meta.outputs.labels }}
provenance: false
# #
# Release Gitea Checkpoint Amd64
# #
- name: '⚠️ Checkpoint'
id: task_release_gi_checkpoint
run: |
echo "registry ................................. Gitea"
echo "github.actor.............................. ${{ github.actor }}"
echo "github.ref ............................... ${{ github.ref }}"
echo "github.ref_name .......................... ${{ github.ref_name }}"
echo "github.event_name ........................ ${{ github.event_name }}"
echo "github.repository_owner .................. ${{ github.repository_owner }}"
echo "github.repository ........................ ${{ github.repository }}"
echo "inputs.DRY_RUN ........................... ${{ inputs.DRY_RUN }}"
echo "env.AUTHOR ............................... ${{ env.REGISTRY_REPO_AUTHOR_LC }}"
echo "tags ..................................... ${{ steps.task_release_gi_meta.outputs.tags }}"
echo "labels ................................... ${{ steps.task_release_gi_meta.outputs.labels }}"
echo "docker image ............................. ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}"
echo "docker sha ............................... ${{ env.DOCKER_SHA }}"
echo "docker image id .......................... ${{ steps.task_release_gi_push.outputs.imageid }}"
echo "docker digest ............................ ${{ steps.task_release_gi_push.outputs.digest }}"
# #
# Release Gitea Get Weekly Commits
# #
- name: '🕛 Get Weekly Commit List'
id: task_release_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Release Gitea Notify Gitea
# #
- name: '🔔 Send Discord Webhook Message'
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 📦 Docker Deploy (Gitea) ${{ job.status == 'success' && '✅' || '❌' }} `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
${{ inputs.DEV_RELEASE == true && '### ⚠️⚠️ Development / Pre-release ⚠️⚠️' || '' }}
A new version of the docker container `${{ env.IMAGE_NAME }}` has been released from Github to Gitea. The image is available at:
- https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
- Release Type: `${{ inputs.DEV_RELEASE == true && '⚠️⚠️ Development / Pre-release ⚠️⚠️' || 'Stable' }}`
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}:${{ inputs.DEV_RELEASE == true && 'development' || env.IMAGE_VERSION }}-amd64`
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push.outputs.digest }}`
- Dry Run: `${{ inputs.DRY_RUN }}`
- Source: `Gitea` https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
- Docker Image: `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
- Version: `${{ env.IMAGE_VERSION }}`
- Branch: `${{ github.ref_name }}`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
### Tags
-# This docker image will use the following tags:
```
${{ steps.task_release_gi_meta.outputs.tags }}
```
### Labels
-# This docker image embeds the following labels:
```
${{ steps.task_release_gi_meta.outputs.labels }}
```
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"

View File

@@ -1,736 +0,0 @@
# #
# @type github workflow
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage deploys docker container to github and send message to discord
# upload this workflow to both the `main` branch of the tvapp2 repository
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/deploy-docker-github.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/deploy-docker-github.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: "📦 Deploy Docker Github"
run-name: "📦 Deploy Docker Github"
# #
# Triggers
# #
on:
# #
# Trigger Workflow Dispatch
#
# If any values are not provided, will use fallback env variable
# #
workflow_dispatch:
inputs:
# #
# Image Name
#
# used in github image path
# ghcr.io/${{ env.IMAGE_GHCR_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_NAME:
description: '📦 Image Name'
required: true
default: 'tvapp2'
type: string
# #
# Image Version
#
# used to create new release tag, and add version to docker image name
# #
IMAGE_VERSION:
description: '🏷️ Image Version'
required: true
default: '1.0.0'
type: string
# #
# Image Author
#
# used in github image path
# ghcr.io/${{ env.IMAGE_GHCR_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
IMAGE_GHCR_AUTHOR:
description: '🪪 Image Author'
required: true
default: 'TheBinaryNinja'
type: string
# #
# Image ghcr username
#
# this is the user to sign into ghcr as.
# #
IMAGE_GHCR_USERNAME:
description: '🪪 ghcr.io Username'
required: true
default: 'TheBinaryNinja'
type: string
# #
# true no changes to the repo will be made
# false workflow will behave normally, and push any changes detected to the files
# #
DRY_RUN:
description: '🐛 Dry Run (Debug)'
required: true
default: false
type: boolean
# #
# true released version will be marked as a development build and will have the v1.x.x-development tag instead of -latest
# false release version will be marked with -latest docker tag
# #
DEV_RELEASE:
description: '🧪 Development Release'
required: true
default: false
type: boolean
# #
# Trigger Push
# #
push:
tags:
- '*'
# #
# Environment Vars
# #
env:
IMAGE_NAME: ${{ github.event.inputs.IMAGE_NAME || 'tvapp2' }}
IMAGE_VERSION: ${{ github.event.inputs.IMAGE_VERSION || '1.0.0' }}
IMAGE_GHCR_AUTHOR: ${{ github.event.inputs.IMAGE_GHCR_AUTHOR || 'BinaryNinja' }}
IMAGE_GHCR_USERNAME: ${{ github.event.inputs.IMAGE_GHCR_USERNAME || 'BinaryNinja' }}
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
# #
# Jobs
#
# The way pushed docker containers on Github work, the most recent image built goes at the top.
# We will use the order below which builds the :latest image last so that it appears at the very
# top of the packages page.
# #
jobs:
# #
# Job Create Tag
# #
job-docker-release-tags-create:
name: >-
📦 Release Create Tag
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 4
permissions:
contents: write
packages: write
attestations: write
id-token: write
steps:
# #
# Release Tags Start
# #
- name: '🏳️ Start'
id: task_release_tags_start
run: |
echo "Creating Tag"
# #
# Release Tags Checkout
# #
- name: '✅ Checkout'
id: task_release_tags_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Tags Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_tags_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Tags Create Tag
#
# only called in dispatch mode
# #
- uses: rickstaa/action-create-tag@v1
id: task_release_tags_create
if: ( github.event_name != 'workflow_dispatch' && inputs.DRY_RUN == false )
with:
tag: "${{ env.IMAGE_VERSION }}"
tag_exists_error: false
message: '${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}'
gpg_private_key: ${{ secrets.ADMINSERV_GPG_KEY_ASC }}
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
# #
# Job Docker Release Github
# #
job-docker-release-github:
name: >-
📦 Release Github
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 10
permissions:
contents: write
packages: write
attestations: write
id-token: write
needs: [ job-docker-release-tags-create ]
steps:
# #
# Release Github Start Amd64
# #
- name: '🏳️ Start'
id: task_release_gh_start
run: |
echo "Starting Github docker release"
# #
# Release Github Checkout Amd64
# #
- name: '✅ Checkout'
id: task_release_gh_checkout
uses: actions/checkout@v4
# #
# Release Github Get Timestamp
# #
- name: '🕛 Get Timestamp'
id: task_release_set_timestamp
run: |
echo "IMAGE_VERSION_1DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1`" >> ${GITHUB_ENV} # 1
echo "IMAGE_VERSION_2DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-2`" >> ${GITHUB_ENV} # 1.0
echo "REGISTRY_REPO_ORG_AUTHOR_LC=`echo ${{ env.IMAGE_GHCR_AUTHOR }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # thebinaryninja/tvapp2
echo "REGISTRY_REPO_AUTHOR_LC=`echo ${{ env.IMAGE_GHCR_AUTHOR }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # thebinaryninja
echo "DOCKER_SHA=${GITHUB_SHA}" >> $GITHUB_ENV # 71fad013cfce9116ec62779e4a7e627fe4c33627
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV # 02-25-2025 12:49:48
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV # 02-25-2025
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV # 02-25-2025 12:49
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV # 20250225
echo "NOW_DOCKER_TS=$(date -u +'%FT%T.%3NZ')" >> $GITHUB_ENV # 2025-02-25T12:50:11.569Z
# #
# Release Github Install Dependencies
# #
- name: '📦 Install Dependencies'
id: task_release_gh_dependencies
run:
sudo apt-get install -qq dos2unix
# #
# Release Github Execute dos2unix
# #
- name: '🔐 Apply dos2unix'
id: task_release_gh_dos2unix
run: |
echo "⚠️⚠️⚠️ Running DOS2UNIX ⚠️⚠️⚠️"
find ./ \( -path "./.git" -o -path "./docs" -o -path "./.github" -o -path "*.png" -o -path "*.jpg" \) -prune -o -name '*' -print | xargs dos2unix --
echo "✅✅✅ Completed DOS2UNIX ✅✅✅"
# #
# Release Github Fix Permissions
# #
- name: '#️⃣ Manage Permissions'
id: task_release_gh_permissions
run: |
find ./ -name 'run' -exec chmod 755 {} \;
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
if [ -n "${WRONG_PERM}" ]; then
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
for i in ${WRONG_PERM}; do
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
done
exit 1
else
echo "✅✅✅ Executable permissions are OK ✅✅✅"
fi
# #
# Release Github QEMU Amd64
# #
- name: '⚙️ Set up QEMU'
id: task_release_gh_qemu
uses: docker/setup-qemu-action@v3
# #
# Release Github Setup BuildX Amd64
# #
- name: '⚙️ Setup Buildx'
id: task_release_gh_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:latest'
# #
# Release Github Registry Login Amd64
# #
- name: '⚙️ Login to Github'
id: task_release_gh_registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ env.IMAGE_GHCR_USERNAME }}
password: ${{ secrets.ORG_BINARYNINJA_TOKEN_CL }}
# #
# Release Github Read Readme
#
# @usage org.opencontainers.image.description=${{ steps.task_release_gh_readme_cache.outputs.content }}
# #
- name: '📄 Cache README.md'
id: task_release_gh_readme_cache
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ORG_BINARYNINJA_TOKEN_CL }}
script: |
'use strict'
const { promises: fs } = require('fs')
const main = async () => {
const path = "README.md"
let content = await fs.readFile(path, 'utf8')
core.setOutput('content', content)
}
main().catch(err => core.setFailed(err.message))
# #
# Release Github Meta
#
# this version of meta does not need one for amd64 and one for arm64 because both
# platforms are combined into one release, all sharing the same tags
# #
- name: '🔨 Github: Meta'
id: task_release_gh_meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
tags: |
# tag latest = yes ( no dev )
type=raw,value=latest,enable=${{ !inputs.DEV_RELEASE }}
# tag add pr tag ( PR or push only )
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=,event=tag
# tag add 1.0.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=450,prefix=,suffix=,value=${{ env.IMAGE_VERSION }}
# tag add 1.0 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=425,prefix=,suffix=,value=${{ env.IMAGE_VERSION_2DIGIT }}
# tag add 1 ( dispatch only + no dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=400,prefix=,suffix=,value=${{ env.IMAGE_VERSION_1DIGIT }}
# tag add development ( dispatch only + only dev )
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=,value=development
# tag add development ( amd64 + only dev )
type=raw,enable=${{ inputs.DEV_RELEASE }},priority=400,prefix=,suffix=,value=development
flavor: |
latest=false
labels: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=github
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
annotations: |
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
org.opencontainers.image.licenses=MIT
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
org.opencontainers.image.ref.name=${{ github.ref_name }}
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
org.opencontainers.image.registry=github
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
# #
# Release Github Build and Push Amd64
# #
- name: '📦 Build & Push (linux/amd64)'
id: task_release_gh_push_amd64
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
allow: |
network.host
network: host
context: .
file: Dockerfile
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
labels: ${{ steps.task_release_gh_meta.outputs.labels }}
tags: |
${{ steps.task_release_gh_meta.outputs.tags }}
annotations: |
${{ steps.task_release_gh_meta.outputs.annotations }}
provenance: false
sbom: false
build-args: |-
ARCH=amd64
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
VERSION=${{ env.IMAGE_VERSION }}
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
# #
# Release Github Export Digest Amd64
# #
- name: '📄 Export Digest (linux/amd64)'
id: task_release_gh_digest_export_amd64
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
run: |
mkdir -p /tmp/build-digest-amd64
digest="${{ steps.task_release_gh_push_amd64.outputs.digest }}"
digest="${digest#sha256:}"
touch "/tmp/build-digest-amd64/$digest"
shell: bash
# #
# Release Github Upload Digest Amd64
# #
- name: '🔼 Upload Digest (linux/amd64)'
id: task_release_gh_digest_upload_amd64
uses: actions/upload-artifact@v4
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
name: digest-amd64
path: /tmp/build-digest-amd64/*
if-no-files-found: error
retention-days: 10
# #
# Release Github Build and Push Arm64
# #
- name: '📦 Build & Push (linux/arm64)'
id: task_release_gh_push_arm64
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
allow: |
network.host
network: host
context: .
file: Dockerfile
platforms: linux/arm64
push: ${{ github.event_name != 'pull_request' }}
labels: ${{ steps.task_release_gh_meta.outputs.labels }}
tags: |
${{ steps.task_release_gh_meta.outputs.tags }}
annotations: |
${{ steps.task_release_gh_meta.outputs.annotations }}
provenance: false
sbom: false
build-args: |-
ARCH=arm64
RELEASE=${{ inputs.DEV_RELEASE == true && 'development' || 'stable' }}
VERSION=${{ env.IMAGE_VERSION }}
BUILDDATE=${{ env.NOW_DOCKER_LABEL }}
# #
# Release Github Export Digest Arm64
# #
- name: '📄 Export Digest (linux/arm64)'
id: task_release_gh_digest_export_arm64
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
run: |
mkdir -p /tmp/build-digest-arm64
digest="${{ steps.task_release_gh_push_arm64.outputs.digest }}"
digest="${digest#sha256:}"
touch "/tmp/build-digest-arm64/$digest"
shell: bash
# #
# Release Github Upload Digest Arm64
# #
- name: '🔼 Upload Digest (linux/arm64)'
id: task_release_gh_digest_upload_arm64
uses: actions/upload-artifact@v4
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
with:
name: digest-arm64
path: /tmp/build-digest-arm64/*
if-no-files-found: error
retention-days: 10
# #
# Release Github Push Manifest
# #
- name: '📦 Push Manifest'
id: task_release_gh_manifest
uses: int128/docker-manifest-create-action@v2
with:
push: ${{ !inputs.DRY_RUN }}
tags: |
${{ steps.task_release_gh_meta.outputs.tags }}
sources: |
ghcr.io/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gh_push_amd64.outputs.digest }}
ghcr.io/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gh_push_arm64.outputs.digest }}
index-annotations: |
${{ steps.task_release_gh_meta.outputs.labels }}
# #
# Release Github Checkpoint
# #
- name: '⚠️ Checkpoint'
id: task_release_gh_checkpoint
run: |
echo ""
echo "[ GITHUB ] ---------------------------------------------------------------------------------------------"
echo "github.actor.............................. ${{ github.actor }}"
echo "github.ref ............................... ${{ github.ref }}"
echo "github.ref_name .......................... ${{ github.ref_name }}"
echo "github.event_name ........................ ${{ github.event_name }}"
echo "github.repository_owner .................. ${{ github.repository_owner }}"
echo "github.repository ........................ ${{ github.repository }}"
echo ""
echo "[ INPUTS ] ---------------------------------------------------------------------------------------------"
echo "inputs.IMAGE_NAME ........................ ${{ inputs.IMAGE_NAME }}"
echo "inputs.IMAGE_VERSION ..................... ${{ inputs.IMAGE_VERSION }}"
echo "inputs.IMAGE_GHCR_AUTHOR ................. ${{ inputs.IMAGE_GHCR_AUTHOR }}"
echo "inputs.IMAGE_GHCR_USERNAME ............... ${{ inputs.IMAGE_GHCR_USERNAME }}"
echo "inputs.DEV_RELEASE ....................... ${{ inputs.DEV_RELEASE }}"
echo "inputs.DRY_RUN ........................... ${{ inputs.DRY_RUN }}"
echo ""
echo "[ ENV ] ------------------------------------------------------------------------------------------------"
echo "env.IMAGE_NAME ........................... ${{ env.IMAGE_NAME }}"
echo "env.IMAGE_VERSION ........................ ${{ env.IMAGE_VERSION }}"
echo "env.IMAGE_VERSION_1DIGIT ................. ${{ env.IMAGE_VERSION_1DIGIT }}"
echo "env.IMAGE_VERSION_2DIGIT ................. ${{ env.IMAGE_VERSION_2DIGIT }}"
echo "env.IMAGE_GHCR_AUTHOR .................... ${{ env.IMAGE_GHCR_AUTHOR }}"
echo "env.IMAGE_GHCR_USERNAME .................. ${{ env.IMAGE_GHCR_USERNAME }}"
echo "env.NOW .................................. ${{ env.NOW }}"
echo "env.NOW_SHORT ............................ ${{ env.NOW_SHORT }}"
echo "env.NOW_LONG ............................. ${{ env.NOW_LONG }}"
echo "env.NOW_DOCKER_LABEL ..................... ${{ env.NOW_DOCKER_LABEL }}"
echo "env.NOW_DOCKER_TS ........................ ${{ env.NOW_DOCKER_TS }}"
echo "env.DOCKER_IMAGE ......................... ${{ env.DOCKER_IMAGE }}"
echo "env.REGISTRY_REPO_ORG_AUTHOR_LC .......... ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}"
echo "env.REGISTRY_REPO_AUTHOR_LC .............. ${{ env.REGISTRY_REPO_AUTHOR_LC }}"
echo "env.DOCKER_SHA ........................... ${{ env.DOCKER_SHA }}"
echo ""
echo "[ DOCKER IMAGES ] --------------------------------------------------------------------------------------"
echo "registry ................................. Github GHCR"
echo "tags ..................................... ${{ steps.task_release_gh_meta.outputs.tags }}"
echo "labels ................................... ${{ steps.task_release_gh_meta.outputs.labels }}"
echo "digest ................................... ${{ steps.task_release_gh_push_amd64.outputs.digest }}"
echo ""
echo "(release) tags ........................... ${{ steps.task_release_gh_meta.outputs.tags }}"
echo "(release) labels ......................... ${{ steps.task_release_gh_meta.outputs.labels }}"
echo ""
echo "[ DOCKER DIGESTS ] -------------------------------------------------------------------------------------"
echo "docker image id (amd64) .................. ${{ steps.task_release_gh_push_amd64.outputs.imageid }}"
echo "docker digest (amd64) .................... ${{ steps.task_release_gh_push_amd64.outputs.digest }}"
echo "docker image id (arm64) .................. ${{ steps.task_release_gh_push_arm64.outputs.imageid }}"
echo "docker digest (arm64) .................... ${{ steps.task_release_gh_push_arm64.outputs.digest }}"
# #
# Release Github Get Weekly Commits
# #
- name: '🕛 Get Weekly Commit List'
id: task_release_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Release Github Notify Github
# #
- name: '🔔 Send Discord Webhook Message'
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
### 📦 Deploy (Github) ${{ job.status == 'success' && '✅' || '❌' }} `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
${{ inputs.DEV_RELEASE == true && '### ⚠️⚠️ Development / Pre-release ⚠️⚠️' || '' }}
A new version of the docker container `${{ env.IMAGE_NAME }}` has been released from Github to Github GHCR. The image is available at:
- https://github.com/${{ github.repository }}/pkgs/container/${{ env.IMAGE_NAME }}
- Version: `${{ env.IMAGE_VERSION }}`
- Release Type: `${{ inputs.DEV_RELEASE == true && '⚠️⚠️ Development / Pre-release ⚠️⚠️' || 'Stable' }}`
- Pull: `docker pull ghcr.io/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}:${{ inputs.DEV_RELEASE == true && 'development' || env.IMAGE_VERSION }}`
- Pull (amd64): `docker pull ghcr.io/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gh_push_amd64.outputs.digest }}`
- Pull (arm64): `docker pull ghcr.io/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gh_push_arm64.outputs.digest }}`
- Dry Run: `${{ inputs.DRY_RUN }}`
- Source: `Github` https://github.com/${{ github.repository }}
- Docker Image: `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
- Branch: `${{ github.ref_name }}`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
### Tags
-# This docker image will use the following tags:
```
${{ steps.task_release_gh_meta.outputs.tags }}
```
### Labels
-# This docker image embeds the following labels:
```
${{ steps.task_release_gh_meta.outputs.labels }}
```
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
# #
# Job Docker Release Cleanup
# #
job-docker-release-cleanup:
name: >-
🧹 Release Cleanup
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 5
permissions:
contents: write
packages: write
attestations: write
id-token: write
needs: [ job-docker-release-tags-create, job-docker-release-github ]
steps:
# #
# Release Cleanup
# #
- name: '🏳️ Start'
id: task_cleanup_gh_start
run: |
echo "Cleaning up untagged docker images"
# #
# Release Cleanup Checkout
# #
- name: '✅ Checkout'
id: task_cleanup_gh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Cleanup Clean Untagged Images
# #
- name: '🧹 Clean Untagged Images'
id: task_cleanup_clean
uses: quartx-analytics/ghcr-cleaner@v1
with:
owner-type: org
token: ${{ secrets.ORG_BINARYNINJA_TOKEN_CL }}
repository-owner: ${{ github.repository_owner }}
repository-name: ${{ github.repository }}
delete-untagged: true
# keep-at-most: 0

516
.github/workflows/deploy-docker.yml vendored Normal file
View File

@@ -0,0 +1,516 @@
# #
# @type github workflow
# @desc deploys docker container
# @author Aetherinox
# @url https://github.com/Aetherinox
# #
name: "⚙️ Deploy Docker Main"
run-name: "⚙️ Deploy Docker Main"
# #
# triggers
# #
on:
# #
# Trigger > Workflow Dispatch
# #
workflow_dispatch:
inputs:
IMAGE_NAME:
description: "📦 Image Name"
required: true
default: 'thetvapp-docker'
type: string
IMAGE_AUTHOR:
description: "📦 Image Author"
required: true
default: 'aetherinox'
type: string
# #
# true: runs all actions, even ones not scheduled
# false: only scheduled tasks will run
# #
PRINT_ONLY:
description: "📑 Print Debugs Only"
required: true
default: false
type: boolean
# #
# Trigger > Push
# #
push:
tags:
- '*'
# #
# environment variables
# #
env:
IMAGE_NAME: alpine-base
IMAGE_AUTHOR: Aetherinox
BOT_NAME_1: EuropaServ
BOT_NAME_DEPENDABOT: dependabot[bot]
# #
# jobs
#
# The way pushed docker containers on Github work, the most recent image built goes at the top.
# We will use the order below which builds the :latest image last so that it appears at the very
# top of the packages page.
# #
jobs:
# #
# Job > Docker Release > Github
# #
job-docker-release-github-php:
name: >-
📦 Release Github PHP
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
# #
# Release > Github > Start
# #
- name: "✅ Start"
id: task_release_gh_start
run: |
echo "Starting Github docker release for image PHP"
# #
# Release > Github > Checkout
# #
- name: "☑️ Checkout"
id: task_release_gh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release > Github > QEMU
# #
- name: "⚙️ Set up QEMU"
id: task_release_gh_qemu
uses: docker/setup-qemu-action@v3
# #
# Release > Github > Setup BuildX
# #
- name: "⚙️ Setup Buildx"
id: task_release_gh_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:v0.10.5'
# #
# Release > Github > Registry Login
# #
- name: "⚙️ Login to Github"
id: task_release_gh_registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.SELF_TOKEN_CL }}
# #
# Release > Github > Meta
# #
- name: "🔨 Docker meta"
id: task_release_gh_meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ inputs.IMAGE_AUTHOR || env.IMAGE_AUTHOR }}/docker-${{ inputs.IMAGE_NAME || env.IMAGE_NAME }}
tags: |
type=ref,enable=true,priority=600,prefix=,suffix=-php,event=tag
flavor: |
latest=false
# #
# Release > Github > Debug
# #
- name: "🪪 Debug Print"
id: task_release_gh_print
run: |
echo "registry ............. Github"
echo "github.actor.......... ${{ github.actor }}"
echo "github.ref ........... ${{ github.ref }}"
echo "github.event_name .... ${{ github.event_name }}"
echo "tags ................. ${{ steps.task_release_gh_meta.outputs.tags }}"
echo "labels ............... ${{ steps.task_release_gh_meta.outputs.labels }}"
# #
# Release > Github > Build and Push
# #
- name: "📦 Build and push"
id: task_release_gh_push
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.PRINT_ONLY == 'false' ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile-php.template
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.task_release_gh_meta.outputs.tags }}
labels: ${{ steps.task_release_gh_meta.outputs.labels }}
# #
# Job > Docker Release > Github
# #
job-docker-release-dockerhub-php:
name: >-
📦 Release Dockerhub PHP
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
# #
# Release > Dockerhub > Start
# #
- name: "✅ Start"
id: task_release_dh_start
run: |
echo "Starting Dockerhub Release"
# #
# Release > Dockerhub > Checkout
# #
- name: "☑️ Checkout"
id: task_release_dh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release > Dockerhub > QEMU
# #
- name: "⚙️ Set up QEMU"
id: task_release_dh_qemu
uses: docker/setup-qemu-action@v3
# #
# Release > Dockerhub > Setup BuildX
# #
- name: "⚙️ Setup Buildx"
id: task_release_dh_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:v0.10.5'
# #
# Release > Dockerhub > Registry Login
# #
- name: "⚙️ Login to DockerHub"
id: task_release_dh_registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ inputs.IMAGE_AUTHOR || env.IMAGE_AUTHOR }}
password: ${{ secrets.SELF_DOCKERHUB_TOKEN }}
# #
# Release > Dockerhub > Meta
# #
- name: "🔨 Docker meta"
id: task_release_dh_meta
uses: docker/metadata-action@v5
with:
images: |
${{ inputs.IMAGE_AUTHOR || env.IMAGE_AUTHOR }}/${{ inputs.IMAGE_NAME || env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable=false
type=ref,enable=true,priority=600,prefix=,suffix=-php,event=tag
flavor: |
latest=false
# #
# Release > Dockerhub > Debug
# #
- name: "🪪 Debug Print"
id: task_release_dh_print
run: |
echo "registry ............. Dockerhub"
echo "github.actor.......... ${{ github.actor }}"
echo "github.ref ........... ${{ github.ref }}"
echo "github.event_name .... ${{ github.event_name }}"
echo "tags ................. ${{ steps.task_release_dh_meta.outputs.tags }}"
echo "labels ............... ${{ steps.task_release_dh_meta.outputs.labels }}"
# #
# Release > Dockerhub > Build and Push
# #
- name: "📦 Build and push"
id: task_release_dh_push
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.PRINT_ONLY == 'false' ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile-php.template
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.task_release_dh_meta.outputs.tags }}
labels: ${{ steps.task_release_dh_meta.outputs.labels }}
# #
# Job > Docker Release > Github
# #
job-docker-release-github-main:
name: >-
📦 Release Github Main
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
needs: [ job-docker-release-github-php, job-docker-release-dockerhub-php ]
steps:
# #
# Release > Github > Start
# #
- name: "✅ Start"
id: task_release_gh_start
run: |
echo "Starting Github docker release"
# #
# Release > Github > Checkout
# #
- name: "☑️ Checkout"
id: task_release_gh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release > Github > QEMU
# #
- name: "⚙️ Set up QEMU"
id: task_release_gh_qemu
uses: docker/setup-qemu-action@v3
# #
# Release > Github > Setup BuildX
# #
- name: "⚙️ Setup Buildx"
id: task_release_gh_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:v0.10.5'
# #
# Release > Github > Registry Login
# #
- name: "⚙️ Login to Github"
id: task_release_gh_registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.SELF_TOKEN_CL }}
# #
# Release > Github > Meta
# #
- name: "🔨 Docker meta"
id: task_release_gh_meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ inputs.IMAGE_AUTHOR || env.IMAGE_AUTHOR }}/docker-${{ inputs.IMAGE_NAME || env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable=${{ endsWith(github.ref, 'main') }}
type=ref,event=tag
# #
# Release > Github > Debug
# #
- name: "🪪 Debug Print"
id: task_release_gh_print
run: |
echo "registry ............. Github"
echo "github.actor.......... ${{ github.actor }}"
echo "github.ref ........... ${{ github.ref }}"
echo "github.event_name .... ${{ github.event_name }}"
echo "tags ................. ${{ steps.task_release_gh_meta.outputs.tags }}"
echo "labels ............... ${{ steps.task_release_gh_meta.outputs.labels }}"
# #
# Release > Github > Build and Push
# #
- name: "📦 Build and push"
id: task_release_gh_push
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.PRINT_ONLY == 'false' ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.task_release_gh_meta.outputs.tags }}
labels: ${{ steps.task_release_gh_meta.outputs.labels }}
# #
# Job > Docker Release > Github
# #
job-docker-release-dockerhub-main:
name: >-
📦 Release Dockerhub Main
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
needs: [ job-docker-release-github-php, job-docker-release-dockerhub-php ]
steps:
# #
# Release > Dockerhub > Start
# #
- name: "✅ Start"
id: task_release_dh_start
run: |
echo "Starting Github docker release"
# #
# Release > Dockerhub > Checkout
# #
- name: "☑️ Checkout"
id: task_release_dh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release > Dockerhub > QEMU
# #
- name: "⚙️ Set up QEMU"
id: task_release_dh_qemu
uses: docker/setup-qemu-action@v3
# #
# Release > Dockerhub > Setup BuildX
# #
- name: "⚙️ Setup Buildx"
id: task_release_dh_buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver-opts: 'image=moby/buildkit:v0.10.5'
# #
# Release > Dockerhub > Registry Login
# #
- name: "⚙️ Login to DockerHub"
id: task_release_dh_registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ inputs.IMAGE_AUTHOR || env.IMAGE_AUTHOR }}
password: ${{ secrets.SELF_DOCKERHUB_TOKEN }}
# #
# Release > Dockerhub > Meta
# #
- name: "🔨 Docker meta"
id: task_release_dh_meta
uses: docker/metadata-action@v5
with:
images: |
${{ inputs.IMAGE_AUTHOR || env.IMAGE_AUTHOR }}/${{ inputs.IMAGE_NAME || env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable=${{ endsWith(github.ref, 'main') }}
type=ref,event=tag
# #
# Release > Dockerhub > Debug
# #
- name: "🪪 Debug Print"
id: task_release_dh_print
run: |
echo "registry ............. Dockerhub"
echo "github.actor.......... ${{ github.actor }}"
echo "github.ref ........... ${{ github.ref }}"
echo "github.event_name .... ${{ github.event_name }}"
echo "tags ................. ${{ steps.task_release_dh_meta.outputs.tags }}"
echo "labels ............... ${{ steps.task_release_dh_meta.outputs.labels }}"
# #
# Release > Dockerhub > Build and Push
# #
- name: "📦 Build & Push"
id: task_release_dh_push
uses: docker/build-push-action@v6
if: ( github.event_name == 'workflow_dispatch' && inputs.PRINT_ONLY == 'false' ) || ( github.event_name == 'push' )
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.task_release_dh_meta.outputs.tags }}
labels: ${{ steps.task_release_dh_meta.outputs.labels }}

View File

@@ -1,277 +0,0 @@
# #
# @type github workflow
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage builds mkdocs from the main branch /docs/ folder and puts the compiled version
# in the `gh-pages` branch. Is hosted using Github Pages.
#
# @update use the following commands to update mkdocs and the mkdocs-material theme:
# pip install --upgrade mkdocs
# pip install --upgrade --force-reinstall mkdocs-material
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/documentation.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/documentation.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: "📒 Docs Build"
run-name: "📒 Docs Build"
# #
# triggers
# #
on:
# #
# Trigger Release
#
# update documentation every time a release is made
# #
release:
types:
- published
# #
# Trigger Push
#
# update documentation every time a file in docs/ folder is modified
# #
push:
paths:
- docs/**
# #
# Trigger Workflow Dispatch
#
# If any values are not provided, will use fallback env variable
# #
workflow_dispatch:
inputs:
# #
# Image Name
#
# used in github image path
# ghcr.io/${{ env.IMAGE_GHCR_AUTHOR }}/${{ env.IMAGE_NAME }}
# #
WORKING_DIR:
description: '📁 Docs Folder'
required: true
default: './docs/site'
type: string
# #
# Trigger Cron
#
# update documentation every X hours
# #
schedule:
- cron: "0 */12 * * *"
# #
# environment variables
# #
env:
WORKING_DIR: ${{ github.event.inputs.WORKING_DIR || './docs/site' }}
ASSIGN_USER: Aetherinox
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
# #
# jobs
# #
jobs:
build-docs:
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 20
permissions:
contents: write
pages: write
environment:
name: Orion
steps:
# #
# Documentation Checkout Arm64
# #
- name: >-
✅ Checkout
id: task_docs_checkout
uses: actions/checkout@v4
# #
# Documentation Set Env Variables
# #
- name: >-
🕛 Get Timestamp
id: task_docs_set_timestamp
run: |
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# Documentation Setup Python
# #
- name: >-
🐍 Setup Python
id: task_docs_python_setup
uses: actions/setup-python@v5
with:
python-version: 3.x
# #
# Documentation Build Documentation
# #
- name: >-
📕 Build Documentation
id: task_docs_build
run: |
export DOCS_NAME=${{ secrets.DOCS_NAME || 'TVApp2' }}
export DOCS_SECRET_L1=${{ secrets.DOCS_SECRET_L1 }}
export DOCS_SECRET_L2=${{ secrets.DOCS_SECRET_L2 }}
export GH_TOKEN=${{ secrets.ADMINSERV_TOKEN }}
pip install mkdocs
pip install mkdocs-material
pip install mike
pip install mkdocs-embed-external-markdown
pip install mkdocs-git-committers-plugin-2
pip install mkdocs-encryptcontent-plugin
pip install mkdocs-redirects mkdocs-glightbox pymdown-extensions mkdocs-git-revision-date-localized-plugin mkdocs-git-authors-plugin mkdocs-link-embeds-plugin
cd docs
mkdocs build
dir
env:
GH_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
# #
# Documentation Deploy
# #
- name: >-
💽 Deploy
id: task_docs_deploy
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.ADMINSERV_TOKEN_CL }}
publish_dir: "${{ env.WORKING_DIR }}"
# #
# Documentation Get Weekly Commits
# #
- name: >-
🕛 Get Weekly Commit List
id: task_docs_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Documentation Notify Github Success
# #
- name: >-
🔔 Send Discord Webhook Message (Success)
id: task_docs_notify_discord_success
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 📦 Documentation Deployment${{ job.status == 'success' && '✅' || '❌' }}
A **successful** deployment of TVApp2 documentation has been completed. Changes to documentation will appear in the next 5 minutes.
- Documentation: https://thebinaryninja.github.io/tvapp2/
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
# #
# Documentation Notify Github Failure
# #
- name: >-
🔔 Send Discord Webhook Message (Failure)
id: task_docs_notify_discord_failure
uses: tsickert/discord-webhook@v7.0.0
if: failure()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 📦 Documentation Deployment${{ job.status == 'success' && '✅' || '❌' }}
A **failed** attempt to build the new documentation has triggered. No changes to your documentation will be made until the errors are fixed in the workflow.
- Documentation: https://thebinaryninja.github.io/tvapp2/
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"

View File

@@ -1,230 +0,0 @@
# #
# @type github workflow
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage cleans all commit history for a repository
# edit the 'environment:' to determine which deployment to keep clean
# - can be ran manually
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_TOKEN org github personal access token (fine-grained)
# secrets.ORG_TOKEN_CL org github personal access token (classic)
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
#
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/history-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/history-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: '🧹 History Clean'
run-name: '🧹 History Clean'
# #
# triggers
# #
on:
# #
# Trigger > Workflow Dispatch
# #
workflow_dispatch:
inputs:
# #
# Commit Label
#
# the label to use when repository is cleaned
# #
COMMIT_LABEL:
description: '🏷️ Commit Label'
required: true
default: 'cleanup'
type: string
# #
# Main Branch
#
# main branch re-recreate
# #
BRANCH_MAIN:
description: '🌳 Main Branch'
required: true
default: 'main'
type: string
# #
# Deployment Environment Name
#
# this is the name of the deployment item
# #
DEPLOYMENT_ENV:
description: '📦 Deployment Environment'
required: true
default: 'orion'
type: string
# #
# environment variables
# #
env:
COMMIT_LABEL: ${{ github.event.inputs.COMMIT_LABEL || 'cleanup' }}
BRANCH_MAIN: ${{ github.event.inputs.BRANCH_MAIN || 'main' }}
DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }}
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
# #
# jobs
# #
jobs:
history-clean:
name: >-
🧹 History Clean
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 5
steps:
# #
# History Clean Set TImestamps
# #
- name: >-
🕛 Get Timestamp
id: task_history_clean_set_timestamp
run: |
echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# History Clean Checkout
# #
- name: >-
✅ Checkout
id: task_history_clean_gh_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# History Clean Git Identify
# #
- name: >-
🪪 Configure Git Identity
id: task_history_clean_git_ident
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
# #
# History Clean Pre-Commit
# #
- name: >-
📦 Commit Pre-commit
id: task_history_clean_commit_pre
run: |
now=$(date -u '+%m/%d/%Y %H:%M')
commit_label="${{ env.COMMIT_LABEL }}" >> $GITHUB_ENV
echo -e "$commit_label"
commit_message="\\\`️️🧹 $commit_label 🧹\\\` \\\`$now UTC\\\`" >> $GITHUB_ENV
echo -e "$commit_message"
echo "COMMIT_MESSAGE=$(echo $commit_message)" >> $GITHUB_ENV
echo "NOW=$(echo $now)" >> $GITHUB_ENV
# #
# History Clean Pre-Commit Debug
# #
- name: >-
📦 Commit Pre-commit Debug
id: task_history_clean_commit_debug
run: |
echo -e "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
echo -e " Printing Values"
echo -e "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
echo -e " env.COMMIT_LABEL .................... ${{ env.COMMIT_LABEL }}"
echo -e " env.COMMIT_MESSAGE .................. ${{ env.COMMIT_MESSAGE }}"
echo -e " env.NOW ............................. ${{ env.NOW }}"
# #
# History Clean Start
# #
- name: >-
🧹 Clean Repo History
id: task_history_clean_history
run: |
# Create a new orphan branch
git checkout --orphan temp-branch
# Add all files to the new branch
git add -A
# Commit the files to the new branch
git commit -m "${{ env.COMMIT_MESSAGE }}"
# Delete the old main branch
git branch -D ${{ env.BRANCH_MAIN }}
# Rename the new orphan branch to main
git branch -m ${{ env.BRANCH_MAIN }}
# Force push the new main branch to the remote repository
git push -f origin ${{ env.BRANCH_MAIN }}
# #
# History Clean References
# #
- name: >-
🗑️ Clean References
id: task_history_clean_references
run: |
# Remove remote-tracking references to deleted branches (optional)
git fetch origin --prune
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# #
# History Clean Commit
# #
- name: >-
📦 Commit Execute
id: task_history_clean_commit_execute
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: ${{ env.COMMIT_MESSAGE }}

72
.github/workflows/issues-accept.yml vendored Normal file
View File

@@ -0,0 +1,72 @@
# #
# @type github workflow
# @desc adds a label to a PR when the command "/accept" is typed in the issue comments
# do not attempt to use env variables in if condition.
# do not accept to change GITHUB_TOKEN.
# @author Aetherinox
# @url https://github.com/Aetherinox
# #
name: "🎫 Issue Accept"
run-name: "🎫 Issue Accept"
# #
# triggers
# #
on:
issue_comment:
types: [created]
# #
# environment variables
# #
env:
LABEL_ACCEPT: "Status 𐄂 Accepted"
BOT_NAME_1: AdminServ
BOT_NAME_2: AdminServX
BOT_NAME_3: EuropaServ
BOT_NAME_DEPENDABOT: dependabot[bot]
# #
# jobs
# #
jobs:
# #
# Job [ Deploy ]
# #
deploy:
if: contains(github.event.comment.body, '/accept') && github.event.comment.user.login == 'Aetherinox'
runs-on: ubuntu-latest
steps:
# #
# Add Label to accepted PR
# #
- name: >-
🏷️ Assign Label ${{ env.LABEL_ACCEPT }}
run: gh issue edit "$NUMBER" --add-label "$LABELS"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
LABELS: ${{ env.LABEL_ACCEPT }}
# #
# Add assignee to accepted PR
# #
- name: >-
🏷️ Assign Assignee ${{ github.repository_owner }}
run: gh issue edit "$NUMBER" --add-assignee "$ASSIGNEE"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
ASSIGNEE: ${{ github.repository_owner }}

764
.github/workflows/issues-new.yml vendored Executable file → Normal file

File diff suppressed because it is too large Load Diff

1674
.github/workflows/issues-scan.yml vendored Executable file → Normal file

File diff suppressed because it is too large Load Diff

525
.github/workflows/issues-stale.yml vendored Executable file → Normal file
View File

@@ -1,54 +1,31 @@
# #
# @type github workflow
# @desc creates repository labels if they are not yet installed
# issues marked as stale after 30 days, given tag Status 𐄂 Stale
# inactive issues closed after 180 days, given tag Status 𐄂 Locked
# inactive pr closed after 365 days, given tag Status 𐄂 Locked
# issues marked stale after 30 days, given tag Status 𐄂 Stale
# issues marked closed 7 days after being marked stale, given tag Status 𐄂 Autoclosed
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage creates repository labels if they are not yet installed
# issues marked as stale after 30 days, given tag Status Stale
# inactive issues closed after 180 days, given tag Status Locked
# inactive pr closed after 365 days, given tag Status Locked
# issues marked stale after 30 days, given tag Status Stale
# issues marked closed 7 days after being marked stale, given tag Status Autoclosed
#
# @notes This Github action must be activated manually. This workflow script will do the following:
# - Scan issues / pull requests and make sure they have properly assigned labels:
# - `Bug`
# - `Feature`
# - `Urgent`
# - `Roadmap`
# This Github action must be activated manually. This workflow script will do the
# following:
#
# - Workflow script will then scan each pr or issue and mark them as `Stale`
# if they haven't had any replies in 30 days.
# - Scan issues / pull requests and make sure they have properly assigned labels:
# - `Bug`
# - `Feature`
# - `Urgent`
# - `Roadmap`
#
# - Workflow will `autoclose` pr or issues which haven't had action in `365 days`.
# - Workflow script will then scan each pr or issue and mark them as `Stale`
# if they haven't had any replies in 30 days.
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_TOKEN org github personal access token (fine-grained)
# secrets.ORG_TOKEN_CL org github personal access token (classic)
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/issues-stale.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/issues-stale.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# - Workflow will `autoclose` pr or issues which haven't had action in `365 days`.
# #
name: '🎫 Issues Stale'
run-name: '🎫 Issues Stale'
name: "🎫 Issues Stale"
run-name: "🎫 Issues Stale"
# #
# triggers
@@ -64,75 +41,64 @@ on:
# #
env:
PREFIX_BUG: "🐛 Bug"
PREFIX_DEPENDENCY: "Dependency"
PREFIX_DOCS: "Docs"
PREFIX_FEATURE: "💡 Feature"
PREFIX_GIT: "Git Action"
PREFIX_PR: "PR"
PREFIX_ROADMAP: "🗺️ Roadmap"
PREFIX_INTERNAL: "Internal"
PREFIX_URGENT: "Urgent"
PREFIX_BUG: "Bug"
PREFIX_DEPENDENCY: "Dependency"
PREFIX_DOCS: "Docs"
PREFIX_FEATURE: "Feature"
PREFIX_GIT: "Git Action"
PREFIX_PR: "PR"
PREFIX_ROADMAP: "Roadmap"
PREFIX_INTERNAL: "Internal"
PREFIX_URGENT: "Urgent"
LABEL_BUG: "Type Bug"
LABEL_DEPENDENCY: "Type Dependency"
LABEL_DOCS: "Type Docs"
LABEL_FEATURE: "Type Feature"
LABEL_GIT: "Type Git Action"
LABEL_PR: "Type Pull Request"
LABEL_ROADMAP: "Type Roadmap"
LABEL_INTERNAL: "Type Internal"
LABEL_LOCKED: "Status Locked"
LABEL_STALE: "Status Stale"
LABEL_AUTOCLOSE: "Status Autoclosed"
LABEL_ACCEPTED: "Status Accepted"
LABEL_REVIEW: "Status Review"
LABEL_PENDING: "Status Pending"
LABEL_AC_REVIEW: "AC Review Required"
LABEL_URGENT: "⚠ Urgent"
ASSIGN_USER: Aetherinox
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
LABEL_BUG: "Type Bug"
LABEL_DEPENDENCY: "Type Dependency"
LABEL_DOCS: "Type Docs"
LABEL_FEATURE: "Type Feature"
LABEL_GIT: "Type Git Action"
LABEL_PR: "Type Pull Request"
LABEL_ROADMAP: "Type Roadmap"
LABEL_INTERNAL: "Type Internal"
LABEL_URGENT: "⚠ Urgent"
BOT_NAME_1: EuropaServ
BOT_NAME_DEPENDABOT: dependabot[bot]
LABELS_JSON: |
[
{ "name": "AC Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
{ "name": "AC Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
{ "name": "AC Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
{ "name": "AC Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
{ "name": "AC Passed", "color": "146b4a", "description": "Ready to be reviewed" },
{ "name": "AC Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
{ "name": "AC Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
{ "name": "AC Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
{ "name": "Status Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
{ "name": "Status Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
{ "name": "Status Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
{ "name": "Status Denied", "color": "ba4058", "description": "Pull request has been denied" },
{ "name": "Status Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
{ "name": "Status Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
{ "name": "Status No Action", "color": "030406", "description": "Closed without any action being taken" },
{ "name": "Status Pending", "color": "984b12", "description": "Pending pull request" },
{ "name": "Status Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
{ "name": "Status Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
{ "name": "Status Review", "color": "9e1451", "description": "Currently pending review" },
{ "name": "Status Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
{ "name": "Type Bug", "color": "9a2c2c", "description": "Something isn't working" },
{ "name": "Type Dependency", "color": "243759", "description": "Item is associated to dependency" },
{ "name": "Type Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
{ "name": "Type Feature", "color": "3c4e93", "description": "Feature request" },
{ "name": "Type Git Action", "color": "030406", "description": "GitHub Action / workflow" },
{ "name": "Type Pull Request", "color": "8F1784", "description": "Normal pull request" },
{ "name": "Type Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
{ "name": "Type Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
{ "name": "Build Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
{ "name": "Build Linux", "color": "c7ca4a", "description": "Specific to Linux" },
{ "name": "Build MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
{ "name": "Build Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
{ "name": "Build Web", "color": "c7ca4a", "description": "Specific to web" },
{ "name": "Build Windows", "color": "c7ca4a", "description": "Specific to Windows" },
{ "name": "AC Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
{ "name": "AC Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
{ "name": "AC Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
{ "name": "AC Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
{ "name": "AC Passed", "color": "146b4a", "description": "Ready to be reviewed" },
{ "name": "AC Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
{ "name": "AC Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
{ "name": "AC Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
{ "name": "Type Bug", "color": "9a2c2c", "description": "Something isn't working" },
{ "name": "Type Dependency", "color": "243759", "description": "Item is associated to dependency" },
{ "name": "Type Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
{ "name": "Type Feature", "color": "3c4e93", "description": "Feature request" },
{ "name": "Type Git Action", "color": "030406", "description": "GitHub Action / workflow" },
{ "name": "Type Pull Request", "color": "8F1784", "description": "Normal pull request" },
{ "name": "Type Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
{ "name": "Type Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
{ "name": "Build Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
{ "name": "Build Linux", "color": "c7ca4a", "description": "Specific to Linux" },
{ "name": "Build MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
{ "name": "Build Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
{ "name": "Build Web", "color": "c7ca4a", "description": "Specific to web" },
{ "name": "Build Windows", "color": "c7ca4a", "description": "Specific to Windows" },
{ "name": " API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
{ "name": " Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
{ "name": " Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
@@ -175,62 +141,40 @@ jobs:
job-labels-create:
name: >-
🎫 Labels Verify Existing
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
# #
# Issues (Stale) Labels Create Start
# [ Create Labels ] Start
# #
- name: >-
✅ Start
id: task_labels_create_start
id: task_label_create_start
run: |
echo "Assigning labels and assignees"
# #
# Issues (Stale) Labels Create Set Env Variables
# #
- name: >-
🕛 Get Timestamp
id: task_labels_create_set_timestamp
run: |
echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# Issues (Stale) Labels Create Checkout
# [ Create Labels ] Checkout
# #
- name: >-
☑️ Checkout
id: task_labels_create_checkout
id: task_label_create_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Issues (Stale) Labels Create Verify Existing
#
# check if repo has all of the needed issue / pr labels; create label if not exists
#
# action needed if using 'pull_request' and 'issue_comment'
# to get the pull request, you would normally use ${{ github.event.number }}
# however this isnt available for 'issue_comment'
# [ Create Labels ] Verify Existing Labels
# #
- name: >-
🎫 Labels Verify Existing
id: task_labels_create_verify
🏷️ Verify Existing Labels
id: task_label_create_verify
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
script: |
const labels = JSON.parse( process.env.LABELS_JSON );
for ( const label of labels )
@@ -242,7 +186,7 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
name: label.name,
description: label.description || 'No Description',
description: label.description || '',
color: label.color
});
}
@@ -260,7 +204,7 @@ jobs:
}
# #
# Issues (Stale) Labels Assign Missing
# Job [ Check Labels ]
#
# Runs through all submissions to check for ones that have not been properly labeled
# - Bug
@@ -273,34 +217,29 @@ jobs:
name: >-
🎫 Labels Assign Missing
runs-on: ubuntu-latest
timeout-minutes: 4
needs: job-labels-create
steps:
# #
# Issues (Stale) Labels Assign Missing Checkout
# [ Check Labels ] Checkout
# #
- name: >-
☑️ Checkout
- name: "☑️ Prepare"
id: task_issues_nolabel_prepare
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Issues (Stale) Labels Assign Missing Check
#
# Check if repo has labels to use
# [ Check Labels ] Check
# Check if repo has labels currently added to issues
# #
- name: >-
🎫 Labels Check
- name: 🏷️ Checking Issues
id: task_issues_nolabel_run
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
script: |
/*
@@ -309,18 +248,19 @@ jobs:
const dateTimeformat = ( date ) =>
{
let month = date.getMonth( ) + 1;
month = month.toString( ).padStart( 2, '0' );
let day = date.getDate( ).toString( ).padStart( 2, '0' );
let year = date.getFullYear( ).toString( ).padStart( 2, '0' );
let month = date.getMonth( ) + 1;
month = month.toString( ).padStart( 2, '0' );
let day = date.getDate( ).toString( ).padStart( 2, '0' );
let year = date.getFullYear( ).toString( ).padStart( 2, '0' );
let hours = date.getHours();
let minutes = date.getMinutes();
let x = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes.toString( ).padStart( 2, '0' );
let mergeTime = month + '.' + day + '.' + year + ' ' + hours + ':' + minutes + ' ' + x;
let hours = date.getHours();
let minutes = date.getMinutes();
let x = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes.toString( ).padStart( 2, '0' );
let mergeTime = month + '.' + day + '.' + year + ' ' + hours + ':' + minutes + ' ' + x;
return mergeTime;
}
@@ -345,7 +285,7 @@ jobs:
let date_UpdateHuman = dateTimeformat( date_UpdateDate ) + " UTC"; // 03.26.2024 4:40 PM UTC
const time_UpdateMs = new Date( issue.updated_at ).getTime( ); // 1711471241000
// if ( curtime < time_UpdateMs + expireAfterMs ) continue;
//if ( curtime < time_UpdateMs + expireAfterMs ) continue;
/*
Anything past this point is stale / to be closed
@@ -366,8 +306,8 @@ jobs:
let iss_body = `${ issue.body }`;
const iss_body_lc = iss_body.toLowerCase( );
console.log( ` └── 📁 ` + iss_title + ` #${ issue.number }`);
console.log( ` └── 📄 last updated on ${ date_UpdateHuman }` );
console.log( ` └── 📁 ` + iss_title );
console.log( ` └── 📄 Issue #${ issue.number } last updated on ${ date_UpdateHuman }` );
console.log( ` └── 📄 ${add_labels}` );
console.log( `\n\n` )
@@ -375,8 +315,8 @@ jobs:
Keywords
*/
const bug_words = [ "bug", "broke", "issue", "fail", "wont work" ];
const feat_words = [ "feature", "request", "add", "addition", "enhance", "create" ];
const bug_words = [ "bug", "broke", "issue", "fail" ];
const feat_words = [ "feature", "request", "add support" ];
const urgn_words = [ "urgent", "urgency", "emergency", "important", "critical" ];
const road_words = [ "roadmap", "road map", "planned" ];
@@ -395,14 +335,17 @@ jobs:
/*
Label > Bugs
*/
const bug_bIncWordT = bug_words.some( s => s.includes( iss_title_lc ) || iss_title_lc.includes( s ) );
/*
Find regex based phrases
Regex:
https://regex101.com/r/Z99Gnq/2
*/
const bug_bIncWordT = bug_words.some( s => s.includes( iss_title_lc ) || iss_title_lc.includes( s ) );
const bug_findWordList = /^\b(?:I?\s*have\s*(?:a|an)\s*(?:issue|problem|bug))|(?:will\s*not\s*work)|(?:it\s*is\s*(?:broken|broke|stuck))|(?:found\s*(?:an?|the)\s*(?:bug|issue))|(?:can\s*I\s*fix\s*the\s*(?:bug|issue))|(?:(?:does not|doesn'?t|don'?t|won'?t|can'?t|can\s?not|will\s*not)\s*(?:work|load|function))|(?:it\s*(?:will\s?not|won'?t|can\s?not|can'?t))\s*(?:get|find)\s*the\s*(?:website|site|webpage|page)|(?:the\s*(?:window|frame)\s*is\s*(?:blank|white|empty|missing))\b$/igm;
const bug_bFoundMatchTitle = Boolean( bug_findWordList.test( iss_title ) );
const bug_bFoundMatchBody = Boolean( bug_findWordList.test( iss_body ) );
@@ -430,49 +373,16 @@ jobs:
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
core.info( `Skipping: Detected ${ author }` )
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
core.info( `Skipping: Detected ${ author }` )
/*
Rename title to contain Bug:
if bug title or body contains keyword hinting at the issue being about a bug; change the title of the issue
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
*/
// Rename title to contain Bug:
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !bug_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
{
/*
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
original: Bug: CMD windows opens then closes, can't run the script.
new: 🐛 Bug: CMD windows opens then closes, can't run the script.
*/
const removeBeginning1 = bug_tag.substring(3); // "Bug:"
let removeBeginning2 = bug_tag.substring(0); // "🐛 Bug:"
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Bug:"
if ( iss_title.startsWith(removeBeginning1) )
{
iss_title = iss_title.slice(removeBeginning1.length);
iss_title = iss_title.trim();
}
else if ( iss_title.startsWith(removeBeginning2) )
{
iss_title = iss_title.slice(removeBeginning2.length);
iss_title = iss_title.trim();
}
const title = iss_title;
const title = issue.title;
let title_new = title.replace( /^\s?bug\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?fail\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?issue\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?fail\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?issue\s*(.*?)\b/gi, '' );
iss_title = `${ bug_tag } ${ title_new }`;
}
console.log( `New Title: ...................... ${ iss_title }` )
await github.rest.issues.update(
{
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
@@ -493,7 +403,7 @@ jobs:
https://regex101.com/r/fR1Hm6/1
*/
const feat_findWordList = /(?:(?:add|enjoy|would|like|can|request|include|see|could|have)\s*?(?:the|liked?|i|we|an?|the|you?)\s*?(?:to|have|an|get|ability|request|add|feature|functionality|addon|addition|plugin|create))|(?:(?:add|see|get)\s*?support\s*?(?:for|with|of))|(?:can\s*we\s*get\s*?(?:the|a)\s*?(?:ability|feature))|(?:💡 Feature:)$/igm;
const feat_findWordList = /^(?:(?:request|include|see)\s*(?:an?|the?)\s*(?:feature|addon|addition|plugin))|(?:(?:add|see|get)\s*support\s*(?:for|with|of))|(?:can\s*we\s*get\s*(?:the|a)\s*(?:ability|feature))|(?:💡 Feature:)$/igm;
const feat_bFoundMatchTitle = Boolean( feat_findWordList.test( iss_title ) );
const feat_bFoundMatchBody = Boolean( feat_findWordList.test( iss_body ) );
@@ -520,49 +430,17 @@ jobs:
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
core.info( `Skipping: Detected ${ author }` )
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
core.info( `Skipping: Detected ${ author }` )
/*
Rename title to contain Feature:
if feature title or body contains keyword hinting at the issue being about a feature; change the title of the issue
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
*/
// Rename title to contain Feature:
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !feat_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
{
/*
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
original: Feature: CMD windows opens then closes, can't run the script.
new: 💡 Feature: CMD windows opens then closes, can't run the script.
*/
const removeBeginning1 = feat_tag.substring(3); // "Feature:"
let removeBeginning2 = feat_tag.substring(0); // "💡 Feature:"
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Feature:"
if ( iss_title.startsWith(removeBeginning1) )
{
iss_title = iss_title.slice(removeBeginning1.length);
iss_title = iss_title.trim();
}
else if ( iss_title.startsWith(removeBeginning2) )
{
iss_title = iss_title.slice(removeBeginning2.length);
iss_title = iss_title.trim();
}
const title = iss_title;
const title = issue.title;
let title_new = title.replace( /^\s?feature\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?request\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?add(.*?)\s?feature\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?add(.*?)\s?support\s*(.*?)\b/gi, '' );
iss_title = `${ feat_tag } ${ title_new }`; // change TAG per category
iss_title = `${ feat_tag } ${ title_new }`;
}
console.log( `New Title: ...................... ${ iss_title }` )
await github.rest.issues.update(
{
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
@@ -610,40 +488,10 @@ jobs:
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
core.info( `Skipping: Detected ${ author }` )
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
core.info( `Skipping: Detected ${ author }` )
/*
Rename title to contain Urgent:
if urgent title or body contains keyword hinting at the issue being about urgent; change the title of the issue
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
*/
// Rename title to contain Urgent:
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !urgn_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
{
/*
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
original: Urgent: CMD windows opens then closes, can't run the script.
new: ⚠ Urgent: CMD windows opens then closes, can't run the script.
*/
const removeBeginning1 = urgn_tag.substring(3); // "Urgent:"
let removeBeginning2 = urgn_tag.substring(0); // "⚠ Urgent:"
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Urgent:"
if ( iss_title.startsWith(removeBeginning1) )
{
iss_title = iss_title.slice(removeBeginning1.length);
iss_title = iss_title.trim();
}
else if ( iss_title.startsWith(removeBeginning2) )
{
iss_title = iss_title.slice(removeBeginning2.length);
iss_title = iss_title.trim();
}
const title = iss_title;
const title = issue.title;
let title_new = title.replace( /^\s?emergency\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?urgent\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?urgency\s*(.*?)\b/gi, '' );
@@ -652,8 +500,6 @@ jobs:
iss_title = `${ urgn_tag } ${ title_new }`;
}
console.log( `New Title: ...................... ${ iss_title }` )
await github.rest.issues.update(
{
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
@@ -676,8 +522,8 @@ jobs:
*/
const road_findWordList = /#\s*Summary[\S\s]+#\s*(?:Proposal|Objective)[^\]]+/igm;
const road_bFoundMatchTitle = Boolean( road_findWordList.test( iss_title ) );
const road_bFoundMatchBody = Boolean( road_findWordList.test( iss_body ) );
const road_bFoundMatchTitle = Boolean( road_findWordList.test( iss_title ) );
const road_bFoundMatchBody = Boolean( road_findWordList.test( iss_body ) );
/*
Do not change a title if the item starts with a PR: #
@@ -686,8 +532,8 @@ jobs:
https://regex101.com/r/JOrqbN/1
*/
const road_findPRTitle = /^PR\s?#?(?:[0-9]*:)/igm;
const road_bFoundPRTitle = Boolean( road_findPRTitle.test( iss_title ) );
const road_findPRTitle = /^PR\s?#?(?:[0-9]*:)/igm;
const road_bFoundPRTitle = Boolean( road_findPRTitle.test( iss_title ) );
/*
- Check if issue title matches the issue label "Roadmap:"
@@ -702,48 +548,18 @@ jobs:
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
core.info( `Skipping: Detected ${ author }` )
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
core.info( `Skipping: Detected ${ author }` )
/*
Rename title to contain Roadmap:
if roadmap title or body contains keyword hinting at the issue being about roadmap; change the title of the issue
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
*/
// Rename title to contain Roadmap:
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !road_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
{
/*
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
original: Roadmap: CMD windows opens then closes, can't run the script.
new: 🗺️ Roadmap: CMD windows opens then closes, can't run the script.
*/
const removeBeginning1 = road_tag.substring(3); // "Roadmap:"
let removeBeginning2 = road_tag.substring(0); // "🗺️ Roadmap:"
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Roadmap:"
if ( iss_title.startsWith(removeBeginning1) )
{
iss_title = iss_title.slice(removeBeginning1.length);
iss_title = iss_title.trim();
}
else if ( iss_title.startsWith(removeBeginning2) )
{
iss_title = iss_title.slice(removeBeginning2.length);
iss_title = iss_title.trim();
}
const title = iss_title;
let title_new = title.replace( /^\s?broad(.*?)\s?map\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?planned\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?broadmap\s*(.*?)\b/gi, '' );
iss_title = `${ road_tag } ${ title_new }`; // change TAG per category
const title = issue.title;
let title_new = title.replace( /^\s?emergency\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?urgent\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?urgency\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?important\s*(.*?)\b/gi, '' );
title_new = title.replace( /^\s?critical\s*(.*?)\b/gi, '' );
iss_title = `${ road_tag } ${ title_new }`;
}
console.log( `New Title: ...................... ${ iss_title }` )
await github.rest.issues.update(
{
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
@@ -761,15 +577,13 @@ jobs:
}
# #
# Issues (Stale) Stale
# Job [ Stale Issues ]
# #
job-issues-stale:
name: >-
💤 Scan Check Stale
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 5
💤 Check Stale
runs-on: ubuntu-latest
needs:
- job-labels-create
- job-issues-nolabel
@@ -779,60 +593,57 @@ jobs:
pull-requests: write
steps:
# #
# Stale Check Condition
# #
# #
# [ Stale Issues ] Check Condition
# #
- name: >-
💤 Stale Check Condition
id: task_issues_inactive_stale
uses: actions/stale@v9
with:
repo-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
stale-issue-message: |
⚠️ It looks like there hasn't been any recent updates on this issue. If you created this issue and no longer consider it open, then please login to github and close the issue.
- name: "💤 Stale Check Condition"
uses: actions/stale@v9
id: task_issues_stale_run
with:
repo-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
stale-issue-message: |
⚠️ It looks like there hasn't been any recent updates on this issue. If you created this issue and no longer consider it
open, then please login to github and close the issue.
If there is no further activity on this issue, it will be automatically closed in the next week.
If there is no further activity on this issue, it will be automatically closed in the next week.
---
---
<sub>I am a bot reaching out to you with an automated response.</sub>
stale-issue-label: '${{ env.LABEL_STALE }}'
close-issue-label: '${{ env.LABEL_AUTOCLOSE }}'
exempt-issue-labels: '${{ env.LABEL_ACCEPTED }},${{ env.LABEL_REVIEW }},${{ env.LABEL_PENDING }},${{ env.LABEL_BUG }},${{ env.LABEL_DEPENDENCY }},${{ env.LABEL_DOCS }},${{ env.LABEL_FEATURE }},${{ env.LABEL_GIT }},${{ env.LABEL_PR }},${{ env.LABEL_ROADMAP }}'
days-before-stale: 120
days-before-close: 7
days-before-pr-stale: -1
days-before-pr-close: -1
<sub>I am a bot reaching out to you with an automated response.</sub>
stale-issue-label: 'Status 𐄂 Stale'
close-issue-label: 'Status 𐄂 Autoclosed'
exempt-issue-labels: 'Status 𐄂 Accepted,Status 𐄂 Review,Status 𐄂 Pending,Type ◦ Bug,Type ◦ Dependency,Type ◦ Docs,Type ◦ Feature,Type ◦ Git Action,Type ◦ Pull Request,Type ◦ Roadmap'
days-before-stale: 14
days-before-close: 7
days-before-pr-stale: -1
days-before-pr-close: -1
# #
# Issues (Stale) Lock
# Job [ Lock Issues ]
# #
job-issues-lock:
name: >-
🔒 Scan Lock Inactive
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 5
🔒 Check Inactive
runs-on: ubuntu-latest
needs:
- job-labels-create
- job-issues-nolabel
steps:
# #
# Inactive Lock
# [ Lock Issues ] Look for inactives
# #
- name: >-
🔒 Inactive Lock
id: task_issues_inactive_lock
- name: "🔒 Lock Inactives"
uses: dessant/lock-threads@v5
id: task_issues_lock_run
with:
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
exclude-any-issue-labels: '${{ env.LABEL_AC_REVIEW }},${{ env.LABEL_ACCEPTED }},${{ env.LABEL_REVIEW }},${{ env.LABEL_PENDING }},${{ env.LABEL_BUG }},${{ env.LABEL_DEPENDENCY }},${{ env.LABEL_DOCS }},${{ env.LABEL_FEATURE }},${{ env.LABEL_GIT }},${{ env.LABEL_ROADMAP }},${{ env.LABEL_INTERNAL }}'
add-issue-labels: '${{ env.LABEL_LOCKED }}'
issue-inactive-days: '120'
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
exclude-any-issue-labels: 'AC Review Required,Status 𐄂 Accepted,Status 𐄂 Review,Status 𐄂 Pending,Type ◦ Bug,Type ◦ Dependency,Type ◦ Docs,Type ◦ Feature,Type ◦ Git Action,Type ◦ Roadmap,Type ◦ Internal'
add-issue-labels: 'Status 𐄂 Locked'
issue-inactive-days: '60'
issue-lock-reason: 'resolved'
issue-comment: >
⚠️ This **issue** has been automatically locked since there has not been any recent activity after it was closed.
@@ -842,8 +653,8 @@ jobs:
---
<sub>I am a bot reaching out to you with an automated response.</sub>
exclude-any-pr-labels: '${{ env.LABEL_AC_REVIEW }},${{ env.LABEL_ACCEPTED }},${{ env.LABEL_REVIEW }},${{ env.LABEL_PENDING }},${{ env.LABEL_BUG }},${{ env.LABEL_DEPENDENCY }},${{ env.LABEL_DOCS }},${{ env.LABEL_FEATURE }},${{ env.LABEL_GIT }},${{ env.LABEL_ROADMAP }},${{ env.LABEL_INTERNAL }}'
add-pr-labels: '${{ env.LABEL_LOCKED }}'
exclude-any-pr-labels: 'AC Review Required,Status 𐄂 Accepted,Status 𐄂 Review,Status 𐄂 Pending,Type ◦ Bug,Type ◦ Dependency,Type ◦ Docs,Type ◦ Feature,Type ◦ Git Action,Type ◦ Roadmap,Type ◦ Internal'
add-pr-labels: 'Status 𐄂 Locked'
pr-inactive-days: '365'
pr-lock-reason: 'resolved'
pr-comment: >

183
.github/workflows/labels-clean..yml vendored Normal file
View File

@@ -0,0 +1,183 @@
# #
# @type github workflow
# @desc manually activated workflow to remove issue labels
# @author Aetherinox
# @url https://github.com/Aetherinox
#
# This Github action must be activated manually. This workflow script will do the
# following:
#
# - Remove all existing labels in repository
# #
name: "🎫 Labels Remove"
run-name: "🎫 Labels Remove"
# #
# triggers
# #
on:
workflow_dispatch:
# #
# environment variables
# #
env:
BOT_NAME_1: EuropaServ
BOT_NAME_DEPENDABOT: dependabot[bot]
LABELS_JSON: |
[
{ "name": "AC Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
{ "name": "AC Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
{ "name": "AC Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
{ "name": "AC Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
{ "name": "AC Passed", "color": "146b4a", "description": "Ready to be reviewed" },
{ "name": "AC Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
{ "name": "AC Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
{ "name": "AC Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
{ "name": "Type ◦ Bug", "color": "9a2c2c", "description": "Something isn't working" },
{ "name": "Type ◦ Dependency", "color": "243759", "description": "Item is associated to dependency" },
{ "name": "Type ◦ Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
{ "name": "Type ◦ Feature", "color": "3c4e93", "description": "Feature request" },
{ "name": "Type ◦ Git Action", "color": "030406", "description": "GitHub Action / workflow" },
{ "name": "Type ◦ Pull Request", "color": "8F1784", "description": "Normal pull request" },
{ "name": "Type ◦ Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
{ "name": "Type ◦ Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
{ "name": "Build ◦ Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
{ "name": "Build ◦ Linux", "color": "c7ca4a", "description": "Specific to Linux" },
{ "name": "Build ◦ MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
{ "name": "Build ◦ Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
{ "name": "Build ◦ Web", "color": "c7ca4a", "description": "Specific to web" },
{ "name": "Build ◦ Windows", "color": "c7ca4a", "description": "Specific to Windows" },
{ "name": " API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
{ "name": " Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
{ "name": " Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
{ "name": " Customization", "color": "E3F0FC", "description": "Customizations: plugins, themes, configs" },
{ "name": " Design", "color": "FA70DE", "description": "Design related queries" },
{ "name": " Dist", "color": "FA70DE", "description": "Installers and other forms of software distribution" },
{ "name": " Enterprise", "color": "11447a", "description": "Issues about collaboration, administration, and so on" },
{ "name": " Hardware", "color": "5a7503", "description": "YubiKey, other tokens, biometrics" },
{ "name": " Import/Export", "color": "F5FFCC", "description": "Import from and export to different file formats" },
{ "name": " Improvement", "color": "185c98", "description": "Enhance an existing feature" },
{ "name": " Performance", "color": "006b75", "description": "Web and desktop performance issues" },
{ "name": " Plugin Request", "color": "FCE9CA", "description": "Requested changes should be implemented as a plugin" },
{ "name": " Security", "color": "F75D39", "description": "Security issues" },
{ "name": " Self-Hosting", "color": "fad8c7", "description": "Self-hosting installations and configs" },
{ "name": " Storage", "color": "5319e7", "description": "Storage providers: Dropbox, Google, WebDAV, etc." },
{ "name": " Updater", "color": "1BADDE", "description": "Auto-updater issues" },
{ "name": " UX", "color": "1BADDE", "description": "UX and usability" },
{ "name": " Website", "color": "fef2c0", "description": "Website related issues" },
{ "name": "⚠ Urgent", "color": "a8740e", "description": "Requires urgent attention" },
{ "name": "⚠ Announcement", "color": "DB4712", "description": "Announcements" },
{ "name": "📰 Progress Report", "color": "392297", "description": "Development updates" },
{ "name": "📦 Release", "color": "277542", "description": "Release announcements" },
{ "name": "✔️ Poll", "color": "972255", "description": "Community polls" },
{ "name": "❔ Question", "color": "FFFFFF", "description": "All questions" }
]
# #
# jobs
# #
jobs:
# #
# Job Remove Labels
#
# This job removes all existing labels
# #
issues-labels-remove:
name: >-
🎫 Labels Remove
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
issues: 'write'
steps:
# #
# [ Delete Labels ] Start
# #
- name: >-
✅ Start
id: task_label_remove_start
run: |
echo "Starting workflow"
# #
# [ Delete Labels ] Checkout
# #
- name: >-
☑️ Checkout
id: task_label_remove_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# [ Delete Labels ] Start
# #
- name: >-
🏷️ Delete Existing Labels
id: task_label_remove_run
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
script: |
const targetOwner = context.repo.owner;
const targetRepo = context.repo.repo;
// Fetch labels from the source repository
const response = await github.rest.issues.listLabelsForRepo({
owner: targetOwner,
repo: targetRepo,
});
console.log("Labels fetched: ", response.data);
const labels = response.data;
if (labels.length === 0) {
console.log("No labels found in the source repository.");
}
// Fetch all labels from the target repository and delete them
const existingLabels = await github.rest.issues.listLabelsForRepo({
owner: targetOwner,
repo: targetRepo,
});
// const labels = JSON.parse( process.env.LABELS_JSON );
for ( const label of labels )
{
try
{
await github.rest.issues.deleteLabel(
{
owner: context.repo.owner,
repo: context.repo.repo,
name: label.name,
});
}
catch ( err )
{
console.error("Error: " + err);
}
}

View File

@@ -1,252 +0,0 @@
# #
# @type github workflow
# @desc manually activated workflow to remove issue labels
# @author Aetherinox
# @url https://github.com/Aetherinox
#
# @notes This Github action must be activated manually. This workflow script will do the following:
# - Remove all existing labels in repository
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_TOKEN org github personal access token (fine-grained)
# secrets.ORG_TOKEN_CL org github personal access token (classic)
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/labels-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/labels-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: '🧹 Labels Clean'
run-name: '🧹 Labels Clean'
# #
# triggers
# #
on:
workflow_dispatch:
# #
# environment variables
# #
env:
ASSIGN_USER: Aetherinox
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
LABELS_JSON: |
[
{ "name": "bug", "color": "8F1784", "description": "Default github label" },
{ "name": "documentation", "color": "8F1784", "description": "Default github label" },
{ "name": "duplicate", "color": "8F1784", "description": "Default github label" },
{ "name": "enhancement", "color": "8F1784", "description": "Default github label" },
{ "name": "good first issue", "color": "8F1784", "description": "Default github label" },
{ "name": "help wanted", "color": "8F1784", "description": "Default github label" },
{ "name": "invalid", "color": "8F1784", "description": "Default github label" },
{ "name": "question", "color": "8F1784", "description": "Default github label" },
{ "name": "wontfix", "color": "8F1784", "description": "Default github label" },
{ "name": "AC Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
{ "name": "AC Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
{ "name": "AC Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
{ "name": "AC Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
{ "name": "AC Passed", "color": "146b4a", "description": "Ready to be reviewed" },
{ "name": "AC Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
{ "name": "AC Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
{ "name": "AC Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
{ "name": "Status Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
{ "name": "Status Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
{ "name": "Status Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
{ "name": "Status Denied", "color": "ba4058", "description": "Pull request has been denied" },
{ "name": "Status Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
{ "name": "Status Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
{ "name": "Status No Action", "color": "030406", "description": "Closed without any action being taken" },
{ "name": "Status Pending", "color": "984b12", "description": "Pending pull request" },
{ "name": "Status Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
{ "name": "Status Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
{ "name": "Status Review", "color": "9e1451", "description": "Currently pending review" },
{ "name": "Status Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
{ "name": "Type Bug", "color": "9a2c2c", "description": "Something isn't working" },
{ "name": "Type Dependency", "color": "243759", "description": "Item is associated to dependency" },
{ "name": "Type Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
{ "name": "Type Feature", "color": "3c4e93", "description": "Feature request" },
{ "name": "Type Git Action", "color": "030406", "description": "GitHub Action / workflow" },
{ "name": "Type Pull Request", "color": "8F1784", "description": "Normal pull request" },
{ "name": "Type Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
{ "name": "Type Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
{ "name": "Build Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
{ "name": "Build Linux", "color": "c7ca4a", "description": "Specific to Linux" },
{ "name": "Build MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
{ "name": "Build Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
{ "name": "Build Web", "color": "c7ca4a", "description": "Specific to web" },
{ "name": "Build Windows", "color": "c7ca4a", "description": "Specific to Windows" },
{ "name": " API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
{ "name": " Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
{ "name": " Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
{ "name": " Customization", "color": "E3F0FC", "description": "Customizations: plugins, themes, configs" },
{ "name": " Design", "color": "FA70DE", "description": "Design related queries" },
{ "name": " Dist", "color": "FA70DE", "description": "Installers and other forms of software distribution" },
{ "name": " Enterprise", "color": "11447a", "description": "Issues about collaboration, administration, and so on" },
{ "name": " Hardware", "color": "5a7503", "description": "YubiKey, other tokens, biometrics" },
{ "name": " Import/Export", "color": "F5FFCC", "description": "Import from and export to different file formats" },
{ "name": " Improvement", "color": "185c98", "description": "Enhance an existing feature" },
{ "name": " Performance", "color": "006b75", "description": "Web and desktop performance issues" },
{ "name": " Plugin Request", "color": "FCE9CA", "description": "Requested changes should be implemented as a plugin" },
{ "name": " Security", "color": "F75D39", "description": "Security issues" },
{ "name": " Self-Hosting", "color": "fad8c7", "description": "Self-hosting installations and configs" },
{ "name": " Storage", "color": "5319e7", "description": "Storage providers: Dropbox, Google, WebDAV, etc." },
{ "name": " Updater", "color": "1BADDE", "description": "Auto-updater issues" },
{ "name": " UX", "color": "1BADDE", "description": "UX and usability" },
{ "name": " Website", "color": "fef2c0", "description": "Website related issues" },
{ "name": "⚠ Urgent", "color": "a8740e", "description": "Requires urgent attention" },
{ "name": "⚠ Announcement", "color": "DB4712", "description": "Announcements" },
{ "name": "📰 Progress Report", "color": "392297", "description": "Development updates" },
{ "name": "📦 Release", "color": "277542", "description": "Release announcements" },
{ "name": "✔️ Poll", "color": "972255", "description": "Community polls" },
{ "name": "❔ Question", "color": "FFFFFF", "description": "All questions" }
]
# #
# jobs
# #
jobs:
# #
# Job Remove Labels
#
# This job removes all existing labels
# #
issues-labels-clean:
name: >-
🧹 Labels Clean
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 3
permissions:
contents: 'read'
id-token: 'write'
issues: 'write'
steps:
# #
# Labels Start
# #
- name: >-
✅ Start
id: task_label_remove_start
run: |
echo "Starting workflow"
# #
# Labels Set Env Variables
# #
- name: >-
🕛 Get Timestamp
id: task_label_set_timestamp
run: |
echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# Labels Checkout
# #
- name: >-
☑️ Checkout
id: task_label_remove_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Labels Start
# #
- name: >-
🏷️ Delete Existing Labels
id: task_label_remove_run
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
script: |
const targetOwner = context.repo.owner;
const targetRepo = context.repo.repo;
// Fetch labels from the source repository
const response = await github.rest.issues.listLabelsForRepo({
owner: targetOwner,
repo: targetRepo,
});
console.log("Labels fetched: ", response.data);
const labels = response.data;
if (labels.length === 0) {
console.log("No labels found in the source repository.");
}
// Fetch all labels from the target repository and delete them
const existingLabels = await github.rest.issues.listLabelsForRepo({
owner: targetOwner,
repo: targetRepo,
});
// const labels = JSON.parse( process.env.LABELS_JSON );
let result = Object.keys(labels).length;
for ( const label of labels )
{
try
{
await github.rest.issues.deleteLabel(
{
owner: context.repo.owner,
repo: context.repo.repo,
name: label.name,
});
}
catch ( err )
{
console.error("Error: " + err);
}
}
console.log("[Success]: Added " + result + " labels to repo");
return result
# #
# Labels Get Weekly Commits
# #
- name: >-
🕛 Get Weekly Commit List
id: task_label_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV

228
.github/workflows/labels-create.yml vendored Executable file → Normal file
View File

@@ -1,37 +1,26 @@
# #
# @type github workflow
# @desc manually activated workflow to create issue labels
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage manually activated workflow to create issue labels
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_TOKEN org github personal access token (fine-grained)
# secrets.ORG_TOKEN_CL org github personal access token (classic)
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
# This Github action must be activated manually. This workflow script will do the
# following:
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/labels-create.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/labels-create.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# - Scan issues / pull requests and make sure they have properly assigned labels:
# - `Bug`
# - `Feature`
# - `Urgent`
# - `Roadmap`
#
# - Workflow script will then scan each pr or issue and mark them as `Stale`
# if they haven't had any replies in 30 days.
#
# - Workflow will `autoclose` pr or issues which haven't had action in `365 days`.
# #
name: '🎫 Labels Create'
run-name: '🎫 Labels Create'
name: "🎫 Labels Create"
run-name: "🎫 Labels Create"
# #
# triggers
@@ -45,48 +34,46 @@ on:
# #
env:
ASSIGN_USER: Aetherinox
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
BOT_NAME_1: AdminServ
BOT_NAME_2: AdminServX
BOT_NAME_3: EuropaServ
BOT_NAME_DEPENDABOT: dependabot[bot]
LABELS_JSON: |
[
{ "name": "AC Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
{ "name": "AC Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
{ "name": "AC Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
{ "name": "AC Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
{ "name": "AC Passed", "color": "146b4a", "description": "Ready to be reviewed" },
{ "name": "AC Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
{ "name": "AC Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
{ "name": "AC Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
{ "name": "Status Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
{ "name": "Status Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
{ "name": "Status Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
{ "name": "Status Denied", "color": "ba4058", "description": "Pull request has been denied" },
{ "name": "Status Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
{ "name": "Status Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
{ "name": "Status No Action", "color": "030406", "description": "Closed without any action being taken" },
{ "name": "Status Pending", "color": "984b12", "description": "Pending pull request" },
{ "name": "Status Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
{ "name": "Status Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
{ "name": "Status Review", "color": "9e1451", "description": "Currently pending review" },
{ "name": "Status Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
{ "name": "Type Bug", "color": "9a2c2c", "description": "Something isn't working" },
{ "name": "Type Dependency", "color": "243759", "description": "Item is associated to dependency" },
{ "name": "Type Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
{ "name": "Type Feature", "color": "3c4e93", "description": "Feature request" },
{ "name": "Type Git Action", "color": "030406", "description": "GitHub Action / workflow" },
{ "name": "Type Pull Request", "color": "8F1784", "description": "Normal pull request" },
{ "name": "Type Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
{ "name": "Type Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
{ "name": "Build Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
{ "name": "Build Linux", "color": "c7ca4a", "description": "Specific to Linux" },
{ "name": "Build MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
{ "name": "Build Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
{ "name": "Build Web", "color": "c7ca4a", "description": "Specific to web" },
{ "name": "Build Windows", "color": "c7ca4a", "description": "Specific to Windows" },
{ "name": "AC Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
{ "name": "AC Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
{ "name": "AC Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
{ "name": "AC Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
{ "name": "AC Passed", "color": "146b4a", "description": "Ready to be reviewed" },
{ "name": "AC Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
{ "name": "AC Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
{ "name": "AC Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
{ "name": "Type Bug", "color": "9a2c2c", "description": "Something isn't working" },
{ "name": "Type Dependency", "color": "243759", "description": "Item is associated to dependency" },
{ "name": "Type Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
{ "name": "Type Feature", "color": "3c4e93", "description": "Feature request" },
{ "name": "Type Git Action", "color": "030406", "description": "GitHub Action / workflow" },
{ "name": "Type Pull Request", "color": "8F1784", "description": "Normal pull request" },
{ "name": "Type Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
{ "name": "Type Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
{ "name": "Build Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
{ "name": "Build Linux", "color": "c7ca4a", "description": "Specific to Linux" },
{ "name": "Build MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
{ "name": "Build Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
{ "name": "Build Web", "color": "c7ca4a", "description": "Specific to web" },
{ "name": "Build Windows", "color": "c7ca4a", "description": "Specific to Windows" },
{ "name": " API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
{ "name": " Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
{ "name": " Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
@@ -129,9 +116,7 @@ jobs:
issues-labels-create:
name: >-
🎫 Labels Create
# runs-on: ubuntu-latest
runs-on: apollo-x64
timeout-minutes: 3
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
@@ -148,20 +133,6 @@ jobs:
run: |
echo "Assigning labels and assignees"
# #
# Create Labels Set Env Variables
# #
- name: >-
🕛 Get Timestamp
id: task_label_set_timestamp
run: |
echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# [ Create Labels ] Checkout
# #
@@ -179,13 +150,11 @@ jobs:
- name: >-
🏷️ Verify Existing Labels
id: task_label_verify_existing
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
script: |
const labels = JSON.parse( process.env.LABELS_JSON );
let result = Object.keys(labels).length;
for ( const label of labels )
{
try
@@ -211,90 +180,3 @@ jobs:
}
}
}
console.log("[Success]: Added " + result + " labels to repo");
return result
# #
# Cleanup Get Weekly Commits
# #
- name: >-
🕛 Get Weekly Commit List
id: task_label_set_weekly_commit_list
run: |
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# #
# Cleanup Notify Github Success
# #
- name: >-
🔔 Send Discord Webhook Message (Success)
id: task_label_notify_discord_success
uses: tsickert/discord-webhook@v7.0.0
if: success()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 🎫 Labels Create ${{ job.status == 'success' && '✅' || '❌' }}
A **successful** workflow has been ran to generate labels for your repository.
**${{ steps.task_label_verify_existing.outputs.result }}** labels have been added.
- Labels: `${{ steps.task_label_verify_existing.outputs.result }} created`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
# #
# Cleanup Notify Github Failure
# #
- name: >-
🔔 Send Discord Webhook Message (Failure)
id: task_label_notify_discord_failure
uses: tsickert/discord-webhook@v7.0.0
if: failure()
with:
username: 'Io'
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
embed-title: "⚙️ ${{ github.workflow_ref }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
embed-description: |
## 🎫 Labels Create ${{ job.status == 'success' && '✅' || '❌' }}
A **failed** attempt was made to run this workflow. No new labels have been added to your repository.
- Labels: `${{ steps.task_label_verify_existing.outputs.result }} created`
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
- Runner: `${{ runner.name }}`
- Triggered By: `${{ github.actor }}`
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
embed-timestamp: "${{ env.NOW_LONG }}"
embed-author-name: "${{ github.repository_owner }}"
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"

175
.github/workflows/ping-developer.yml vendored Normal file
View File

@@ -0,0 +1,175 @@
# #
# @type github workflow
# @desc pings the developer
# @author Aetherinox
# @url https://github.com/Aetherinox
# #
name: "⚙️ Ping Developer"
run-name: "⚙️ Ping Developer"
# #
# triggers
# #
on:
issue_comment:
types: [created]
# #
# environment variables
# #
env:
BOT_NAME_1: AdminServ
BOT_NAME_2: AdminServX
BOT_NAME_3: EuropaServ
BOT_NAME_DEPENDABOT: dependabot[bot]
# #
# jobs
#
# env not available for job.if
# #
jobs:
deploy:
runs-on: ubuntu-latest
if: |
contains(github.event.comment.body, '/ping')
steps:
# #
# Job > Complete > Get publish timestamp
# #
- name: "🕛 Get Timestamp"
id: task_complete_timestamp_get
run: |
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
# #
# Add Label to accepted PR
#
# port 465
# server_port: 465
# secure: true
# ignore_cert: false
#
# port 587
# server_port: 587
# secure: false
# #
- name: Send mail
uses: dawidd6/action-send-mail@v4
with:
server_address: ${{secrets.EMAIL_SMTP}}
server_port: 465
secure: true
username: ${{secrets.EMAIL_FROM}}
password: ${{secrets.EMAIL_KEY}}
subject: "Github: Ping notification from ${{ github.repository }}"
to: ${{secrets.EMAIL_TO}}
from: ${{secrets.EMAIL_FROM}}
html_body: |
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Title</title>
<style>
body {
background: url('https://images.unsplash.com/photo-1541422348463-9bc715520974?fm=jpg&q=60&w=3000&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8ZGFyayUyMG1vdW50YWlufGVufDB8fDB8fHww');
font-size:9pt;
margin:0;
padding:0;
}
.background-overlay {
background-color: #1111119f;
}
.background-header {
background: url('https://process.fs.teachablecdn.com/ADNupMnWyR7kCWRvm76Laz/resize=width:705/https://cdn.filestackcontent.com/MipxnobQRRS5h7raz9aM');
background-size: cover;
background-size: 100%;
background-color:#1b1b1b;
padding:5px;
height:100px;
}
</style>
</head>
<body>
<div class="background-overlay">
<center>
<div class="background-header">
<a href="https://github.com/${{ github.repository }}"><img style="height:80px;padding-top:10px;" src="https://cdn0.iconfinder.com/data/icons/shift-logotypes/32/Github-512.png"></a>
</div>
</center>
<div style="font-size:9pt;padding: 20px;color:#FFF;">
<h3><span style="font-size:9pt;color:#cc6613;">[Github]</span> <span style="font-size:9pt;color:#FFF;">Dear ${{github.repository_owner}},</span></h3>
<p style="font-size:9pt;color:#FFF;"><br />You have received a ping notification from <a href="https://github.com/${{ github.repository }}">${{ github.repository }}</a> by <a href="https://github.com/${{ github.event.comment.user.login }}">${{ github.event.comment.user.login }}</a>.</p>
<br>
<br>
<center>
<table cellspacing="0" cellpadding="0" width="40%" class="center">
<tbody>
<tr>
<td
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Repository</b></td>
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#1b1b1b;padding-left:10px;">${{ github.repository }}</td>
</tr>
<tr>
<td
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Date</b></td>
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#0f0f0f;padding-left:10px;">${{ env.NOW }}</td>
</tr>
<tr>
<td
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Commenter</b></td>
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#1b1b1b;padding-left:10px;">${{ github.event.comment.user.login }}</td>
</tr>
<tr>
<td
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Issue #</b></td>
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#0f0f0f;padding-left:10px;">${{ github.event.issue.number }}</td>
</tr>
<tr>
<td
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Action</b></td>
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#1b1b1b;padding-left:10px;">Notification</td>
</tr>
</tbody>
</table>
</center>
<br><br>
<center>
<div style="font-family:Consolas;">
<textarea readonly=true style="font-size:9pt;width:60%;background-color:#363636;color:#FFF;padding:15px;border:1px solid #5a5a5a;" id="w3review" name="w3review" rows="20" cols="100">
${{ github.event.comment.body }}
</textarea>
</div>
</center>
<p>&nbsp;</p>
<p style="color:#FFF;"><br /> ~ Github
</p>
</div>
<br /><br />
<div style="background-color:#1b1b1b;padding:5px;line-height:70px;height:70px;text-align:center;">
<span style="color:#FFF;font-size:8pt;">Copyright &copy; 2024 - Betelgeuse</span>
</div>
</div>
</body>
</html>
ignore_cert: true
convert_markdown: true
priority: normal

View File

@@ -1,741 +0,0 @@
# #
# @type github workflow
# @author Aetherinox
# @url https://github.com/Aetherinox
# @usage publishes a new release on Github
#
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
# secrets.SELF_TOKEN_CL self github personal access token (classic)
# secrets.NPM_TOKEN self npmjs access token
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
#
# @local these workflows can be tested locally through the use of `act`
# https://github.com/nektos/act
# Extract act to folder
# Add system env var with path to act.exe
# Run the commands:
# git pull https://github.com/username/repo
# act -W .github/workflows/labels-create.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
# act -W .github/workflows/labels-create.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
# #
name: '📦 Release Github'
run-name: '📦 Release Github'
# #
# Triggers
# #
on:
workflow_dispatch:
inputs:
# #
# Name of the plugin to use when creating the release zip filename
# e.g: tvapp2-v1.0.0.zip
# #
PROJECT_NAME:
description: '📦 Name of App'
required: true
default: 'tvapp2'
type: string
# #
# ENABLE: the changelog generated in releases tab will only display single commits.
# DISABLE: the changelog shows pull requests completed based on their labels
# #
CHANGELOG_MODE_COMMIT:
description: '📑 Use Commits Instead of PRs'
required: true
default: true
type: boolean
# #
# ENABLE: Will show all types of commits, including uncategorized
# DISABLE: WIll only show actions that have been categorized using the format
# type(scope): description
# type: description
# #
SHOW_UNCATEGORIZED:
description: '🗂️ Show Uncategorized Commits'
required: true
default: false
type: boolean
# #
# ENABLE: released version will be marked as pre-release
# DISABLE: release version will be marked as stable / normal release
# #
PRERELEASE:
description: '🧪 Build RC (Pre-release)'
required: true
default: false
type: boolean
# #
# Release Candidate version number
# this will be added to the end of your released app in the releases page.
# e.g: tvapp2-v1.0.0-rc.1
# #
VERSION_RC:
description: '🧪 RC (Pre-release) Ver (tvapp2-rc.v1)'
required: false
type: string
default: '1'
# #
# environment variables
# #
env:
PROJECT_NAME: ${{ github.event.inputs.PROJECT_NAME || 'tvapp2' }}
CHANGELOG_MODE_COMMIT: true
SHOW_UNCATEGORIZED: false
PRERELEASE: false
VERSION_RC: '1'
ASSIGN_USER: Aetherinox
BOT_NAME_1: EuropaServ
BOT_NAME_2: BinaryServ
BOT_NAME_DEPENDABOT: dependabot[bot]
BOT_NAME_RENOVATE: renovate[bot]
# #
# Jobs
# #
jobs:
# #
# Jobs Initialize
# #
job-initialize:
name: >-
📦 Initialize
runs-on: ubuntu-latest
outputs:
package_version: ${{ steps.task_initialize_package_getversion.outputs.PACKAGE_VERSION }}
permissions:
contents: write
packages: write
steps:
# #
# Initialize Start
# #
- name: '✅ Start'
id: task_initialize_start
run: |
echo "Starting build"
# #
# Initialize Set Env Variables
# #
- name: >-
🕛 Get Timestamp
id: task_initialize_label_set_timestamp
run: |
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# Initialize Checkout
# #
- name: '☑️ Checkout'
id: task_initialize_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Initialize Set Package.json Version
# #
- name: '👁️‍🗨️ Package Version Set'
id: task_initialize_package_getversion
working-directory: ./tvapp2
run: |
VER=$(cat package.json | jq -r '.version')
echo "PACKAGE_VERSION=$VER" >> $GITHUB_OUTPUT
# #
# Initialize Get Package.json Version
# #
- name: '👁️‍🗨️ Package Version Get'
id: task_initialize_package_version_get
run: |
echo "VERSION: ${{ steps.task_initialize_package_getversion.outputs.PACKAGE_VERSION }}"
# #
# Job Release Github
# #
job-release:
name: >-
📦 Publish Release
runs-on: ubuntu-latest
needs: [ job-initialize ]
env:
PACKAGE_VERSION: ${{ needs.job-initialize.outputs.package_version }}
outputs:
guid: ${{ steps.task_release_dotenv_get.outputs.GUID }}
uuid: ${{ steps.task_release_dotenv_get.outputs.UUID }}
permissions:
contents: write
packages: write
steps:
# #
# Release Checkout
# #
- name: '☑️ Checkout'
id: task_release_checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# #
# Release Set Env Variables
# #
- name: >-
🕛 Get Timestamp
id: task_release_label_set_timestamp
run: |
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# Release Print Version Debug
# #
- name: '🪪 Test Next Job Version'
id: task_release_debug_print_ver
run: |
echo "VERSION: ${{ env.PACKAGE_VERSION }}"
# #
# Release Install package via NPM
# #
- name: '🪪 NPM Install & Lint'
id: task_release_npm_install
working-directory: ./tvapp2
run: |
npm ci
npm run lint
env:
NODE_AUTH_TOKEN: ${{ secrets.SELF_TOKEN_CL }}
# #
# Release Execute npm generate so that a uuid and guid can be created
# #
- name: '🪪 Generate IDs'
id: task_release_npm_env_generate
working-directory: ./tvapp2
run: |
npm run root:generate
# #
# Release .ENV Get
# Get guid and uuid from env variable generated by npm
# #
- name: '🪪 .ENV Get'
id: task_release_dotenv_get
uses: falti/dotenv-action@v1
with:
path: "./tvapp2/.env"
# #
# Release .ENV Print (Debug)
# Show guid and uuid from env variable generated by npm
# #
- name: '🪪 .ENV Read'
id: task_dotenv_debug_print
run: |
echo "GUID: ${{ steps.task_release_dotenv_get.outputs.GUID }}"
echo "UUID: ${{ steps.task_release_dotenv_get.outputs.UUID }}"
# #
# Release Build Stable
# #
- name: '🔨 Build Stable ( ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip )'
id: task_release_build_st
if: ${{ startsWith( inputs.PRERELEASE, false ) }}
run: |
echo Building STABLE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip Dockerfile Dockerfile.aarch64 docker-compose.yml docker-entrypoint.sh root/ tvapp2/package.json README.md LICENSE
echo Building STABLE Package ${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-docker-compose.zip
zip -r ${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-docker-compose.zip docker-compose.yml README.md LICENSE
env:
NODE_AUTH_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
# #
# Release Build Release Candidate
# #
- name: '🔨 Build RC ( ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip )'
id: task_release_build_rc
if: ${{ startsWith( inputs.PRERELEASE, true ) }}
run: |
echo Building PRE-RELEASE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip Dockerfile Dockerfile.aarch64 docker-compose.yml docker-entrypoint.sh root/ tvapp2/package.json README.md LICENSE
echo Building PRE-RELEASE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip docker-compose.yml README.md LICENSE
env:
NODE_AUTH_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
# #
# Release Tag Pre Create
#
# in order to use the changelog github action, you must pre-create the tag otherwise
# the changelog action will have no idea what tag you are going to be creating and
# the list of commits will not be for the correct release.
# #
- name: '🔖 Tag Pre Create ${{ env.PACKAGE_VERSION }}'
id: task_release_tag_create
uses: rickstaa/action-create-tag@v1
with:
tag: ${{ env.PACKAGE_VERSION }}
tag_exists_error: false
message: "Latest release"
gpg_private_key: ${{ secrets.ADMINSERV_GPG_KEY_ASC }}
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
# #
# Release Tag Confirm
#
# check if tag already exists
# #
- name: '🔖 Tag Confirm ${{ env.PACKAGE_VERSION }}'
id: task_release_tag_get
run: |
echo "Tag already present: ${{ env.TAG_EXISTS }}"
echo "Tag already present: ${{ steps.task_release_tag_create.outputs.tag_exists }}"
# #
# Release Checksum Stable
# #
- name: '🆔 Checksum Stable'
id: task_release_checksum_st_set
if: ${{ startsWith( inputs.PRERELEASE, false ) }}
run: |
filename_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip"
sha256="$(shasum --algorithm 256 ${filename_zip} | awk '{ print $1 }')"
shasum --algorithm 256 ${filename_zip} > SHA256SUMS.txt
echo "FILE_ZIP=${filename_zip}" >> $GITHUB_ENV
echo "SHA256SUM=${sha256}" >> $GITHUB_ENV
filename_compose_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-docker-compose.zip"
sha256_compose="$(shasum --algorithm 256 ${filename_compose_zip} | awk '{ print $1 }')"
echo "FILE_COMPOSE_ZIP=${filename_compose_zip}" >> $GITHUB_ENV
# #
# Release Checksum Release Candidate
# #
- name: '🆔 Checksum RC'
id: task_release_checksum_rc_set
if: ${{ startsWith( inputs.PRERELEASE, true ) }}
run: |
filename_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip"
sha256="$(shasum --algorithm 256 ${filename_zip} | awk '{ print $1 }')"
shasum --algorithm 256 ${filename_zip} > SHA256SUMS.txt
echo "FILE_ZIP=${filename_zip}" >> $GITHUB_ENV
echo "SHA256SUM=${sha256}" >> $GITHUB_ENV
filename_compose_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip"
sha256_compose="$(shasum --algorithm 256 ${filename_compose_zip} | awk '{ print $1 }')"
echo "FILE_COMPOSE_ZIP=${filename_compose_zip}" >> $GITHUB_ENV
# #
# Release Checksum Print
# #
- name: '🆔 Checksum Print'
id: task_release_checksum_st_get
run: |
echo "${{ env.SHA256SUM }}"
# #
# Release Contributor Images
# #
- name: '🥸 Contributors Generate'
id: task_release_contribs_generate
uses: jaywcjlove/github-action-contributors@main
with:
filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\])
output: CONTRIBUTORS.svg
avatarSize: 42
# #
# Release Checksum Add (Stable)
# #
- name: '📦 Zip Add Checksum Stable'
id: task_release_zip_st
if: ${{ startsWith( inputs.PRERELEASE, false ) }}
run: |
echo Zipping STABLE Package .zip ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
zip -jr ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip SHA256SUMS.txt
ls
# #
# Release Checksum Add (Release Candidate)
# #
- name: '📦 Zip Add Checksum RC'
id: task_release_zip_rc
if: ${{ startsWith( inputs.PRERELEASE, true ) }}
run: |
echo Zipping PRE-RELEASE Package .zip ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip
zip -jr ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip SHA256SUMS.txt
ls
# #
# Release Generate Tags
# #
- name: '📝 Changelog Pre Setup (Categorized Commits)'
id: task_release_changelog_categorized_sha_set
run: |
echo "TAG_LAST=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
echo "COMMIT_LAST=$(git rev-parse HEAD)" >> $GITHUB_ENV
# #
# Release Changelog Build (Categorized)
#
# generates a changelog from the github api. requires a TAG_LAST in order to figure
# out the changes made between the two versions.
#
# outputs:
# ${{ steps.task_release_changelog_categorized.outputs.changelog }}
# #
- name: '📝 Changelog Build (Categorized)'
id: task_release_changelog_categorized
if: |
startsWith( inputs.SHOW_UNCATEGORIZED, false ) ||
startsWith( env.SHOW_UNCATEGORIZED, false )
uses: mikepenz/release-changelog-builder-action@v5
with:
token: ${{ secrets.ADMINSERV_TOKEN }}
#fromTag: "${{ env.TAG_LAST }}"
#toTag: "${{ github.ref }}"
configuration: ".github/changelog-configuration.json"
ignorePreReleases: false
commitMode: ${{ inputs.CHANGELOG_MODE_COMMIT || env.CHANGELOG_MODE_COMMIT }}
fetchReleaseInformation: true
fetchViaCommits: true
configurationJson: |
{
"template": "## Release Info \n| Item | Value |\n| --- | --- |\n|<sub>📄 ${{ env.FILE_ZIP }}</sub>|<sub>Contains TVApp2 node source code and Docker build kit</sub>|\n|<sub>📄 ${{ env.FILE_COMPOSE_ZIP }}</sub>|<sub>Contains `docker-compose.yml`</sub>|\n|<sub>🏷️ SHA256</sub>|<sub>`${{ env.SHA256SUM }}`</sub>|\n|<sub>🏷️ GUID</sub>|<sub>`${{ steps.task_release_dotenv_get.outputs.GUID }}`</sub>|\n|<sub>🏷️ UUID</sub>|<sub>`${{ steps.task_release_dotenv_get.outputs.UUID }}`</sub>|\n|<sub>🕟 Stamp</sub>|<sub>`#{{FROM_TAG}}-#{{FROM_TAG_DATE}} 🔺 #{{TO_TAG}}-#{{TO_TAG_DATE}}`</sub>|\n|<sub>📅 Last Release</sub>|<sub>`#{{DAYS_SINCE}} days ago`</sub>|\n\n<br>\n\n---\n\n<br>\n\n### What's New\nThis release contains the following changes:\n\n<br>\n\n---\n\n<br>\n\n### Statistics\nHow the files have changed:\n<ul><li><a href='#{{RELEASE_DIFF}}'>Changed files</a> : <b>#{{CHANGED_FILES}}</b></li><li>Changes : <b>#{{CHANGES}}</b></li><li>Commits : <b>#{{COMMITS}}</b></li><li>Additions : <b>#{{ADDITIONS}}</b></li><li>Deletions : <b>#{{DELETIONS}}</b></li><li>PRs (categorized) : <b>#{{CATEGORIZED_COUNT}}</b></li><li>PRs (uncategorized) : <b>#{{UNCATEGORIZED_COUNT}}</b></li><li>PRs (open) : <b>#{{OPEN_COUNT}}</b></li>\n<br />\n</ul>\n\n<br>\n\n---\n\n<br>\n\n### Pull Requests\nThis release is associated with the following pull requests:\n#{{CHANGELOG}}\n\n<br>\n\n---\n\n<br>\n\n"
}
env:
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
# #
# Release Changelog Build (Uncategorized)
#
# generates a changelog from the github api. requires a TAG_LAST in order to figure
# out the changes made between the two versions.
#
# outputs:
# ${{ steps.task_release_changelog_categorized.outputs.changelog }}
#
# shows only categorized commits using the commit standards
# type(scope): description
# type: description
# #
- name: '📝 Changelog Build (Uncategorized)'
id: task_release_changelog_uncategorized
if: |
startsWith( inputs.SHOW_UNCATEGORIZED, true ) ||
startsWith( env.SHOW_UNCATEGORIZED, true )
uses: mikepenz/release-changelog-builder-action@v5
with:
token: ${{ secrets.ADMINSERV_TOKEN }}
#fromTag: "${{ env.TAG_LAST }}"
#toTag: "${{ github.ref }}"
configuration: ".github/changelog-configuration.json"
ignorePreReleases: false
commitMode: ${{ inputs.CHANGELOG_MODE_COMMIT || env.CHANGELOG_MODE_COMMIT }}
fetchReleaseInformation: true
fetchViaCommits: true
configurationJson: |
{
"template": "## Release Info \n| Item | Value |\n| --- | --- |\n|<sub>📄 ${{ env.FILE_ZIP }}</sub>|<sub>Contains TVApp2 node source code and Docker build kit</sub>|\n|<sub>📄 ${{ env.FILE_COMPOSE_ZIP }}</sub>|<sub>Contains `docker-compose.yml`</sub>|\n|<sub>🏷️ SHA256</sub>|<sub>`${{ env.SHA256SUM }}`</sub>|\n|<sub>🏷️ GUID</sub>|<sub>`${{ steps.task_release_dotenv_get.outputs.GUID }}`</sub>|\n|<sub>🏷️ UUID</sub>|<sub>`${{ steps.task_release_dotenv_get.outputs.UUID }}`</sub>|\n|<sub>🕟 Stamp</sub>|<sub>`#{{FROM_TAG}}-#{{FROM_TAG_DATE}} 🔺 #{{TO_TAG}}-#{{TO_TAG_DATE}}`</sub>|\n|<sub>📅 Last Release</sub>|<sub>`#{{DAYS_SINCE}} days ago`</sub>|\n\n<br>\n\n---\n\n<br>\n\n### What's New\nThis release contains the following changes:\n\n<br>\n\n---\n\n<br>\n\n### Statistics\nHow the files have changed:\n<ul><li><a href='#{{RELEASE_DIFF}}'>Changed files</a> : <b>#{{CHANGED_FILES}}</b></li><li>Changes : <b>#{{CHANGES}}</b></li><li>Commits : <b>#{{COMMITS}}</b></li><li>Additions : <b>#{{ADDITIONS}}</b></li><li>Deletions : <b>#{{DELETIONS}}</b></li><li>PRs (categorized) : <b>#{{CATEGORIZED_COUNT}}</b></li><li>PRs (uncategorized) : <b>#{{UNCATEGORIZED_COUNT}}</b></li><li>PRs (open) : <b>#{{OPEN_COUNT}}</b></li>\n<br />\n</ul>\n\n<br>\n\n---\n\n<br>\n\n### Commits (#{{UNCATEGORIZED_COUNT}})\nThe following commits are uncategorized:\n#{{UNCATEGORIZED}}\n\n<br>\n\n---\n\n<br>\n\n### Pull Requests\nThis release is associated with the following pull requests:\n#{{CHANGELOG}}\n\n<br>\n\n"
}
env:
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
# #
# Release Changelog Convert step into ENV
#
# This is a requirement in order for the action mikepenz/release-changelog-builder-action@v5 to work properly.
# If you use special characters like quotes and tildes in your push comments, bash will have no way of knowing
# if it's part of the changelog, or code itself.
#
# By converting the step into an env var, we quote the text, and it fixes the issue.
#
# For every step that you need to print the changelog text, first define the env var
# env:
# CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
#
# Then you can call the changelog in the body / run command with
# echo "$CHANGELOG_CATEGORIZED"
# #
- name: '🙊 Changelog Step to Env Categorized'
id: task_release_changelog_escape_categorized
if: |
startsWith( inputs.SHOW_UNCATEGORIZED, false ) ||
startsWith( env.SHOW_UNCATEGORIZED, false )
env:
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
run: |
echo "$CHANGELOG_CATEGORIZED"
- name: '🙊 Changelog Step to Env Uncategorized'
id: task_release_changelog_escape_uncategorized
if: |
startsWith( inputs.SHOW_UNCATEGORIZED, true ) ||
startsWith( env.SHOW_UNCATEGORIZED, true )
env:
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
run: |
echo "$CHANGELOG_UNCATEGORIZED"
# #
# Release List Tree
# #
- name: '⚙️ Debug Tree Listing'
id: task_release_debug_tree
run: |
tree
# #
# Release Post Release (Stable)
#
# outputs:
# [RELEASE ID]:
# ${{ steps.task_release_bundle_rc.outputs.id
# ${{ steps.task_release_bundle_st.outputs.id
# #
- name: '🏳️ Post Stable'
id: task_release_bundle_st
if: |
startsWith( inputs.PRERELEASE, false ) ||
startsWith( env.PRERELEASE, false )
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
with:
token: ${{ secrets.ADMINSERV_TOKEN_CL }}
name: v${{ env.PACKAGE_VERSION }}
tag_name: ${{ env.PACKAGE_VERSION }}
target_commitish: ${{ github.event.inputs.branch }}
draft: false
generate_release_notes: false
files: |
${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-docker-compose.zip
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
SHA256SUMS.txt
prerelease: false
body: |
${{ steps.task_release_changelog_categorized.outputs.changelog }}
${{ steps.task_release_changelog_uncategorized.outputs.changelog }}
# #
# Release Post Release (Release Candidate)
#
# outputs:
# [RELEASE ID]:
# ${{ steps.task_release_bundle_rc.outputs.id
# ${{ steps.task_release_bundle_st.outputs.id
# #
- name: "🏳️ Post Release Candidate"
id: task_release_bundle_rc
if: |
startsWith( inputs.PRERELEASE, true ) ||
startsWith( env.PRERELEASE, true )
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
with:
token: ${{ secrets.ADMINSERV_TOKEN }}
name: v${{ env.PACKAGE_VERSION }}
tag_name: ${{ env.PACKAGE_VERSION }}
target_commitish: ${{ github.event.inputs.branch }}
draft: false
generate_release_notes: false
files: |
${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip
SHA256SUMS.txt
prerelease: false
body: |
> [!WARNING]
> This is a **release candidate**, which means it is not a stable release and could contain bugs. You should download it at your own risk.
${{ steps.task_release_changelog_categorized.outputs.changelog }}
${{ steps.task_release_changelog_uncategorized.outputs.changelog }}
# #
# Release Print Status
#
# For every step that you need to print the changelog text, first define the env var
# env:
# CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
#
# Then you can call the changelog in the body / run command with
# echo "$CHANGELOG_CATEGORIZED"
# #
- name: "🎛️ Status Print"
id: task_release_status_print
env:
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
run: |
echo "Printing Variables"
echo
echo "---- CHANGELOG ---------------------------------------------------------------"
echo "$CHANGELOG_CATEGORIZED"
echo "$CHANGELOG_UNCATEGORIZED"
echo "---- CHANGELOG ---------------------------------------------------------------"
echo ""
echo ""
echo "---- VARIABLES ---------------------------------------------------------------"
echo "Package Version ............ ${{ env.PACKAGE_VERSION }}"
echo "Tag: Previous .............. ${{ env.TAG_LAST }}"
echo "Tag: Now.... ............... ${{ github.ref }}"
echo "Last Commit ................ ${{ env.COMMIT_LAST }}"
echo "ST Output ID ............... ${{ steps.task_release_bundle_st.outputs.id }}"
echo "RC Output ID ............... ${{ steps.task_release_bundle_rc.outputs.id }}"
echo "---- CHANGELOG ---------------------------------------------------------------"
# #
# Release Upload Artifacts Release Files
# #
- name: >-
📋 Upload Artifacts ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
id: task_release_artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: "${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}"
path: ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
retention-days: 30
# #
# Job Complete
# #
job-complete:
name: >-
🆗 Successful Deployment
runs-on: ubuntu-latest
needs: [ job-initialize, job-release ]
env:
PACKAGE_VERSION: ${{ needs.job-initialize.outputs.package_version }}
GUID: ${{ needs.job-release.outputs.guid }}
UUID: ${{ needs.job-release.outputs.uuid }}
steps:
# #
# Complete Download Artifacts
# #
- name: "📁 Download Saved Artifacts"
id: task_complete_artifacts_download
uses: actions/download-artifact@v4
# #
# Complete Get publish timestamp
# #
- name: >-
🕛 Get Timestamp
id: task_complete_timestamp_get
run: |
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
# #
# Complete Set ENVs
# #
- name: "🕛 Get Env Vars"
id: task_complete_set_envs
run: |
release_stable_file="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}/${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip"
release_stable_sha256="$(shasum --algorithm 256 ${release_stable_file} | awk '{ print $1 }')"
echo "FILE_STABLE=${release_stable_file}" >> $GITHUB_ENV
echo "SHA_STABLE=${release_stable_sha256}" >> $GITHUB_ENV
# #
# Complete Summary of publish
# #
- name: "🆗 Completed: ${{ env.NOW }}"
id: task_complete_summary
run: |
echo ""
echo ""
echo "| File | Result |" >> $GITHUB_STEP_SUMMARY
echo "| ------------------------------- | ----------------------- |" >> $GITHUB_STEP_SUMMARY
echo "| 📦 **Project** | ${{ env.PROJECT_NAME }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🕛 **Deploy Time** | ${{ env.NOW }} |" >> $GITHUB_STEP_SUMMARY
echo ""
echo "### 📄 File (${{ env.FILE_STABLE }}) " >> $GITHUB_STEP_SUMMARY
echo "This is the main release. It contains all required docker files, and the TVApp2 `package.json`" >> $GITHUB_STEP_SUMMARY
echo "| File | Result |" >> $GITHUB_STEP_SUMMARY
echo "| ------------------------------- | ----------------------- |" >> $GITHUB_STEP_SUMMARY
echo "| 🏷️ **SHA256** | ${{ env.SHA_STABLE }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🏷️ **GUID** | ${{ env.GUID }} |" >> $GITHUB_STEP_SUMMARY
echo "| 🏷️ **UUID** | ${{ env.UUID }} |" >> $GITHUB_STEP_SUMMARY

316
.gitignore vendored Executable file → Normal file
View File

@@ -1,322 +1,64 @@
# #
# Dependency directories
# Windows image file caches
# #
node_modules/
jspm_packages/
Thumbs.db
ehthumbs.db
# #
# Snowpack dependency directory (https://snowpack.dev/)
# Folder config file
# #
web_modules/
Desktop.ini
# #
# TypeScript cache
# Recycle Bin used on file shares
# #
\*.tsbuildinfo
$RECYCLE.BIN/
# #
# Optional npm cache directory
# Windows Installer files
# #
.npm
*.cab
*.msi
*.msm
*.msp
# #
# npm files
# Windows shortcuts
# #
.npmrc
*.lnk
# #
# Optional eslint cache
# Operating System Files
# #
.eslintcache
.DS_Store
.AppleDouble
.LSOverride
# #
# Optional stylelint cache
# Thumbnails
# #
.stylelintcache
._*
# #
# Microbundle cache
# Other
# #
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
.Spotlight-V100
.Trashes
# #
# Optional REPL history
# Directories potentially created on remote AFP share
# #
.node_repl_history
# #
# Output of 'npm pack'
# #
\*.tgz
# #
# Yarn Integrity file
# #
.yarn-integrity
# #
# Binaries
# #
*.exe
*.exe~
*.dll
*.so
*.dylib
# #
# TVApp2 Specific
# #
*.dat
*.xml
*.txt
# #
# Test binary
# build with `go test -c`
# #
*.test
# #
# Coverage directory used by tools like istanbul
# #
coverage
\*.lcov
*.out
# #
# nyc test coverage
# #
.nyc_output
# #
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
# #
.grunt
# #
# Bower dependency directory (https://bower.io/)
# #
bower_components
# #
# node-waf configuration
# #
.lock-wscript
# #
# Compiled binary addons (https://nodejs.org/api/addons.html)
# #
build/Release
# #
# Dependency directories (remove the comment below to include it)
# vendor/
# #
# #
# Go workspace file
# #
go.work
# #
# Mac
# #
.DS_STORE
# #
# Visual Studio Code
# #
.vscode/
# #
# Temp folders
# #
.temp/
temp/
work/
# #
# Python Cache
# #
__pycache__/
# #
# Logs
# #
logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# #
# yarn v2
# #
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.\*
# #
# wrangler project
# #
.dev.vars
.wrangler/
# #
# sources
# #
.src
# #
# dist
# #
.dist
# #
# Private Files
# #
.dev
keys
# #
# dotenv environment variable files
# #
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# #
# parcel-bundler cache (https://parceljs.org/)
# #
.cache
.parcel-cache
# #
# Next.js build output
# #
.next
# #
# Nuxt.js build / generate output
# #
.nuxt
# #
# vuepress build output
# #
.vuepress/dist
# #
# Docusaurus cache and generated files
# #
.docusaurus
# #
# Serverless directories
# #
.serverless/
# #
# FuseBox cache
# #
.fusebox/
# #
# DynamoDB Local files
# #
.dynamodb/
# #
# TernJS port file
# #
.tern-port
# #
# Gatsby files
# #
.cache/
# #
# Misc
# #
tmp
*.user
# #
# Python files
# #
.opt-*
# #
# Diagnostic reports (https://nodejs.org/api/report.html)
# #
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# #
# Runtime data
# #
pids
_.pid
_.seed
\*.pid.lock
# #
# Directory for instrumented libs generated by jscoverage/JSCover
# #
lib-cov
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

View File

@@ -1,58 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
<br />
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
<br />
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
<br />
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
<br />
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
<br />
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at `thebinaryninja [at] proton [dot] me`. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
<br />
## Attribution
This Code of Conduct is adapted from the [📄 Contributor Covenant][homepage], version 2.1, available at [https://contributor-covenant.org/version/2/1/][version]
[homepage]: http://contributor-covenant.org
[version]: https://www.contributor-covenant.org/version/2/1/

View File

@@ -1,11 +1,12 @@
<div align="center">
<h6>Contribution Guidelines for BinaryNinja Applications</h6>
<h6>Thank you for your interest in contributing!</h6>
<h1>♾️ Contributing ♾️</h1>
<br />
<!-- prettier-ignore-start -->
[![Version][github-version-img]][github-version-uri]
[![Build Status][github-build-img]][github-build-uri]
[![Downloads][github-downloads-img]][github-downloads-uri]
[![Size][github-size-img]][github-size-img]
[![Last Commit][github-commit-img]][github-commit-img]
@@ -40,26 +41,11 @@ Please review everything on this page before you submit your contribution.
- [Types](#types)
- [Example 1:](#example-1)
- [Example 2:](#example-2)
- [Committing](#committing)
- [Languages](#languages)
- [Python](#python)
- [Indentation](#indentation)
- [Line Length](#line-length)
- [Blank Lines](#blank-lines)
- [Imports](#imports)
- [Commenting](#commenting)
- [Casing](#casing)
- [NodeJS](#nodejs)
- [Prettier](#prettier)
- [ESLint](#eslint)
- [v9 \& Newer (Config)](#v9--newer-config)
- [v8 \& Older (Config)](#v8--older-config)
- [Packages](#packages)
- [Indentation](#indentation-1)
- [Style](#style)
- [Line Length](#line-length-1)
- [Commenting](#commenting-1)
- [Casing](#casing-1)
- [Commiting](#commiting)
- [Commenting](#commenting)
- [Casing](#casing)
- [Indentation Style](#indentation-style)
- [Spaces Instead Of Tabs](#spaces-instead-of-tabs)
<br />
@@ -68,16 +54,15 @@ Please review everything on this page before you submit your contribution.
<br />
## Issues, Bugs, Ideas
Stuff happens, and sometimes as best as we try, there may be issues within this project that we are unaware of. That is the great thing about open-source; anyone can use the program and contribute to making it better.
<br />
If you have found a bug, have an issue, or maybe even a cool idea; you can let us know by [submitting it](https://github.com/thebinaryninja/tvapp2/issues). However, before you submit your new issue, bug report, or feature request; head over to the [Issues Section](https://github.com/thebinaryninja/tvapp2/issues) and ensure nobody else has already submitted it.
If you have found a bug, have an issue, or maybe even a cool idea; you can let us know by [submitting it](https://github.com/aetherinox/thetvapp-docker/issues). However, before you submit your new issue, bug report, or feature request; head over to the [Issues Section](https://github.com/aetherinox/thetvapp-docker/issues) and ensure nobody else has already submitted it.
<br />
Once you are sure that your issue has not already being dealt with; you may submit a new issue at [here](https://github.com/thebinaryninja/tvapp2/issues/new/choose). You'll be asked to specify exactly what your new submission targets, such as:
Once you are sure that your issue has not already being dealt with; you may submit a new issue at [here](https://github.com/aetherinox/thetvapp-docker/issues/new/choose). You'll be asked to specify exactly what your new submission targets, such as:
- Bug report
- Feature Suggestion
@@ -117,10 +102,9 @@ If you are submitting a bug report:
<br />
## Contributing
If you are looking to contribute to this project by actually submit your own code; please review this section completely. There is important information and policies provided below that you must follow for your pull request to get accepted.
The source is here for everyone to collectively share and collaborate on. If you think you have a possible solution to a problem; don't be afraid to get your hands dirty.
The source is here for everyone to collectively share and colaborate on. If you think you have a possible solution to a problem; don't be afraid to get your hands dirty.
All contributions are made via pull requests. To create a pull request, you need a GitHub account. If you are unclear on this process, see [GitHub's documentation on forking and pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). Pull requests should be targeted at the master branch.
@@ -135,7 +119,7 @@ All contributions are made via pull requests. To create a pull request, you need
- When submitting your Pull Request, use one of the following branches:
- For bug fixes: `main` branch
- For features & functionality: `development` branch
- Include a proper git commit message following the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification).
- Include a proper git commit message following the [Conventional Commit Specification](https://www.conventionalcommits.org/en/v1.0.0/#specification).
<br />
@@ -147,7 +131,7 @@ Reviewers will approve the pull request once they are satisfied with the patch i
### Conventional Commit Specification
When committing your changes, we require you to follow the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification). The **Conventional Commits** is a specification for the format and content of a commit message. The concept behind Conventional Commits is to provide a rich commit history that can be read and understood by both humans and automated tools. Conventional Commits have the following format:
When commiting your changes, we require you to follow the [Conventional Commit Specification](https://www.conventionalcommits.org/en/v1.0.0/#specification). The **Conventional Commits** is a specification for the format and content of a commit message. The concept behind Conventional Commits is to provide a rich commit history that can be read and understood by both humans and automated tools. Conventional Commits have the following format:
<br />
@@ -162,24 +146,24 @@ When committing your changes, we require you to follow the [Conventional Commit
<br />
#### Types
Our repositories make use of the following commit tags:
<br />
| Type | Description |
| --- | --- |
| `feat` | Introduce new feature |
| `fix` | Bug fix |
| `chore` | Includes technical or preventative maintenance task that is necessary for managing the app or repo, such as updating grunt tasks, but is not tied to any specific feature. Usually done for maintenance purposes.<br/>E.g: Edit .gitignore, .prettierrc, .prettierignore, .gitignore, eslint.config.js file |
| `revert` | Revert a previous commit |
| `style` | Update / reformat style of source code. Does not change the way app is implemented. Changes that do not affect the meaning of the code<br />E.g: white-space, formatting, missing semi-colons, change tabs to spaces, etc) |
| `docs` | Change website or markdown documents. Does not mean changes to the documentation generator script itself, only the documents created from the generator. <br/>E.g: documentation, readme.md or markdown |
| `build` | Changes to the build / compilation / packaging process or auxiliary tools such as doc generation<br />E.g: create new build tasks, update release script, etc. |
| `refactor` | Change to production code that leads to no behavior difference,<br/>E.g: split files, rename variables, rename package, improve code style, etc. |
| `deps` | Add or update existing dependencies |
| `docs` | Change website or markdown documents. Does not mean changes to the documentation generator script itself, only the documents created from the generator. <br/><br/><small>E.g: documentation, readme.md or markdown</small> <br /><br /> |
| `build` | Changes to the build / compilation / packaging process or auxiliary tools such as doc generation<br /><br/><small>E.g: create new build tasks, update release script, etc.</small> |
| `test` | Add or refactor tests, no production code change. Changes the suite of automated tests for the app. |
| `ci` | Changes related to Continuous Integration (usually `yml` and other configuration files). |
| `perf` | Performance improvement of algorithms or execution time of the app. Does not change an existing feature. |
| `style` | Update / reformat style of source code. Does not change the way app is implemented. Changes that do not affect the meaning of the code<br /><br/><small>E.g: white-space, formatting, missing semi-colons, change tabs to spaces, etc)</small> |
| `refactor` | Change to production code that leads to no behavior difference,<br/><br/><small>E.g: split files, rename variables, rename package, improve code style, etc.</small> |
| `change` | Change an existing feature. |
| `chore` | Includes technical or preventative maintenance task that is necessary for managing the app or repo, such as updating grunt tasks, but is not tied to any specific feature. Usually done for maintanence purposes.<br/><br/><small>E.g: Edit .gitignore, .prettierrc, .prettierignore, .gitignore, eslint.config.js file</small> |
| `ci` | Changes related to Continuous Integration (usually `yml` and other configuration files). |
| `misc` | Anything that doesn't fit into another commit type. Usually doesn't change production code; yet is not ci, test or chore. |
| `revert` | Revert a previous commit |
| `remove` | Remove a feature from app. Features are usually first deprecated for a period of time before being removed. Removing a feature from the app may be considered a breaking change that will require a major version number increment.|
| `deprecate` | Deprecate existing functionality, but does not remove it from the app.|
<br />
@@ -191,17 +175,16 @@ feat(core): bug affecting menu [#22]
| | | |
| | | └───⫸ (ISSUE): Reference issue ID
│ │ │
│ │ └──────────────────────⫸ (DESC): Summary in present tense. Use lower case not title case!
│ │ └───⫸ (DESC): Summary in present tense. Use lower case not title case!
│ │
│ └──────────────────────────────⫸ (SCOPE): The package(s) that this change affects
│ └───────────⫸ (SCOPE): The package(s) that this change affects
└──────────────────────────────────⫸ (TYPE): See list above
└───────────────⫸ (TYPE): See list above
```
<br />
##### Example 2:
```
<type>(<scope>): <short summary> [issue]
| | | |
@@ -221,8 +204,7 @@ feat(core): bug affecting menu [#22]
<br />
### Committing
### Commiting
If you are pushing a commit which addresses a submitted issue, reference your issue at the end of the commit message. You may also optionally add the major issue to the end of your commit body.
References should be on their own line, following the word `Ref` or `Refs`
@@ -234,333 +216,96 @@ Description: The description of your commit
Ref: #22, #34, #37
```
<br />
<br />
### Languages
### Commenting
The formatting of code greatly depends on the language being used for this repository. We provide various different languages below as this guide is utilized across multiple repositories.
Comment your code. If someone else comes along, they should be able to do a quick glance and have an idea of what is going on. Plus it helps novice readers to better understand the process.
- [Python](#python)
- [Javascript / Typescript / NodeJS](#nodejs)
You may use block style commenting, or single lines:
<br />
<br />
#### Python
The following guidelines apply to any projects written with Python:
<br />
##### Indentation
Use `4 spaces` per indentation level.
<br />
> [!TIP]
> ✅ Correct
> ```python
> def Encrypt( key : int, bytestr : bytes ):
> res = b''
> i_blk, left_bytes = divmod( len(bytestr), 3 )
> ```
<br />
> [!CAUTION]
> ❌ Wrong
> ```python
> def encrypt( key : int, byteStr : bytes ):
> Res = b''
> iBlk, leftBytes = divmod( len(byteStr), 3 )
> ```
<br />
##### Line Length
Keep the maximum character count to `100 characters per line`. If you are revising old code which doesn't follow this guideline; please rewrite it to conform.
<br />
##### Blank Lines
Surround top-level functions and class definitions with a blank in-between.
Method definitions inside a class are surrounded by a single blank line.
Extra blank lines may be used (sparingly) to separate groups of functions related to one another. Blank lines may be omitted between a bunch of related one-liners (e.g: set of dummy implementations).
<br />
##### Imports
Imports should usually be on separate lines:
<br />
> [!TIP]
> ✅ Correct
> ```python
> import os
> import sys
> ```
<br />
> [!CAUTION]
> ❌ Wrong
> ```python
> import sys, os
> ```
<br />
The following is acceptable:
<br />
> [!TIP]
> ✅ Correct
> ```python
> from mypkg import siblingA, siblingB, siblingC
> ```
<br />
##### Commenting
Comment your code. It helps novice readers to better understand the process. It doesn't have to be painfully obvious explanations, but it helps to give an idea of what something does.
Please append `#` to the beginning of each line.
```python
```bash
# #
# byteString : b'1#Aetherx|232#1#233262#0#0#0#'
# set perms and import user crontabs
# #
def Encrypt( key : int, byteString : bytes ):
res = bytearray( )
checkown "${cron_user}":"${cron_user}" "/config/crontabs/${cron_user}"
crontab -u "${cron_user}" "/config/crontabs/${cron_user}"
```
<br />
<br />
At the top of any new file introduced, please add the following header:
##### Casing
```bash
#!/usr/bin/with-contenv bash
# shellcheck shell=bash
- Stick to `camelCase`; unless:
- naming functions, capitalize the first letter
- Capitalize enums
- If you see code not conforming with this, please revise it in your pull request.
# #
# @project thetvapp-docker
# @about DESCRIPTION OF WHAT FILE DOES
# @file /path/to/file.ext
# @repo https://github.com/Aetherinox/thetvapp-docker
# #
```
<br />
> [!TIP]
> ✅ Correct
> ```python
> def Encrypt( key : int, byteStr : bytes ):
> res = b''
> iBlock, leftBytes = divmod( len(byteStr), 3 )
> ```
### Casing
When calling environment variables, you should use `UPPERCASE`:
```bash
arg_cron=$(echo ${CRON_TIME})
if [ -z "${arg_cron}" ]; then
arg_cron="0/60 * * * *"
fi
```
<br />
> [!CAUTION]
> ❌ Wrong
> ```python
> def encrypt( key : int, bytestr : bytes ):
> res = b''
> i_blk, left_bytes = divmod( len(bytestr), 3 )
> ```
When defining general variables, use `snake_case`
```bash
migrations_dir="/migrations"
migrations_history="/config/.migrations"
```
<br />
<br />
<div align="center">
**[`^ back to top ^`](#about)**
</div>
<br />
---
<br />
#### NodeJS
The following allows you to configure ESLint and Prettier.
<br />
<br />
##### Prettier
We have opted to make use of [ESLint](#eslint) over Prettier. We provide a detailed ESLint flag config file with very specific linting rules. Please review that section for more information.
<br />
<br />
##### ESLint
Within the root folder of the repo, there are several configuration files which you should be using within the project. These files dictate how prettier and eslint will behave and what is acceptable / not acceptable.
<br />
Pick the config file below depending on which version of ESLint you are using. The v8 and older `.eslint` may not be there if we have migrated over to an Eslint v9 flat config file:
<br />
###### v9 & Newer (Config)
Our NodeJS applications require that you utilize ESLint v9 or newer which makes use of a flat config structure. You may find a copy of our flat config at the link below:
- [📄 eslint.config.mjs](https://github.com/thebinaryninja/tvapp2/blob/main/tvapp2/eslint.config.mjs)
<br />
###### v8 & Older (Config)
- We no longer utilize any version of ESLint older than version 9.
<br />
<br />
> [!NOTE]
> When submitting your pull request, these linting and style rules will be verified with all of your files. If you did not follow these rules; the linter tests on your pull request will fail; and you'll be expected to correct these issues before your submission will be transferred over for human review.
<br />
<br />
##### Packages
We use the following packages for linting and prettier.
<br />
| Package | Repo File | Description |
| --- | --- | --- |
| [@stylistic/eslint-plugin-js](https://npmjs.com/package/@stylistic/eslint-plugin-js) | [package.json](./package.json) | JavaScript stylistic rules for ESLint, migrated from eslint core. |
| [@stylistic/eslint-plugin-ts](https://npmjs.com/package/@stylistic/eslint-plugin-ts) | [package.json](./package.json) | TypeScript stylistic rules for ESLint, migrated from typescript-eslint. |
| [@stylistic/eslint-plugin-plus](https://npmjs.com/package/@stylistic/eslint-plugin-plus) | [package.json](./package.json) | Supplementary rules introduced by ESLint Stylistic. |
| [eslint-plugin-prettier](https://npmjs.com/package/eslint-plugin-prettier) | [package.json](./package.json) | Runs Prettier as an ESLint rule and reports differences as individual ESLint issues. |
<br />
You can add the following to your `package.json` file:
https://github.com/TheBinaryNinja/tvapp2/blob/1c75f11e9f0506ad3dd05133fdafc3aeb87686ca/tvapp2/package.json#L81-L92
<br />
<br />
##### Indentation
Use `4 spaces` per indentation level.
<br />
<br />
##### Style
For files that are not controlled by [Prettier](#prettier) or [ESLint](#eslint); use `Allman Style`. Braces should be on their own lines, and any code inside the braces should be indented 4 spaces.
### Indentation Style
You should be using the `Allman Style`. This style puts the brace associated with a control statement on the next line, indented. Statements within the braces are indented to the same level as the braces.
<br />
```javascript
return {
status: "failure",
user:
{
id: "1aaa35aa-fb3a-62ae-ffec-a14g7fc401ac",
label: "Test String",
}
};
while (x == y)
location ~ ^(.+\.php)(.*)$
{
foo();
bar();
# enable the next two lines for http auth
# auth_basic "Restricted";
# auth_basic_user_file /config/nginx/.htpasswd;
fastcgi_split_path_info ^(.+\.php)(.*)$;
if (!-f $document_root$fastcgi_script_name) { return 404; }
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
}
# deny access to .htaccess/.htpasswd files
location ~ /\.ht
{
deny all;
}
```
<br />
<br />
##### Line Length
Keep the maximum character count to `100 characters per line`. The configs on this page have prettier automatically set up to detect more than 100 characters per line.
### Spaces Instead Of Tabs
When writing your code, set your IDE to utilize **spaces**, with a configured size of `4 characters`. If this project utilizes ESLint, you should find the file `.editorconfig` in the root directory of the repo which defines how the file should be formatted. Load that file into programs such as Visual Studio Code.
<br />
##### Commenting
Comment your code. It helps novice readers to better understand the process. You may use block style commenting, or single lines:
```javascript
/*
tests to decide if the end-user is running on Darwin or another platform.
*/
test(`Return true if platform is Darwin`, () => {
process.platform = 'darwin';
expect(bIsDarwin()).toBe(true);
});
test(`Return false if platform is not Darwin`, () => {
process.platform = 'linux';
expect(bIsDarwin()).toBe(false);
});
```
<br />
##### Casing
Stick to `camelCase` as much as possible.
```javascript
let myVar = 'one';
let secondVar = 'two';
```
<br />
If you are defining a new environment variable; it must be in ALL CAPS in the `Dockerfile`:
```dockerfile
ENV DIR_BUILD=/usr/src/app
ENV DIR_RUN=/usr/bin/app
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
ENV WEB_IP="0.0.0.0"
ENV WEB_PORT=4124
ENV STREAM_QUALITY="hd"
ENV FILE_PLAYLIST="playlist.m3u8"
ENV FILE_EPG="xmltv.xml"
ENV LOG_LEVEL=4
ENV TZ="Etc/UTC"
```
<br />
Then you may call your new environment variable within the Javascript code; and ensure you define a default value to correct any user misconfigurations:
```javascript
const envUrlRepo = process.env.URL_REPO || 'https://git.binaryninja.net/binaryninja';
const envStreamQuality = process.env.STREAM_QUALITY || 'hd';
const envFileM3U = process.env.FILE_PLAYLIST || 'playlist.m3u8';
const envFileXML = process.env.FILE_EPG || 'xmltv.xml';
const envFileTAR = process.env.FILE_TAR || 'xmltv.xml.gz';
```
<br />
<br />
<div align="center">
@@ -572,72 +317,73 @@ const envFileTAR = process.env.FILE_TAR || 'xmltv.xml.gz';
<br />
<br />
<br />
<br />
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- BADGE > GENERAL -->
[general-npmjs-uri]: https://npmjs.com
[general-nodejs-uri]: https://nodejs.org
[general-npmtrends-uri]: http://npmtrends.com/tvapp2
[general-npmtrends-uri]: http://npmtrends.com/thetvapp-docker
<!-- BADGE > VERSION > GITHUB -->
[github-version-img]: https://img.shields.io/github/v/tag/thebinaryninja/tvapp2?logo=GitHub&label=Version&color=ba5225
[github-version-uri]: https://github.com/thebinaryninja/tvapp2/releases
[github-version-img]: https://img.shields.io/github/v/tag/Aetherinox/thetvapp-docker?logo=GitHub&label=Version&color=ba5225
[github-version-uri]: https://github.com/Aetherinox/thetvapp-docker/releases
<!-- BADGE > VERSION > NPMJS -->
[npm-version-img]: https://img.shields.io/npm/v/thetvapp-docker?logo=npm&label=Version&color=ba5225
[npm-version-uri]: https://npmjs.com/package/thetvapp-docker
<!-- BADGE > VERSION > PYPI -->
[pypi-version-img]: https://img.shields.io/pypi/v/thetvapp-docker-plugin
[pypi-version-uri]: https://pypi.org/project/thetvapp-docker-plugin/
<!-- BADGE > LICENSE > MIT -->
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
[license-mit-uri]: https://github.com/thebinaryninja/tvapp2/blob/main/LICENSE
[license-mit-uri]: https://github.com/Aetherinox/thetvapp-docker/blob/main/LICENSE
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
[github-downloads-img]: https://img.shields.io/github/downloads/thebinaryninja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
[github-downloads-uri]: https://github.com/thebinaryninja/tvapp2/releases
[github-downloads-img]: https://img.shields.io/github/downloads/Aetherinox/thetvapp-docker/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
[github-downloads-uri]: https://github.com/Aetherinox/thetvapp-docker/releases
<!-- BADGE > NPMJS > DOWNLOAD COUNT -->
[npmjs-downloads-img]: https://img.shields.io/npm/dw/%40aetherinox%2Fmkdocs-link-embeds?logo=npm&&label=Downloads&color=376892
[npmjs-downloads-uri]: https://npmjs.com/package/thetvapp-docker
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
[github-size-img]: https://img.shields.io/github/repo-size/thebinaryninja/tvapp2?logo=github&label=Size&color=59702a
[github-size-uri]: https://github.com/thebinaryninja/tvapp2/releases
[github-size-img]: https://img.shields.io/github/repo-size/Aetherinox/thetvapp-docker?logo=github&label=Size&color=59702a
[github-size-uri]: https://github.com/Aetherinox/thetvapp-docker/releases
<!-- BADGE > NPMJS > DOWNLOAD SIZE -->
[npmjs-size-img]: https://img.shields.io/npm/unpacked-size/thetvapp-docker/latest?logo=npm&label=Size&color=59702a
[npmjs-size-uri]: https://npmjs.com/package/thetvapp-docker
<!-- BADGE > CODECOV > COVERAGE -->
[codecov-coverage-img]: https://img.shields.io/codecov/c/github/Aetherinox/thetvapp-docker?token=MPAVASGIOG&logo=codecov&logoColor=FFFFFF&label=Coverage&color=354b9e
[codecov-coverage-uri]: https://codecov.io/github/Aetherinox/thetvapp-docker
<!-- BADGE > ALL CONTRIBUTORS -->
[contribs-all-img]: https://img.shields.io/github/all-contributors/thebinaryninja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
[contribs-all-img]: https://img.shields.io/github/all-contributors/Aetherinox/thetvapp-docker?logo=contributorcovenant&color=de1f6f&label=contributors
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
<!-- BADGE > GITHUB > BUILD > NPM -->
[github-build-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-release.yml
[github-build-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/thetvapp-docker/deploy-docker.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-uri]: https://github.com/Aetherinox/thetvapp-docker/actions/workflows/deploy-docker.yml
<!-- BADGE > GITHUB > BUILD > Pypi -->
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-pypi-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/pypi-release.yml
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/thetvapp-docker/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-pypi-uri]: https://github.com/Aetherinox/thetvapp-docker/actions/workflows/pypi-release.yml
<!-- BADGE > GITHUB > TESTS -->
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
[github-tests-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-tests.yml
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/Aetherinox/thetvapp-docker/npm-tests.yml?logo=github&label=Tests&color=2c6488
[github-tests-uri]: https://github.com/Aetherinox/thetvapp-docker/actions/workflows/npm-tests.yml
<!-- BADGE > GITHUB > COMMIT -->
[github-commit-img]: https://img.shields.io/github/last-commit/thebinaryninja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
[github-commit-uri]: https://github.com/thebinaryninja/tvapp2/commits/main/
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
[github-docker-version-uri]: https://github.com/thebinaryninja/tvapp2/pkgs/container/tvapp2
<!-- BADGE > Dockerhub > Docker Image -->
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
<!-- BADGE > Gitea 2 > Docker Image -->
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
[github-commit-img]: https://img.shields.io/github/last-commit/Aetherinox/thetvapp-docker?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
[github-commit-uri]: https://github.com/Aetherinox/thetvapp-docker/commits/main/
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
[btn-github-submit-uri]: https://github.com/thebinaryninja/tvapp2/issues
[btn-github-submit-uri]: https://github.com/aetherinox/thetvapp-docker/issues
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->

View File

@@ -1,163 +1,118 @@
# syntax=docker/dockerfile:1
# #
# @project TVApp2
# @usage docker image which allows you to download a m3u playlist and EPG guide data from
# multiple IPTV services.
# @file Dockerfile
# @repo https://github.com/TheBinaryNinja/tvapp2
# https://git.binaryninja.net/BinaryNinja/tvapp2
# https://github.com/aetherinox/docker-base-alpine
#
# build your own image by running
# amd64 docker build --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 -t tvapp2:latest -t tvapp2:1.5.0 -t tvapp2:1.5.0-amd64 -f Dockerfile .
# arm64 docker build --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 -t tvapp2:1.5.0-arm64 -f Dockerfile.aarch64 .
#
# OR; build using `docker buildx`
# create docker buildx create --driver docker-container --name container --bootstrap --use
# amd64 docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-amd64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --pull --push .
# arm64 docker buildx build --build-arg ARCH=arm64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-arm64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/arm64 --output type=docker --allow network.host --network host --no-cache --pull --push .
#
# OR; build single amd64 image
# create docker buildx create --driver docker-container --name container --bootstrap --use
# amd64 docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0 --tag ghcr.io/thebinaryninja/tvapp2:1.5 --tag ghcr.io/thebinaryninja/tvapp2:1 --tag ghcr.io/thebinaryninja/tvapp2:latest --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --push .
#
# OR; build official image (publish)
# create docker buildx create --driver docker-container --name container --bootstrap --use
# amd64-stable docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-amd64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --pull --push .
# arm64-stable docker buildx build --build-arg ARCH=arm64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-arm64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/arm64 --output type=docker --allow network.host --network host --no-cache --pull --push .
# amd64-dev docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=development --tag ghcr.io/thebinaryninja/tvapp2:development-amd64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --pull --push .
# arm64-dev docker buildx build --build-arg ARCH=arm64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=development --tag ghcr.io/thebinaryninja/tvapp2:development-arm64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/arm64 --output type=docker --allow network.host --network host --no-cache --pull --push .
# amd64-stable-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.5.0-amd64
# arm64-stable-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.5.0-arm64
# amd64-dev-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-amd64
# arm64-dev-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-arm64
# merge-stable docker buildx imagetools create --tag ghcr.io/thebinaryninja/tvapp2:1.5.0 --tag ghcr.io/thebinaryninja/tvapp2:1.5 --tag ghcr.io/thebinaryninja/tvapp2:1 --tag ghcr.io/thebinaryninja/tvapp2:latest sha256:0abe1b1c119959b3b1ccc23c56a7ee2c4c908c6aaef290d4ab2993859d807a3b sha256:e68b9de8669eac64d4e4d2a8343c56705e05e9a907cf0b542343f9b536d9c473
# merge-dev docker buildx imagetools create --tag ghcr.io/thebinaryninja/tvapp2:development sha256:8f36385a28c8f6eb7394d903c9a7a2765b06f94266b32628389ee9e3e3d7e69d sha256:c719ccb034946e3f0625003f25026d001768794e38a1ba8aafc9146291d548c5
# @about This docker file installs:
# - nginx
# - php-fpm
# - theapptv
# #
# #
# FROM
# any args defined before FROM cannot be called after FROM and the ARE is classified outside the build process.
# You will have to re-define the arg after FROM to utilize it anywhere else in the build process.
#
# @ref https://docs.docker.com/reference/dockerfile/#understand-how-arg-and-from-interact
# Base Image
# This container uses a modified version of the Linux server alpine image
# #
ARG ARCH=amd64
ARG ALPINE_VERSION=3.21
FROM --platform=linux/${ARCH} ghcr.io/aetherinox/alpine-base:${ALPINE_VERSION}
# #
# Set Args
# #
ARG ARCH=amd64
ARG ALPINE_VERSION=3.21
ARG BUILDDATE
ARG VERSION
ARG RELEASE
FROM ghcr.io/linuxserver/baseimage-alpine:3.20
# #
# Set Labels
# #
LABEL org.opencontainers.image.authors="Aetherinox, iFlip721, Optx"
LABEL org.opencontainers.image.vendor="BinaryNinja"
LABEL org.opencontainers.image.title="TVApp2"
LABEL org.opencontainers.image.description="Automatic m3u and xml guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client."
LABEL org.opencontainers.image.source="https://github.com/thebinaryninja/tvapp2"
LABEL org.opencontainers.image.repo.1="https://github.com/thebinaryninja/tvapp2"
LABEL org.opencontainers.image.repo.2="https://git.binaryninja.net/binaryninja/tvapp2"
LABEL org.opencontainers.image.repo.3="https://github.com/aetherinox/docker-base-alpine"
LABEL org.opencontainers.image.documentation="https://thebinaryninja.github.io/tvapp2"
LABEL org.opencontainers.image.url="https://github.com/thebinaryninja/tvapp2/pkgs/container/tvapp2"
LABEL maintainer="Aetherinox"
LABEL org.opencontainers.image.authors="Aetherinox"
LABEL org.opencontainers.image.vendor="Aetherinox"
LABEL org.opencontainers.image.title="TheTVApp Grabber"
LABEL org.opencontainers.image.description="thetvapp image by Aetherinox"
LABEL org.opencontainers.image.source="https://github.com/Aetherinox/thetvapp-docker"
LABEL org.opencontainers.image.documentation="https://github.com/Aetherinox/thetvapp-docker"
LABEL org.opencontainers.image.url="https://github.com/Aetherinox/thetvapp-docker"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.architecture="${ARCH}"
LABEL org.opencontainers.image.ref.name="main"
LABEL org.opencontainers.image.registry="local"
LABEL org.opencontainers.image.release="${RELEASE}"
LABEL org.tvapp2.image.maintainers="Aetherinox, iFlip721, Optx"
LABEL org.tvapp2.image.build-version="Version:- ${VERSION} Date:- ${BUILDDATE}"
LABEL org.tvapp2.image.build-version-alpine="${ALPINE_VERSION}"
LABEL org.tvapp2.image.build-architecture="${ARCH}"
LABEL org.tvapp2.image.build-release="${RELEASE}"
LABEL build_version="1.0.0"
# #
# Set Env Var
# Set Args
# #
ENV NODE_VERSION=22.8.0
ENV YARN_VERSION=1.22.22
ENV RELEASE="${RELEASE}"
ENV DIR_BUILD=/usr/src/app
ENV DIR_RUN=/usr/bin/app
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
ENV WEB_IP="0.0.0.0"
ENV WEB_PORT=4124
ENV WEB_ENCODING="deflate, br"
ENV WEB_PROXY_HEADER="x-forwarded-for"
ENV STREAM_QUALITY="hd"
ENV FILE_URL="urls.txt"
ENV FILE_M3U="playlist.m3u8"
ENV FILE_EPG="xmltv.xml"
ENV FILE_TAR="xmltv.xml.gz"
ENV HEALTH_TIMER=600000
ENV LOG_LEVEL=4
ARG BUILD_DATE
ARG VERSION
ARG NGINX_VERSION
ARG CRON_TIME
ENV CRON_TIME="0/60 * * * *"
ENV TZ="Etc/UTC"
ENV URL_XML="https://raw.githubusercontent.com/dtankdempse/thetvapp-m3u/refs/heads/main/guide/epg.xml"
ENV URL_XML_GZ="https://raw.githubusercontent.com/dtankdempse/thetvapp-m3u/refs/heads/main/guide/epg.xml.gz"
ENV URL_M3U="https://thetvapp-m3u.data-search.workers.dev/playlist"
ENV FILE_NAME="thetvapp"
ENV PORT_HTTP=80
ENV PORT_HTTPS=443
# #
# Install
# #
RUN \
apk add --no-cache \
wget \
curl \
bash \
nano \
npm \
openssl
if [ -z ${NGINX_VERSION+x} ]; then \
NGINX_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \
&& awk '/^P:nginx$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \
fi && \
apk add --no-cache \
wget \
logrotate \
openssl \
apache2-utils \
nginx \
nginx==${NGINX_VERSION} \
nginx-mod-http-fancyindex==${NGINX_VERSION} && \
echo "**** Install Build Packages ****" && \
echo "**** Configure Nginx ****" && \
echo 'fastcgi_param HTTP_PROXY ""; # https://httpoxy.org/' >> \
/etc/nginx/fastcgi_params && \
echo 'fastcgi_param PATH_INFO $fastcgi_path_info; # http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info' >> \
/etc/nginx/fastcgi_params && \
echo 'fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/#connecting-nginx-to-php-fpm' >> \
/etc/nginx/fastcgi_params && \
echo 'fastcgi_param SERVER_NAME $host; # Send HTTP_HOST as SERVER_NAME. If HTTP_HOST is blank, send the value of server_name from nginx (default is `_`)' >> \
/etc/nginx/fastcgi_params && \
rm -f /etc/nginx/http.d/default.conf && \
rm -f /etc/nginx/conf.d/stream.conf && \
rm -f /config/www/index.html && \
echo "**** Setup Logrotate ****" && \
sed -i "s#/var/log/messages {}.*# #g" \
/etc/logrotate.conf && \
sed -i 's#/usr/sbin/logrotate /etc/logrotate.conf#/usr/sbin/logrotate /etc/logrotate.conf -s /config/log/logrotate.status#g' \
/etc/periodic/daily/logrotate
# #
# Copy docker-entrypoint
# Set work directory
# #
COPY docker-entrypoint.sh /usr/local/bin/
WORKDIR /config/www
# #
# copy s6-overlays root to image root
# add local files
# #
COPY root/ /
# #
# set work directory
# ports and volumes
# #
WORKDIR ${DIR_BUILD}
EXPOSE ${PORT_HTTP} ${PORT_HTTPS}
# #
# copy tvapp2 project to workdir
# Add Cron Task Files
# #
COPY tvapp2/ ./
# #
# set work dir to built app
# #
WORKDIR ${DIR_RUN}
# #
# Ports and volumes
# #
EXPOSE ${WEB_PORT}/tcp
ADD run.sh /
ADD download.sh /
# #
# In case user sets up the cron for a longer duration, do a first run
# and then keep the container running. Hacky, but whatever.
# #
ENTRYPOINT ["/init"]
CMD ["sh", "-c", "/run.sh ; /download.sh ; tail -f /dev/null"]

134
Dockerfile-php.template Normal file
View File

@@ -0,0 +1,134 @@
# syntax=docker/dockerfile:1
# #
# @file Dockerfile.IncPhp
# @about This docker file installs:
# - nginx
# - php-fpm
# - theapptv
# #
# #
# Base Image
# This container uses a modified version of the Linux server alpine image
# #
FROM ghcr.io/linuxserver/baseimage-alpine:3.20
# #
# Set Labels
# #
LABEL maintainer="Aetherinox"
LABEL org.opencontainers.image.authors="Aetherinox"
LABEL org.opencontainers.image.vendor="Aetherinox"
LABEL org.opencontainers.image.title="TheTVApp Grabber"
LABEL org.opencontainers.image.description="thetvapp image by Aetherinox"
LABEL org.opencontainers.image.source="https://github.com/Aetherinox/thetvapp-docker"
LABEL org.opencontainers.image.documentation="https://github.com/Aetherinox/thetvapp-docker"
LABEL org.opencontainers.image.url="https://github.com/Aetherinox/thetvapp-docker"
LABEL org.opencontainers.image.licenses="MIT"
LABEL build_version="1.0.0"
# #
# Set Args
# #
ARG BUILD_DATE
ARG VERSION
ARG NGINX_VERSION
ARG CRON_TIME
ENV CRON_TIME="0/60 * * * *"
ENV TZ="Etc/UTC"
ENV URL_XML="https://raw.githubusercontent.com/dtankdempse/thetvapp-m3u/refs/heads/main/guide/epg.xml"
ENV URL_XML_GZ="https://raw.githubusercontent.com/dtankdempse/thetvapp-m3u/refs/heads/main/guide/epg.xml.gz"
ENV URL_M3U="https://thetvapp-m3u.data-search.workers.dev/playlist"
ENV FILE_NAME="thetvapp"
ENV PORT_HTTP=80
ENV PORT_HTTPS=443
# #
# Install
# #
RUN \
if [ -z ${NGINX_VERSION+x} ]; then \
NGINX_VERSION=$(curl -sL "http://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz" | tar -xz -C /tmp \
&& awk '/^P:nginx$/,/V:/' /tmp/APKINDEX | sed -n 2p | sed 's/^V://'); \
fi && \
apk add --no-cache \
wget \
logrotate \
openssl \
apache2-utils \
nginx \
php83 \
php83-fileinfo \
php83-fpm \
php83-mbstring \
nginx==${NGINX_VERSION} \
nginx-mod-http-fancyindex==${NGINX_VERSION} && \
echo "**** Install Build Packages ****" && \
echo "**** Configure Nginx ****" && \
echo 'fastcgi_param HTTP_PROXY ""; # https://httpoxy.org/' >> \
/etc/nginx/fastcgi_params && \
echo 'fastcgi_param PATH_INFO $fastcgi_path_info; # http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info' >> \
/etc/nginx/fastcgi_params && \
echo 'fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/#connecting-nginx-to-php-fpm' >> \
/etc/nginx/fastcgi_params && \
echo 'fastcgi_param SERVER_NAME $host; # Send HTTP_HOST as SERVER_NAME. If HTTP_HOST is blank, send the value of server_name from nginx (default is `_`)' >> \
/etc/nginx/fastcgi_params && \
rm -f /etc/nginx/http.d/default.conf && \
rm -f /etc/nginx/conf.d/stream.conf && \
rm -f /config/www/index.html && \
echo "**** Check PHP version and symlink ****" && \
if [ "$(readlink /usr/bin/php)" != "php83" ]; then \
rm -rf /usr/bin/php && \
ln -s /usr/bin/php83 /usr/bin/php; \
fi && \
echo "**** Configure PHP ****" && \
sed -i "s#;error_log = log/php83/error.log.*#error_log = /config/log/php/error.log#g" \
/etc/php83/php-fpm.conf && \
sed -i "s#user = nobody.*#user = abc#g" \
/etc/php83/php-fpm.d/www.conf && \
sed -i "s#group = nobody.*#group = abc#g" \
/etc/php83/php-fpm.d/www.conf && \
echo "**** Setup Logrotate ****" && \
sed -i "s#/var/log/messages {}.*# #g" \
/etc/logrotate.conf && \
sed -i 's#/usr/sbin/logrotate /etc/logrotate.conf#/usr/sbin/logrotate /etc/logrotate.conf -s /config/log/logrotate.status#g' \
/etc/periodic/daily/logrotate
# #
# Set work directory
# #
WORKDIR /config/www
# #
# add local files
# #
COPY root/ /
# #
# ports and volumes
# #
EXPOSE ${PORT_HTTP} ${PORT_HTTPS}
# #
# Add Cron Task Files
# #
ADD run.sh /
ADD download.sh /
# #
# In case user sets up the cron for a longer duration, do a first run
# and then keep the container running. Hacky, but whatever.
# #
CMD ["sh", "-c", "/run.sh ; /download.sh ; tail -f /dev/null"]

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 BinaryNinja
Gistr - Copyright (c) 2025 Aetherinox
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

2269
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,50 +0,0 @@
# #
# TVApp2 Docker-compose.yml
#
# Automatic M3U playlist and XML guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client.
#
# @url https://github.com/TheBinaryNinja/tvapp2
# https://git.binaryninja.net/BinaryNinja/tvapp2
#
# @image:github ghcr.io/thebinaryninja/tvapp2:latest
# ghcr.io/thebinaryninja/tvapp2:amd64
# ghcr.io/thebinaryninja/tvapp2:arm64
#
# @image:dockerhub thebinaryninja/tvapp2:latest
# thebinaryninja/tvapp2:1.0.0-amd64
# thebinaryninja/tvapp2:1.0.0-arm64
#
# @image:gitea git.binaryninja.net/binaryninja/tvapp2:latest
# git.binaryninja.net/binaryninja/tvapp2:1.0.0-amd64
# git.binaryninja.net/binaryninja/tvapp2:1.0.0-arm64
# #
services:
# #
# Service > TVApp2
# #
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest # Image: Github
# image: thebinaryninja/tvapp2:latest # Image: Dockerhub
# image: git.binaryninja.net/binaryninja/tvapp2:latest # Image: Gitea
# image: tvapp2:latest # Image: Locally built
hostname: tvapp2
environment:
TZ: "Etc/UTC"
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
ulimits:
memlock:
soft: -1
hard: -1
healthcheck:
test: [ "CMD", "curl", "--fail", "http://127.0.0.1:4124" ]
interval: 30s
retries: 5

View File

@@ -1,31 +0,0 @@
#!/bin/sh
# #
# @project TVApp2
# @usage docker image which allows you to download a m3u playlist and EPG guide data from
# multiple IPTV services.
# @file docker-entrypoint.sh
# @repo https://github.com/TheBinaryNinja/tvapp2
# https://git.binaryninja.net/BinaryNinja/tvapp2
# https://github.com/aetherinox/docker-base-alpine
#
# you can build your own image by running
# amd64 docker build --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 -t tvapp2:1.0.0-amd64 -f Dockerfile .
# arm64 docker build --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:1.0.0-arm64 -f Dockerfile.aarch64 .
#
# if you prefer to use `docker buildx`
# create docker buildx create --driver docker-container --name container --bootstrap --use
# amd64 docker buildx build --no-cache --pull --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 --platform=linux/amd64 --output type=docker --output type=docker .
# arm64 docker buildx build --no-cache --pull --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 --platform=linux/arm64 --output type=docker --output type=docker .
# #
set -e
# Run command with node if the first argument contains a "-" or is not a system command. The last
# part inside the "{}" is a workaround for the following bug in ash/dash:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264
if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then
set -- node "$@"
fi
exec "$@"

2
docs/.gitattributes vendored
View File

@@ -1,2 +0,0 @@
# Enforce Unix newlines
* text=auto eol=lf

75
docs/.gitignore vendored
View File

@@ -1,75 +0,0 @@
# #
# Copyright (c) 2025 Aetherinox
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# #
# #
# Node, TypeScript, Python
# #
# Dependencies
node_modules
__pycache__
venv
.venv
# Build files
build
site
# Distribution files
dist
mkdocs_material.egg-info
# Caches and logs
*.cpuprofile
*.log
*.tsbuildinfo
.cache
.eslintcache
__pycache__
# Examples
example
example.zip
# -----------------------------------------------------------------------------
# General
# -----------------------------------------------------------------------------
# Never ignore .gitkeep files
!**/.gitkeep
# macOS internals
.DS_Store
# Temporary files
TODO
tmp
# IDEs & Editors
.idea
*~
# -----------------------------------------------------------------------------
# Misc
# -----------------------------------------------------------------------------
encryptcontent.cache

View File

@@ -1,202 +0,0 @@
---
title: Changelog
tags:
- changelog
---
# Changelog
This section outlines all releases of TVApp2, including the version of the release, and the changes made for that release.
<br />
<p align="center" markdown="1">
<!-- prettier-ignore-start -->
[![Version][github-version-img]][github-version-uri]
[![Downloads][github-downloads-img]][github-downloads-uri]
[![Size][github-size-img]][github-size-img]
[![Last Commit][github-commit-img]][github-commit-img]
[![Contributors][contribs-all-img]](#contributors)
<!-- prettier-ignore-end -->
</p>
<br />
---
<br />
### <!-- md:version stable- --> 1.4.0 <small>Apr 10, 2025</small> { id="1.4.0" }
- `feat`: add new environment variable `HEALTH_TIMER` _(See feature below)_
- `feat`: new health check icon in top right; triggers every `10 minutes` and reports back to the web interface as a toast notification
- health check shows timer until next health check is performed.
- `feat`: added bootstramp toast notifications and modals
- `feat`: new modal dialog when when user triggers a re-sync of the m3u and epg data
- `feat`: footer of web interface how discloses which build is being ran; `stable` or `development`
- `refactor`: console logging system overhauled with new syntax for how logs are displayed
- `refactor`: additional logs added for `LOG_LEVEL=5` or higher
<br />
---
<br />
### <!-- md:version stable- --> 1.3.0 <small>Apr 9, 2025</small> { id="1.3.0" }
- `feat`: new button to upper-right side of header which allows you to **force re-sync** your m3u and xml data.
- `feat`: new api endpoint `/api/resync`; utilized to resync M3U and EPG data
- `feat`: new api endpoint `/api/health`; utilized in your `docker-compose.yml` health check
- `feat`: new env variable `WEB_ENCODING`; allows you to customize the HTTP `Accept-Encoding` request and response header
- `feat`: new env variable `IP_GATEWAY`; stores assigned container gateway ip
- `feat`: new env variable `IP_CONTAINER`; stores assigned container ip
- `refactor`: env variables re-named
- `FILE_TAR``FILE_GZP`
- `refactor`: errors and success messages now use api endpoint; lists timestamp, error code, etc.
- `build`: bump bootstrap from `v4` to `v5`
- `fix`: bug in Jellyfin which caused EPG data syncing to error out for hosts which cannot support gzip compression
- Error: _[ERR] [27] Jellyfin.LiveTv.Guide.GuideManager: Error getting programs for channel XXXXXXXXXXXXXXX (Source 2) System.Xml.XmlException: '', hexadecimal value 0x1F, is an invalid character. Line 1, position 1._
<br />
---
<br />
### <!-- md:version stable- --> 1.2.0 <small>Apr 5, 2025</small> { id="1.2.0" }
- `feat`: add support for additional mime types and default file type
- `style`: rename env variable `FILE_PLAYLIST` to `FILE_M3U`
- `build`: add new env vars to `Dockerfile`
- `FILE_TAR`
- `FILE_URL`
- `refactor`: m3u and epg files now stored in `www` folder
- `fix`: html template links pointing to old repo
<br />
---
<br />
### <!-- md:version stable- --> 1.1.0 <small>Mar 25, 2025</small> { id="1.1.0" }
- `feat`: new interface & theme for web ui
- integrated bootstrap 4.x
- new dark theme
- all hosted files now display `date`, `download url`, `size`, and `description`
- automatic viewport resizing depending on the device used
- new favicon
- localized css, js, and image support instead of relying on externally hosted resources
- `feat`: app now offers a compressed `gzip` for EPG guide data
- `feat`: add multiple url paths to download each asset
- `/guide`, `/epg`, `xml`
- `/playlist`, `/m3u`, `/m3u8`
- `/gzip`, `/gz`
- `feat`: add mew environment variables
- `LOG_LEVEL`: specifies what level of logs you will see in console
- `STREAM_QUALITY`: specifies the quality of the stream; options: `hd` and `sd`
- `FILE_PLAYLIST`: filename that M3U playlist data will be stored to
- `FILE_EPG`: filename that EPG / XML guide data will be stored to
- `FILE_GZIP`: filename that compressed gzip guide data will be stored to
- `build`: app migrated from CommonJS to ES Modules
- `build`: bump alpine base image from v3.20 to v3.21
- `build`: migrated html template to independent file in `www` folder; utilizes `ejs` module
- `build`: **amd64** and **arm64** docker images merged into one image with architecture support
- `fix`: resolved bug where local server could not be started using nodejs; related to ip address variable
- `build(deps)`: add package `ejs` 3.1.10
- `build(deps)`: add package `chalk` 5.3.0
- `build(deps)`: add package `moment` 2.30.1
- `build(deps-dev)`: add package `eslint` 9.17.0
- `build(deps-dev)`: add package `eslint-plugin-chai-friendly` 1.0.1
- `build(deps-dev)`: add package `eslint-plugin-import` 2.31.0
- `build(deps-dev)`: add package `eslint-plugin-n` 17.15.0
- `build(deps-dev)`: add package `eslint-plugin-promise` 7.2.1
- `build(deps-dev)`: add package `@stylistic/eslint-plugin-js` 3.1.0
- `remove`: tvapp2.fonts.min.js
<br />
---
<br />
### <!-- md:version stable- --> 1.0.0 <small>Feb 24, 2025</small> { id="1.0.0" }
- Initial release
<br />
---
<br />
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- BADGE > GENERAL -->
[general-npmjs-uri]: https://npmjs.com
[general-nodejs-uri]: https://nodejs.org
[general-npmtrends-uri]: http://npmtrends.com/csf-firewall
<!-- BADGE > VERSION > GITHUB -->
[github-version-img]: https://img.shields.io/github/v/tag/TheBinaryNinja/tvapp2?logo=GitHub&label=Version&color=ba5225
[github-version-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
<!-- BADGE > LICENSE > MIT -->
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
[license-mit-uri]: https://github.com/TheBinaryNinja/tvapp2/blob/main/LICENSE
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
[github-downloads-img]: https://img.shields.io/github/downloads/TheBinaryNinja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
[github-downloads-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
[github-size-img]: https://img.shields.io/github/repo-size/TheBinaryNinja/tvapp2?logo=github&label=Size&color=59702a
[github-size-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
<!-- BADGE > ALL CONTRIBUTORS -->
[contribs-all-img]: https://img.shields.io/github/all-contributors/TheBinaryNinja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
<!-- BADGE > GITHUB > BUILD > NPM -->
[github-build-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-release.yml
<!-- BADGE > GITHUB > BUILD > Pypi -->
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-pypi-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/pypi-release.yml
<!-- BADGE > GITHUB > TESTS -->
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
[github-tests-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-tests.yml
<!-- BADGE > GITHUB > COMMIT -->
[github-commit-img]: https://img.shields.io/github/last-commit/TheBinaryNinja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
[github-commit-uri]: https://github.com/TheBinaryNinja/tvapp2/commits/main/
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
[github-docker-version-uri]: https://github.com/TheBinaryNinja/tvapp2/pkgs/container/tvapp2
<!-- BADGE > Dockerhub > Docker Image -->
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
<!-- BADGE > Gitea 2 > Docker Image -->
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
[btn-github-submit-uri]: https://github.com/TheBinaryNinja/tvapp2/issues
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->

View File

@@ -1,652 +0,0 @@
---
title: Contributing to TVApp2
tags:
- info
---
<div align="center" markdown="1">
<h1>♾️ Contributing ♾️</h1>
<br />
<p align="center" markdown="1">
<!-- prettier-ignore-start -->
[![Version][github-version-img]][github-version-uri]
[![Downloads][github-downloads-img]][github-downloads-uri]
[![Size][github-size-img]][github-size-img]
[![Last Commit][github-commit-img]][github-commit-img]
[![Contributors][contribs-all-img]](#contributors)
<!-- prettier-ignore-end -->
</p>
</div>
<br />
---
<br />
## About
Below are a list of ways that you can help contribute to this project, as well as policies and guides that explain how to get started.
Please review everything on this page before you submit your contribution.
<br />
---
<br />
- [About](#about)
- [Issues, Bugs, Ideas](#issues-bugs-ideas)
- [Contributing](#contributing)
- [Before Submitting Pull Requests](#before-submitting-pull-requests)
- [Conventional Commit Specification](#conventional-commit-specification)
- [Types](#types)
- [Example 1:](#example-1)
- [Example 2:](#example-2)
- [Committing](#committing)
- [Languages](#languages)
- [Python](#python)
- [Indentation](#indentation)
- [Line Length](#line-length)
- [Blank Lines](#blank-lines)
- [Imports](#imports)
- [Commenting](#commenting)
- [Casing](#casing)
- [NodeJS](#nodejs)
- [Prettier](#prettier)
- [ESLint](#eslint)
- [v9 \& Newer (Config)](#v9--newer-config)
- [v8 \& Older (Config)](#v8--older-config)
- [Packages](#packages)
- [Indentation](#indentation-1)
- [Style](#style)
- [Line Length](#line-length-1)
- [Commenting](#commenting-1)
- [Casing](#casing-1)
<br />
---
<br />
## Issues, Bugs, Ideas
Stuff happens, and sometimes as best as we try, there may be issues within this project that we are unaware of. That is the great thing about open-source; anyone can use the program and contribute to making it better.
<br />
If you have found a bug, have an issue, or maybe even a cool idea; you can let us know by [submitting it](https://github.com/thebinaryninja/tvapp2/issues). However, before you submit your new issue, bug report, or feature request; head over to the [Issues Section](https://github.com/thebinaryninja/tvapp2/issues) and ensure nobody else has already submitted it.
<br />
Once you are sure that your issue has not already being dealt with; you may submit a new issue at [here](https://github.com/thebinaryninja/tvapp2/issues/new/choose). You'll be asked to specify exactly what your new submission targets, such as:
- Bug report
- Feature Suggestion
<br />
When writing a new submission; ensure you fill out any of the questions asked of you. If you do not provide enough information, we cannot help. Be as detailed as possible, and provide any logs or screenshots you may have to help us better understand what you mean. Failure to fill out the submission properly may result in it being closed without a response.
<br />
If you are submitting a bug report:
- Explain the issue
- Describe how you expect for a feature to work, and what you're seeing instead of what you expected.
- List possible options for a resolution or insight
- Provide screenshots, logs, or anything else that can visually help track down the issue.
<br />
<div align="center">
[![Submit Issue][btn-github-submit-img]][btn-github-submit-uri]
</div>
<br />
<div align="center">
**[`^ back to top ^`](#about)**
</div>
<br />
---
<br />
## Contributing
If you are looking to contribute to this project by actually submit your own code; please review this section completely. There is important information and policies provided below that you must follow for your pull request to get accepted.
The source is here for everyone to collectively share and collaborate on. If you think you have a possible solution to a problem; don't be afraid to get your hands dirty.
All contributions are made via pull requests. To create a pull request, you need a GitHub account. If you are unclear on this process, see [GitHub's documentation on forking and pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). Pull requests should be targeted at the master branch.
<br />
### Before Submitting Pull Requests
- Follow the repository's code formatting conventions (see below);
- Include tests that prove that the change works as intended and does not add regressions;
- Document the changes in the code and/or the project's documentation;
- Your PR must pass the CI pipeline;
- When submitting your Pull Request, use one of the following branches:
- For bug fixes: `main` branch
- For features & functionality: `development` branch
- Include a proper git commit message following the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification).
<br />
If you have completed the above tasks, the pull request is ready to be reviewed and your pull request's label will be changed to "Ready for Review". At this point, a human will need to step in and manually verify your submission.
Reviewers will approve the pull request once they are satisfied with the patch it will be merged.
<br />
### Conventional Commit Specification
When committing your changes, we require you to follow the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification). The **Conventional Commits** is a specification for the format and content of a commit message. The concept behind Conventional Commits is to provide a rich commit history that can be read and understood by both humans and automated tools. Conventional Commits have the following format:
<br />
```
<type>[(optional <scope>)]: <description>
[optional <body>]
[optional <footer(s)>]
```
<br />
#### Types
Our repositories make use of the following commit tags:
<br />
| Type | Description |
| --- | --- |
| `feat` | <sup><sub>Introduce new feature</sub></sup> |
| `fix` | <sup><sub>Bug fix</sub></sup> |
| `chore` | <sup><sub>Includes technical or preventative maintenance task that is necessary for managing the app or repo, such as updating grunt tasks, but is not tied to any specific feature. Usually done for maintenance purposes.<br/>E.g: Edit .gitignore, .prettierrc, .prettierignore, .gitignore, eslint.config.js file</sub></sup> |
| `revert` | <sup><sub>Revert a previous commit</sub></sup> |
| `style` | <sup><sub>Update / reformat style of source code. Does not change the way app is implemented. Changes that do not affect the meaning of the code<br />E.g: white-space, formatting, missing semi-colons, change tabs to spaces, etc)</sub></sup> |
| `docs` | <sup><sub>Change website or markdown documents. Does not mean changes to the documentation generator script itself, only the documents created from the generator. <br/>E.g: documentation, readme.md or markdown |
| `build` | <sup><sub>Changes to the build / compilation / packaging process or auxiliary tools such as doc generation<br />E.g: create new build tasks, update release script, etc.</sub></sup> |
| `refactor` | <sup><sub>Change to production code that leads to no behavior difference,<br/>E.g: split files, rename variables, rename package, improve code style, etc.</sub></sup> |
| `test` | <sup><sub>Add or refactor tests, no production code change. Changes the suite of automated tests for the app.</sub></sup> |
| `ci` | <sup><sub>Changes related to Continuous Integration (usually `yml` and other configuration files).</sub></sup> |
| `perf` | <sup><sub>Performance improvement of algorithms or execution time of the app. Does not change an existing feature.</sub></sup> |
<br />
##### Example 1:
```
feat(core): bug affecting menu [#22]
^───^────^ ^────────────────^ ^───^
| | | |
| | | └───⫸ (ISSUE): Reference issue ID
│ │ │
│ │ └──────────────────────⫸ (DESC): Summary in present tense. Use lower case not title case!
│ │
│ └──────────────────────────────⫸ (SCOPE): The package(s) that this change affects
└──────────────────────────────────⫸ (TYPE): See list above
```
<br />
##### Example 2:
```
<type>(<scope>): <short summary> [issue]
| | | |
| | | └─⫸ Reference issue id (optional)
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
│ elements|forms|http|language-service|localize|platform-browser|
│ platform-browser-dynamic|platform-server|router|service-worker|
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve|
│ devtools....
└─⫸ Commit Type: build|ci|doc|docs|feat|fix|perf|refactor|test
website|chore|style|type|revert|deprecate
```
<br />
### Committing
If you are pushing a commit which addresses a submitted issue, reference your issue at the end of the commit message. You may also optionally add the major issue to the end of your commit body.
References should be on their own line, following the word `Ref` or `Refs`
```
Title: fix(core): fix error message displayed to users. [#22]
Description: The description of your commit
Ref: #22, #34, #37
```
<br />
<br />
### Languages
The formatting of code greatly depends on the language being used for this repository. We provide various different languages below as this guide is utilized across multiple repositories.
- [Python](#python)
- [Javascript / Typescript / NodeJS](#nodejs)
<br />
<br />
#### Python
The following guidelines apply to any projects written with Python:
<br />
##### Indentation
Use `4 spaces` per indentation level.
<br />
> [!TIP]
> ✅ Correct
> ```python
> def Encrypt( key : int, bytestr : bytes ):
> res = b''
> i_blk, left_bytes = divmod( len(bytestr), 3 )
> ```
<br />
> [!CAUTION]
> ❌ Wrong
> ```python
> def encrypt( key : int, byteStr : bytes ):
> Res = b''
> iBlk, leftBytes = divmod( len(byteStr), 3 )
> ```
<br />
##### Line Length
Keep the maximum character count to `100 characters per line`. If you are revising old code which doesn't follow this guideline; please rewrite it to conform.
<br />
##### Blank Lines
Surround top-level functions and class definitions with a blank in-between.
Method definitions inside a class are surrounded by a single blank line.
Extra blank lines may be used (sparingly) to separate groups of functions related to one another. Blank lines may be omitted between a bunch of related one-liners (e.g: set of dummy implementations).
<br />
##### Imports
Imports should usually be on separate lines:
<br />
> [!TIP]
> ✅ Correct
> ```python
> import os
> import sys
> ```
<br />
> [!CAUTION]
> ❌ Wrong
> ```python
> import sys, os
> ```
<br />
The following is acceptable:
<br />
> [!TIP]
> ✅ Correct
> ```python
> from mypkg import siblingA, siblingB, siblingC
> ```
<br />
##### Commenting
Comment your code. It helps novice readers to better understand the process. It doesn't have to be painfully obvious explanations, but it helps to give an idea of what something does.
Please append `#` to the beginning of each line.
```python
# #
# byteString : b'1#Aetherx|232#1#233262#0#0#0#'
# #
def Encrypt( key : int, byteString : bytes ):
res = bytearray( )
```
<br />
<br />
##### Casing
- Stick to `camelCase`; unless:
- naming functions, capitalize the first letter
- Capitalize enums
- If you see code not conforming with this, please revise it in your pull request.
<br />
> [!TIP]
> ✅ Correct
> ```python
> def Encrypt( key : int, byteStr : bytes ):
> res = b''
> iBlock, leftBytes = divmod( len(byteStr), 3 )
> ```
<br />
> [!CAUTION]
> ❌ Wrong
> ```python
> def encrypt( key : int, bytestr : bytes ):
> res = b''
> i_blk, left_bytes = divmod( len(bytestr), 3 )
> ```
<br />
<br />
<div align="center">
**[`^ back to top ^`](#about)**
</div>
<br />
---
<br />
#### NodeJS
The following allows you to configure ESLint and Prettier.
<br />
<br />
##### Prettier
We have opted to make use of [ESLint](#eslint) over Prettier. We provide a detailed ESLint flag config file with very specific linting rules. Please review that section for more information.
<br />
<br />
##### ESLint
Within the root folder of the repo, there are several configuration files which you should be using within the project. These files dictate how prettier and eslint will behave and what is acceptable / not acceptable.
<br />
Pick the config file below depending on which version of ESLint you are using. The v8 and older `.eslint` may not be there if we have migrated over to an Eslint v9 flat config file:
<br />
###### v9 & Newer (Config)
Our NodeJS applications require that you utilize ESLint v9 or newer which makes use of a flat config structure. You may find a copy of our flat config at the link below:
- [📄 eslint.config.mjs](https://github.com/thebinaryninja/tvapp2/blob/main/tvapp2/eslint.config.mjs)
<br />
###### v8 & Older (Config)
- We no longer utilize any version of ESLint older than version 9.
<br />
<br />
> [!NOTE]
> When submitting your pull request, these linting and style rules will be verified with all of your files. If you did not follow these rules; the linter tests on your pull request will fail; and you'll be expected to correct these issues before your submission will be transferred over for human review.
<br />
<br />
##### Packages
We use the following packages for linting and prettier.
<br />
| Package | Repo File | Description |
| --- | --- | --- |
| [@stylistic/eslint-plugin-js](https://npmjs.com/package/@stylistic/eslint-plugin-js) | [package.json](./package.json) | JavaScript stylistic rules for ESLint, migrated from eslint core. |
| [@stylistic/eslint-plugin-ts](https://npmjs.com/package/@stylistic/eslint-plugin-ts) | [package.json](./package.json) | TypeScript stylistic rules for ESLint, migrated from typescript-eslint. |
| [@stylistic/eslint-plugin-plus](https://npmjs.com/package/@stylistic/eslint-plugin-plus) | [package.json](./package.json) | Supplementary rules introduced by ESLint Stylistic. |
| [eslint-plugin-prettier](https://npmjs.com/package/eslint-plugin-prettier) | [package.json](./package.json) | Runs Prettier as an ESLint rule and reports differences as individual ESLint issues. |
<br />
You can add the following to your `package.json` file:
https://github.com/TheBinaryNinja/tvapp2/blob/1c75f11e9f0506ad3dd05133fdafc3aeb87686ca/tvapp2/package.json#L81-L92
<br />
<br />
##### Indentation
Use `4 spaces` per indentation level.
<br />
<br />
##### Style
For files that are not controlled by [Prettier](#prettier) or [ESLint](#eslint); use `Allman Style`. Braces should be on their own lines, and any code inside the braces should be indented 4 spaces.
<br />
```javascript
return {
status: "failure",
user:
{
id: "1aaa35aa-fb3a-62ae-ffec-a14g7fc401ac",
label: "Test String",
}
};
while (x == y)
{
foo();
bar();
}
```
<br />
<br />
##### Line Length
Keep the maximum character count to `100 characters per line`. The configs on this page have prettier automatically set up to detect more than 100 characters per line.
<br />
##### Commenting
Comment your code. It helps novice readers to better understand the process. You may use block style commenting, or single lines:
```javascript
/*
tests to decide if the end-user is running on Darwin or another platform.
*/
test(`Return true if platform is Darwin`, () => {
process.platform = 'darwin';
expect(bIsDarwin()).toBe(true);
});
test(`Return false if platform is not Darwin`, () => {
process.platform = 'linux';
expect(bIsDarwin()).toBe(false);
});
```
<br />
##### Casing
Stick to `camelCase` as much as possible.
```javascript
let myVar = 'one';
let secondVar = 'two';
```
<br />
If you are defining a new environment variable; it must be in ALL CAPS in the `Dockerfile`:
```dockerfile
ENV DIR_BUILD=/usr/src/app
ENV DIR_RUN=/usr/bin/app
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
ENV WEB_IP="0.0.0.0"
ENV WEB_PORT=4124
ENV STREAM_QUALITY="hd"
ENV FILE_PLAYLIST="playlist.m3u8"
ENV FILE_EPG="xmltv.xml"
ENV LOG_LEVEL=4
ENV TZ="Etc/UTC"
```
<br />
Then you may call your new environment variable within the Javascript code; and ensure you define a default value to correct any user misconfigurations:
```javascript
const envUrlRepo = process.env.URL_REPO || 'https://git.binaryninja.net/binaryninja';
const envStreamQuality = process.env.STREAM_QUALITY || 'hd';
const envFileM3U = process.env.FILE_PLAYLIST || 'playlist.m3u8';
const envFileXML = process.env.FILE_EPG || 'xmltv.xml';
const envFileTAR = process.env.FILE_TAR || 'xmltv.xml.gz';
```
<br />
<br />
<div align="center">
**[`^ back to top ^`](#about)**
</div>
<br />
<br />
<br />
<br />
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- BADGE > GENERAL -->
[general-npmjs-uri]: https://npmjs.com
[general-nodejs-uri]: https://nodejs.org
[general-npmtrends-uri]: http://npmtrends.com/tvapp2
<!-- BADGE > VERSION > GITHUB -->
[github-version-img]: https://img.shields.io/github/v/tag/thebinaryninja/tvapp2?logo=GitHub&label=Version&color=ba5225
[github-version-uri]: https://github.com/thebinaryninja/tvapp2/releases
<!-- BADGE > LICENSE > MIT -->
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
[license-mit-uri]: https://github.com/thebinaryninja/tvapp2/blob/main/LICENSE
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
[github-downloads-img]: https://img.shields.io/github/downloads/thebinaryninja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
[github-downloads-uri]: https://github.com/thebinaryninja/tvapp2/releases
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
[github-size-img]: https://img.shields.io/github/repo-size/thebinaryninja/tvapp2?logo=github&label=Size&color=59702a
[github-size-uri]: https://github.com/thebinaryninja/tvapp2/releases
<!-- BADGE > ALL CONTRIBUTORS -->
[contribs-all-img]: https://img.shields.io/github/all-contributors/thebinaryninja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
<!-- BADGE > GITHUB > BUILD > NPM -->
[github-build-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-release.yml
<!-- BADGE > GITHUB > BUILD > Pypi -->
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-pypi-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/pypi-release.yml
<!-- BADGE > GITHUB > TESTS -->
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
[github-tests-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-tests.yml
<!-- BADGE > GITHUB > COMMIT -->
[github-commit-img]: https://img.shields.io/github/last-commit/thebinaryninja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
[github-commit-uri]: https://github.com/thebinaryninja/tvapp2/commits/main/
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
[github-docker-version-uri]: https://github.com/thebinaryninja/tvapp2/pkgs/container/tvapp2
<!-- BADGE > Dockerhub > Docker Image -->
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
<!-- BADGE > Gitea 2 > Docker Image -->
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
[btn-github-submit-uri]: https://github.com/thebinaryninja/tvapp2/issues
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->

View File

@@ -1,183 +0,0 @@
# Conventions
This documentation use some symbols for illustration purposes. Before you read
on, please make sure you've made yourself familiar with the following list of
conventions:
<br />
### <!-- md:version --> Release Type { data-toc-label="Version" }
The tag symbol in conjunction with a version number denotes when a specific feature or behavior was added. Make sure you're at least on this version if you want to use it.
: <!-- md:version --> default
: <!-- md:version stable- --> stable
: <!-- md:version development- --> development
<br />
### <!-- md:control --> Controls { #default data-toc-label="Control" }
These icons define what type of control a specified setting uses.
: <!-- md:control toggle --> toggle
: <!-- md:control toggle_on --> toggle on
: <!-- md:control toggle_off --> toggle off
: <!-- md:control textbox --> textbox
: <!-- md:control dropdown --> dropdown
: <!-- md:control button --> button
: <!-- md:control slider --> slider
: <!-- md:control color #E5E5E5 #121315 --> color wheel
<br />
### <!-- md:default --> Default Value { #default data-toc-label="Default value" }
This defines what the default value for a setting is.
: <!-- md:default --> Specified setting has a default value
: <!-- md:default none --> Specified setting has no default value and is empty
: <!-- md:default computed --> Specified setting is automatically computed by the app
<br />
### <!-- md:command --> Command { #command data-toc-label="Command" }
This defines a command
: <!-- md:command --> Specified setting has a default value
<br />
### <!-- md:flag --> Flags { #flags data-toc-label="Flags" }
: <!-- md:flag --> Default
: <!-- md:flag experimental --> Experimental
: <!-- md:flag required --> Required
: <!-- md:flag customization --> Customization
: <!-- md:flag metadata --> Metadata
: <!-- md:flag dangerous --> Dangerous
: <!-- md:flag multiple --> Multiple
: <!-- md:flag setting --> Setting
Anything listed with this icon are features or functionality that are still in development and may change in future versions.
<br />
### <!-- md:3rdparty --> 3rd Party { data-toc-label="3rd Party" }
This symbol denotes that the item described is classified as something that changes the overall functionality of the plugin.
<br />
### <!-- md:flag setting --> Configurable Settings { #setting data-toc-label="Configurable Setting" }
The following denotes a configurable setting. These can also be broken up into individual settings as shown below:
#### <!-- md:setting example.setting.enabled -->
<!-- md:version 1.0.0 -->
<!-- md:default `true` -->
This is an example setting
#### <!-- md:setting example.setting.other -->
<!-- md:version 1.0.0 -->
<!-- md:default `true` -->
This is another example setting
<br />
### <!-- md:flag multiple --> Multiple instances { #multiple-instances data-toc-label="Multiple instances" }
This symbol denotes that the plugin supports multiple instances, i.e, that it
can be used multiple times in the `plugins` setting in `mkdocs.yml`.
<br />
### <!-- md:feature --> Optional feature { #feature data-toc-label="Optional feature" }
Some features may be hidden behind feature flags, which means they must
be explicitly enabled first before they can be configured. This allows
for the existence of potentially orthogonal features.
<br />
### <!-- md:markdown --> Markdown extension { data-toc-label="Markdown extension" #extension }
This symbol denotes that the thing described is a Markdown element.
<br />
### <!-- md:flag dangerous --> Dangerous { #danger data-toc-label="Dangerous Property" }
This symbol denotes that the item described is a metadata property, which can
be used in Markdown documents as part of the front matter definition.
<br />
### <!-- md:backers --> Backers only { data-toc-label="Backers only" }
The pumping heart symbol denotes that a specific feature or behavior is only
available to backers. Normal users will not have access to this particular item.
<br />
---
<br />
## Other Tags
<br />
### Example Download { #example data-toc-label="Dangerous Property" }
<!-- md:example my-example-file -->
The following denotes a downloadable file.
<br />
### Commands
<!-- md:command `-s, --start` -->
The above denotes a command which can be executed in a terminal / command prompt.
<br />
## Options
Options are another form of setting which lists what the option does, and then examples of how it works.
<!-- md:option rss.enabled -->
: <!-- md:default `true` --> This option specifies whether
the plugin is enabled when building your project. If you want to speed up
local builds, you can use an [environment variable][mkdocs.env]:
``` yaml
plugins:
- rss:
enabled: !ENV [CI, false]
```
<!-- md:option rss.match_path -->
: <!-- md:default `.*` --> This option specifies which
pages should be included in the feed. For example, to only include blog
posts in the feed, use the following regular expression:
``` yaml
plugins:
- rss:
match_path: blog/posts/.*
```
<br />
---
<br />
<br />
<br />

View File

@@ -1,29 +0,0 @@
# License
**MIT License**
Copyright (c) 2025 Aetherinox
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
<br />
---
<br />

View File

@@ -1,11 +0,0 @@
# Tags
Following is a list of relevant tags:
<!-- material/tags -->
<br />
---
<br />

View File

@@ -1,236 +0,0 @@
---
title: About TVApp2
tags:
- info
---
# About
<figure markdown="span">
![Image settings](https://raw.githubusercontent.com/TheBinaryNinja/tvapp2/main/docs/img/screenshots/01.png){ width="60%" }
<figcaption>TVApp2 Main Interface</figcaption>
</figure>
<br />
<h1 align="center"><b>TVApp2: M3U Playlist & Data Guides</b></h1>
<p align="center" markdown="1">
<!-- prettier-ignore-start -->
[![Version][github-version-img]][github-version-uri]
[![Downloads][github-downloads-img]][github-downloads-uri]
[![Size][github-size-img]][github-size-img]
[![Last Commit][github-commit-img]][github-commit-img]
[![Contributors][contribs-all-img]](#contributors)
<!-- prettier-ignore-end -->
</p>
## What is TVApp2?
**TVApp2** is a docker image which allows you to download M3U playlists and EPG guide data from various online IPTV services such as **TheTVApp**, **TVPass**, and **MoveOnJoy**. The playlist and guide data files can be imported into your favorite IPTV applications such as Jellyfin, Plex, and Emby.
Once the docker container is started; a fresh copy of the channel list and TV guide data will be downloaded and generated within your docker container. You can then visit the website URL associated with your docker container; which will give you direct links to the files that you can utilize with the above listed IPTV apps.
All channels contain multiple sources so that you have a reliable streaming experience, and helps you combat moments when one channel source goes offline.
<br />
---
<br />
## Image Sources
This project contains several repositories which all share the same code; use them as backups:
- [🔀 dockerhub:thebinaryninja/tvapp2](https://hub.docker.com/r/thebinaryninja/tvapp2)
- [🔀 github:thebinaryninja/tvapp2](https://github.com/thebinaryninja/tvapp2)
- [🔀 gitea:git.binaryninja.net/binaryninja/tvapp2](https://git.binaryninja.net/binaryninja/tvapp2)
<br />
| Pull URL | Registry | Arch | Version |
| --- | --- | --- | --- |
| `ghcr.io/thebinaryninja/tvapp2:latest`<br />`ghcr.io/thebinaryninja/tvapp2:development` | Github | amd64<br/>arm64 | [![Github][github-docker-version-img]][github-docker-version-uri] |
| `thebinaryninja/tvapp2:latest`<br />`thebinaryninja/tvapp2:development` | Dockerhub | amd64<br/>arm64 | [![Dockerhub][dockerhub-docker-version-img]][dockerhub-docker-version-uri] |
| `git.binaryninja.net/binaryninja/tvapp2:latest`<br />`git.binaryninja.net/binaryninja/tvapp2:development` | Gitea | amd64<br/>arm64 | [![Gitea][gitea-docker-version-img]][gitea-docker-version-uri] |
<br />
---
<br />
## Features
The following is a small list of the features available with the TVApp2 container:
- Multiple IPTV service sources:
- TheTVApp
- TVPass
- MoveOnJoy
- Channel playlists can be downloaded as a `.m38u` or a compressed `.gzip` archive.
- Compressed gzip compatible with 3rd party apps like Cabernet and Jellyfin.
- Tracking statistics which show the last update time, size, and a description for each file's purpose.
- API endpoints:
- **Resync All Files**
- http://127.0.0.1:4124/api/resync
- http://127.0.0.1:4124/api/restart
- **Health check**
- http://127.0.0.1:4124/api/health
- http://127.0.0.1:4124/api/status
- Direct access to download each of the generated files, including multiple easy-to-remember URLs for each file type.
- **M3U Playlist**:
- http://127.0.0.1:4124/playlist
- http://127.0.0.1:4124/m3u
- http://127.0.0.1:4124/m38u
- **EPG Guide Data (Uncompressed)**:
- http://127.0.0.1:4124/guide
- http://127.0.0.1:4124/epg
- http://127.0.0.1:4124/xml
- **EPG Guide Data (Compressed)**:
- http://127.0.0.1:4124/gzip
- http://127.0.0.1:4124/gz
- Video sources include both quality options `hd` and `sd`.
- Easily mountable docker volumes to access the generated files quickly.
- Wide variety of docker environment variables to change the binding IP, port, app root directory, quality, timezone, etc.
- Small docker image size; based on Alpine 3.x which averages `40MB`.
- Compatible with architectures `amd64` and `arm64/aarm64`.
- Example configurations for 3rd party apps such as Traefik and Authentik.
<br />
---
<br />
## ✨ Contributors
We are always looking for contributors. If you feel that you can provide something useful to Gistr, then we'd love to review your suggestion. Before submitting your contribution, please review the following resources:
- [Pull Request Procedure](https://github.com/TheBinaryNinja/tvapp2/blob/main/.github/PULL_REQUEST_TEMPLATE.md)
- [Contributor Policy](https://github.com/TheBinaryNinja/tvapp2/blob/main/CONTRIBUTING.md)
<br />
Want to help but can't write code?
- Review [active questions by our community](https://github.com/TheBinaryNinja/tvapp2/labels/help%20wanted) and answer the ones you know.
<br />
<div align="center" markdown="1">
![Alt](https://repobeats.axiom.co/api/embed/fb7e11f0bc61b125f923a0ee3eb0bd8aba79b8d5.svg "Repobeats analytics image")
</div>
<br />
The following people have helped get this project going:
<br />
<div align="center" markdown="1">
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![Contributors][contribs-all-img]](#contributors)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top"><a href="https://github.com/Aetherinox">
<img src="https://avatars.githubusercontent.com/u/118329232?v=4?s=40" width="80px;" alt="Aetherinox"/><br /><sub><b>Aetherinox</b></sub></a><br /><a href="https://github.com/TheBinaryNinja/tvapp2/commits?author=Aetherinox" title="Code">💻</a>
</td>
<td align="center" valign="top"><a href="https://github.com/iFlip721">
<img src="https://avatars.githubusercontent.com/u/28721588?v=4" width="80px;" alt="iFlip721"/><br /><sub><b>iFlip721</b></sub></a><br /><a href="https://github.com/TheBinaryNinja/tvapp2/commits?author=iFlip721" title="Code">💻</a>
</td>
<td align="center" valign="top"><a href="https://github.com/Nvmdfth">
<img src="https://avatars.githubusercontent.com/u/32874812?v=4" width="80px;" alt="Nvmdfth"/><br /><sub><b>Optx</b></sub></a><br /><a href="https://github.com/TheBinaryNinja/tvapp2/commits?author=Nvmdfth" title="Code">💻</a>
</td>
</tr>
</tbody>
</table>
</div>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
<br />
---
<br />
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- BADGE > GENERAL -->
[general-npmjs-uri]: https://npmjs.com
[general-nodejs-uri]: https://nodejs.org
[general-npmtrends-uri]: http://npmtrends.com/csf-firewall
<!-- BADGE > VERSION > GITHUB -->
[github-version-img]: https://img.shields.io/github/v/tag/TheBinaryNinja/tvapp2?logo=GitHub&label=Version&color=ba5225
[github-version-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
<!-- BADGE > LICENSE > MIT -->
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
[license-mit-uri]: https://github.com/TheBinaryNinja/tvapp2/blob/main/LICENSE
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
[github-downloads-img]: https://img.shields.io/github/downloads/TheBinaryNinja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
[github-downloads-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
[github-size-img]: https://img.shields.io/github/repo-size/TheBinaryNinja/tvapp2?logo=github&label=Size&color=59702a
[github-size-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
<!-- BADGE > ALL CONTRIBUTORS -->
[contribs-all-img]: https://img.shields.io/github/all-contributors/TheBinaryNinja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
<!-- BADGE > GITHUB > BUILD > NPM -->
[github-build-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-release.yml
<!-- BADGE > GITHUB > BUILD > Pypi -->
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[github-build-pypi-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/pypi-release.yml
<!-- BADGE > GITHUB > TESTS -->
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
[github-tests-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-tests.yml
<!-- BADGE > GITHUB > COMMIT -->
[github-commit-img]: https://img.shields.io/github/last-commit/TheBinaryNinja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
[github-commit-uri]: https://github.com/TheBinaryNinja/tvapp2/commits/main/
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
[github-docker-version-uri]: https://github.com/TheBinaryNinja/tvapp2/pkgs/container/tvapp2
<!-- BADGE > Dockerhub > Docker Image -->
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
<!-- BADGE > Gitea 2 > Docker Image -->
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
[btn-github-submit-uri]: https://github.com/TheBinaryNinja/tvapp2/issues
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

View File

@@ -1,16 +0,0 @@
authors:
Aetherinox:
name: Aetherinox
description: Developer
avatar: https://avatars.githubusercontent.com/u/118329232
url: https://github.com/Aetherinox
iflip721:
name: iflip721
description: Developer
avatar: https://avatars.githubusercontent.com/u/28721588
url: https://github.com/iflip721
Optx:
name: Optx
description: Developer
avatar: https://avatars.githubusercontent.com/u/32874812
url: https://github.com/Nvmdfth

View File

@@ -1,3 +0,0 @@
comments: true
hide:
- feedback

View File

@@ -1 +0,0 @@
# Blog

View File

@@ -1,521 +0,0 @@
---
title: Environment Variables
tags:
- config
---
# Environment Variables
Environment variables allow you to modify how TVApp2 functions within a docker container. Ensure that
you understand the setting you are changing before you modify these values, otherwise, TVApp2 may fail to
start due to misconfigurations.
<br />
## TZ
<!-- md:control env -->
<!-- md:version stable-1.0.0 -->
<!-- md:default `Etc/UTC` -->
The `TZ` environment variable specifies the timezone that your docker container will
utilize. This is useful for syncing your local time with console outputs such as
our logging system.
=== "Example"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- TZ=Etc/UTC # (1)
```
1. :information: Changing this env variable will change the time for anything
related to the TVApp2 docker container.
=== "Timezones"
``` yaml
Etc/UTC
Africa/Cairo
Africa/Johannesburg
Africa/Lagos
America/Argentina/Buenos_Aires
America/Bogota
America/Caracas
America/Chicago
America/El_Salvador
America/Juneau
America/Lima
America/Los_Angeles
America/Mexico_City
America/New_York
America/Phoenix
America/Santiago
America/Sao_Paulo
America/Toronto
America/Vancouver
Asia/Almaty
Asia/Ashkhabad
Asia/Bahrain
Asia/Bangkok
Asia/Chongqing
Asia/Dubai
Asia/Ho_Chi_Minh
Asia/Hong_Kong
Asia/Jakarta
Asia/Jerusalem
Asia/Kathmandu
Asia/Kolkata
Asia/Kuwait
Asia/Muscat
Asia/Qatar
Asia/Riyadh
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Asia/Tehran
Asia/Tokyo
Atlantic/Reykjavik
Australia/ACT
Australia/Adelaide
Australia/Brisbane
Australia/Sydney
Europe/Athens
Europe/Belgrade
Europe/Berlin
Europe/Copenhagen
Europe/Helsinki
Europe/Istanbul
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Moscow
Europe/Paris
Europe/Riga
Europe/Rome
Europe/Stockholm
Europe/Tallinn
Europe/Vilnius
Europe/Warsaw
Europe/Zurich
Pacific/Auckland
Pacific/Chatham
Pacific/Fakaofo
Pacific/Honolulu
Pacific/Norfolk
US/Mountain
```
<br />
## WEB_IP
<!-- md:control env -->
<!-- md:version stable-1.0.0 -->
<!-- md:default `0.0.0.0` -->
The `WEB_IP` environment variable allows you to define what IP address will be
bound to the TVApp2 docker image.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- WEB_IP=0.0.0.0 # (1)
```
1. :information: Specify `0.0.0.0` to bind to all local IP addresses.
<br />
## WEB_PORT
<!-- md:control env -->
<!-- md:version stable-1.0.0 -->
<!-- md:default `4124` -->
The `WEB_PORT` environment variable allows you to define what port the TVApp2
docker container will listen to.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- WEB_IP=4124 # (1)
```
1. :information: The default port is `4124`
<br />
## WEB_ENCODING
<!-- md:control env -->
<!-- md:version stable-1.3.0 -->
<!-- md:default `deflate, br` -->
The `WEB_ENCODING` environment variable allows you to customize the HTTP `Accept-Encoding` request and response header. This value specifies what content encoding the sender can understand when sending these requests.
Most users will not need to modify this value unless you are running Jellyfin and receive the following error when attempting to sync EPG data between Jellyfin and the TVApp2 container:
!!! warning "Jellyfin Error"
```
[ERR] [27] Jellyfin.LiveTv.Guide.GuideManager: Error getting programs for channel
XXXXXXXXXXXXXXX (Source 2) System.Xml.XmlException: '', hexadecimal value 0x1F,
is an invalid character. Line 1, position 1.
```
If you receive the above error and you have already customized this environment variable to include `gzip`, you must remove it from your accepted encoders string to fix the error.
=== "Old"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- WEB_ENCODING: 'gzip, deflate, br'
```
=== "New"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- WEB_ENCODING: 'deflate, br'
```
<br />
## URL_REPO
<!-- md:control env -->
<!-- md:version stable-1.0.0 -->
<!-- md:default `https://git.binaryninja.net/binaryninja` -->
<!-- md:flag dangerous -->
The `URL_REPO` environment variable allows you to specify what Github repo is used to communicate
with in order to fetch IPTV data. This is used as an internal environment variable by the developers
and should not be changed by the end-user; otherwise you will be unable to fetch IPTV data.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- URL_REPO=https://git.binaryninja.net/binaryninja # (1)
```
1. :warning: It is highly recommended that you do not change this value
otherwise you will not be able to download the latest M3U playlists
and EPG guide data.
<br />
## FILE_URL
<!-- md:control env -->
<!-- md:version stable-1.2.0 -->
<!-- md:default `urls.txt` -->
The `FILE_URL` environment variable allows you to specify what the name of the downloaded `urls.txt` cache file. This file is downloaded when you first spin up the TVApp2 container.
There should be no need to utilize this environment variable unless you have a specific reason.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- FILE_URL=urls.txt # (1)
```
1. :warning: There is really no reason to modify this environment variable
unless you have a specific purpose.
<br />
## FILE_M3U
<!-- md:control env -->
<!-- md:version stable-1.1.0 -->
<!-- md:default `playlist.m3u8` -->
The `FILE_M3U` environment variable allows you to specify what the name of the downloaded `playlist.m3u8` file will be. This file is downloaded when you first spin up the TVApp2 container, and contains a list of what channels you can pick from.
There should be no need to utilize this environment variable unless you have a specific reason.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- FILE_M3U=playlist.m3u8 # (1)
```
1. :warning: There is really no reason to modify this environment variable
unless you have a specific purpose.
<br />
## FILE_EPG
<!-- md:control env -->
<!-- md:version stable-1.1.0 -->
<!-- md:default `xmltv.xml` -->
The `FILE_EPG` environment variable specifies the filename that will be utilized when
your .xml EPG playlist file is generated.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- FILE_EPG=xmltv.xml # (1)
```
1. :information: Changing this file only changes the filename locally; it does
not affect the server-side fetching mechanism.
<br />
## FILE_GZIP
<!-- md:control env -->
<!-- md:version stable-1.1.0 -->
<!-- md:default `xmltv.xml.gz` -->
The `FILE_GZIP` environment variable specifies the filename that will be utilized when
a compressed `.gzip` is generated and when you download the file.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- FILE_GZIP=xmltv.xml.gz # (1)
```
1. :information: Changing this file only changes the filename locally for
generation and downloading. It does not affect the server-side fetching
mechanism.
<br />
## STREAM_QUALITY
<!-- md:control env -->
<!-- md:version stable-1.1.0 -->
<!-- md:default `hd` -->
The `STREAM_QUALITY` environment variable specifies the default stream quality that will
be used when you initiate a new channel to view.
Available Options:
* `hd` High Definition
* `sd` Standard Definition
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- STREAM_QUALITY=hd # (1)
```
1. :information: This environment variable has the following options:
- hd
- sd
<br />
## DIR_BUILD
<!-- md:control env -->
<!-- md:version stable-1.0.0 -->
<!-- md:default `/usr/src/app` -->
<!-- md:flag dangerous -->
The `DIR_BUILD` environment variable specifies what local folder will be utilized
by the TVApp2 docker container when the container builds the app.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- DIR_BUILD=/usr/src/app # (1)
```
1. :warning: You should not change this unless you are an advanced user.
<br />
## DIR_RUN
<!-- md:control env -->
<!-- md:version stable-1.0.0 -->
<!-- md:default `/usr/src/app` -->
<!-- md:flag dangerous -->
The `DIR_RUN` environment variable specifies what local folder will be utilized
by the TVApp2 docker container when the container has built the app and placed it
into a production folder.
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- DIR_RUN=/usr/bin/app # (1)
```
1. :warning: You should not change this unless you are an advanced user.
<br />
## LOG_LEVEL
<!-- md:control env -->
<!-- md:version stable-1.1.0 -->
<!-- md:default `4` -->
The `LOG_LEVEL` environment variable allows you specify how deep logs should go
when being output to your console.
=== "Example"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- LOG_LEVEL=4 # (1)
```
1. :information: The default log level is `4` (info).
=== "Log Levels"
| Log Level | Name | Description |
| --------------- | ----------- | ------------------------------------------------------------------------------- |
| `6` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-trace-color) " } Trace | Displays all possible logs in console, along with anything below this line. |
| `5` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-debug-color) " } Debug | Displays debug / developer logs, along with anything below this line. |
| `4` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-info-color) " } Info | Displays informative logs, along with anything below this line. |
| `3` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-notice-color) " } Notice | Displays important notices, along with anything below this line. |
| `2` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-warn-color) " } Warn | Displays warnings, along with anything below this line. |
| `1` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-error-color) " } Error | Displays only errors, none of the log levels above this line will be shown |
<br />
<br />

View File

@@ -1,109 +0,0 @@
---
title: Environment Variables
tags:
- config
---
# Mountable Volumes
Mountable volumes in Docker allow you to share folders within a docker container with your host machine. This allows you to access these specific files without having to bash into the container and using the terminal to navigate around.
The TVApp2 docker image provides a few different paths that you can mount to your host machine; as outlined below.
<br />
## 📁 /usr/bin/app
<!-- md:control volume -->
<!-- md:version stable-1.0.0 -->
The mountable volume `/usr/bin/app` is where TVApp2 files will be placed once the app has been built when your docker container spins up. The files in this folder include:
| File | Description |
| --- | --- |
| `📁 node_modules` | List of all NodeJS packages utilized by TVApp2 |
| `📁 www` | Main storage folder for TVApp2. Contains website files and M3U / EPG synced files |
| `📄 package.json` | NodeJS package file |
| `📄 playlist.m3u8` | Generated playlist containing channels |
| `📄 urls.txt` | List containing cached URLs utilized by TVApp2 |
| `📄 xmltv.xml` | EPG guide data in uncompressed XML format |
| `📄 xmltv.xml.gz` | EPG guide data in compressed GZ archive |
| `📄 index.js` | Main source code file for TVApp2 |
<br />
=== "Example"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="7" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- ./app:/usr/bin/app # (1)
```
1. :information: Changing this env variable will change the time for anything
related to the TVApp2 docker container.
<br />
This folder path can be changed by specifying a new path with the environment variable `DIR_RUN`
=== "Example"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="7" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- ./app:/usr/bin/app # (1) (2)
```
1. :information: Changing this env variable will change the folder within the docker container which stores the fully built TVApp2 files.
2. This should not be used unless you know what you're doing
<br />
---
<br />
## 📁 /config
<!-- md:control volume -->
<!-- md:version stable-1.0.0 -->
The mountable volume `/config` defines where the TVApp2 application will store SSL certificates related to the TVApp2 web interface being ran using https instead of http. The files in this folder include:
| File | Description |
| --- | --- |
| `📁 keys` | Folder which stores the SSL cert and keys |
| `📄 keys/cert.crt` | SSL public certificate |
| `📄 keys/key.crt` | SSL private key |
<br />
=== "Example"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="7" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- ./config:/config # (1) (2)
```
1. :information: Changing this env variable will change the folder within the docker container which stores the fully built TVApp2 files.
2. This should not be used unless you know what you're doing
<br />
<br />

View File

@@ -1,34 +0,0 @@
---
title: Home
tags:
- home
---
<p align="center"><img src="https://techcrunch.com/wp-content/uploads/2017/10/roku-live-tv-screen-1600x900.png" width="860"></p>
<h1 align="center"><b>TVApp2</b></h1>
<p align="center" markdown="1">
![Version](https://img.shields.io/github/v/tag/TheBinaryNinja/tvapp2?logo=GitHub&label=version&color=ba5225)
![Downloads](https://img.shields.io/github/downloads/TheBinaryNinja/tvapp2/total)
![Repo Size](https://img.shields.io/github/repo-size/TheBinaryNinja/tvapp2?label=size&color=59702a)
![Last Commit)](https://img.shields.io/github/last-commit/TheBinaryNinja/tvapp2?color=b43bcc)
</p>
This documentation is related to the github repository for <a href="https://github.com/TheBinaryNinja/tvapp2">TVApp2</a>; a NodeJS powered application which allows you to fetch M3U playlists and EPG guide data from various popular online IPTV services such as TheTvApp, TVPass, and MoveOnJoy. These services provide high-quality and premium channels available as Live TV.
<br />
This documentation covers the following:
- How to install and configure TVApp2
- Managing your TVApp2 docker image
- Building your own docker image
- Traefik and Authentik Integration
<br />
---
<br />

View File

@@ -1,13 +0,0 @@
[mkdocs]: https://www.mkdocs.org
[mkdocs.dotfiles]: https://www.mkdocs.org/dev-guide/themes/#dot-files
[mkdocs.metadata]: https://www.mkdocs.org/user-guide/writing-your-docs/#yaml-style-meta-data
[mkdocs.env]: https://www.mkdocs.org/user-guide/configuration/#environment-variables
[mkdocs.docs_dir]: https://www.mkdocs.org/user-guide/configuration/#docs_dir
[mkdocs.extra_templates]: https://www.mkdocs.org/user-guide/configuration/#extra_templates
[mkdocs.site_dir]: https://www.mkdocs.org/user-guide/configuration/#site_dir
[mkdocs.site_url]: https://www.mkdocs.org/user-guide/configuration/#site_url
[mkdocs.site_description]: https://www.mkdocs.org/user-guide/configuration/#site_description
[mkdocs.nav]: https://www.mkdocs.org/user-guide/configuration/#nav
[mkdocs.plugins]: https://www.mkdocs.org/user-guide/configuration/#plugins
[mkdocs.strict]: https://www.mkdocs.org/user-guide/configuration/#strict
[mkdocs.use_directory_urls]: https://www.mkdocs.org/user-guide/configuration/#use_directory_urls

View File

@@ -1,9 +0,0 @@
---
template: home.html
title: TVApp2
social:
cards_layout_options:
title: TVApp2
---
Welcome to the TVApp2 documentation

View File

@@ -1,125 +0,0 @@
---
title: "Install: docker-run"
tags:
- install
---
# docker run
Our documentation provides two ways that you may start up a TVApp2 docker container:
<div class="grid cards" markdown>
- :material-circle: &nbsp; [docker run](docker-run.md)
---
Spin up the TVApp2 container using the `docker run` command.
This is useful for quick launches, but is not time efficient
if you plan to use this container long-term.
This requires a longer command that must be used each time
you wish to bring the container up.
- :material-circle: &nbsp; [docker compose](docker-compose.md)
---
Spin up the TVApp2 container by creating a `📄 docker-compose.yml`
file which will store all of your options such as env variables,
mounted volumes, and labels.
To bring the container up, `cd` into the folder with the
`📄 docker-compose.yml` file, and run the
command `docker compose up -d`.
</div>
<br />
The `🗔 docker run` command allows you to start up a docker container by providing a set of [options](#command-options) which define how the container should operate, including the environment variables, mounted volumes, assigned IP address, etc.
<br />
---
<br />
## Start TVApp2
Pulling the image if needed and starting the container. To spin up a TVApp2 container using this method; run a command similar to the below example. See the section [Options](#options) below for a list of what you can specify.
=== "Terminal"
```shell
docker run -d \
--restart=unless-stopped \ # (1)!
--name tvapp2 \ # (2)!
-p 4124:4124 \ # (3)!
-e "TZ=Etc/UTC" \ # (4)!
-v ${PWD}/app:/usr/bin/app \ # (5)!
ghcr.io/thebinaryninja/tvapp2:latest # (6)!
```
1. Specifies what happens if the container becomes unresponsive or goes down.
2. Name to assign the container; otherwise, a random id will be given.
3. Port that will be used for the container
4. Environment variable which specifies the timezone to use for the container.
5. Mount the container volume `/usr/bin/app` to your host machine in the subfolder `./app`
6. Specifies what docker image to spin up.
<br />
To confirm that the container has been brought up, run the command `docker ps | grep tvapp2`. If you have the app [Portainer](https://portainer.io/), you can sign into your admin interface and view your TVApp2 container details, instead of using a command-line.
```
e95236c42b43 binaryninja/tvapp2:1.4.0 "/init" 3 seconds ago Up 3 seconds 4124/tcp tvapp2
```
<br />
---
<br />
## Options
Review the list of docker run options below. These allow you to define how a docker container will start up.
???- note "Official Docker Documentation"
To view a full list of the available docker parameters, view the official docker documentation at:
- https://docs.docker.com/reference/cli/docker/container/run/
| Parameter / Flag | Description |
| --- | --- |
| `-d, --detach` | Run container in background and print container ID |
| `-e, --env` | Set environment variable |
| `--env-file` | Read in a file of environment variables |
| `--expose` | Expose a port or a range of ports |
| `--health-cmd` | Command to run to check health |
| `--health-interval` | Time between running the check<br/>`ms|s|m|h` (default 0s) |
| `--health-retries` | Consecutive failures needed to report unhealthy |
| `--health-start-interval` | Time between running the check during the start period<br/>`ms|s|m|h` (default 0s) |
| `--health-start-period` | Start period for the container to initialize before starting health-retries countdown<br/>`ms|s|m|h` (default 0s) |
| `--health-timeout` | Maximum time to allow one check to run<br/>`ms|s|m|h` (default 0s) |
| `-h, --hostname` | Container host name |
| `--ip` | IPv4 address (e.g., 172.30.100.104) |
| `--ip6` | IPv6 address (e.g., 2001:db8::33) |
| `-l, --label` | Set meta data on a container |
| `--mount` | Attach a filesystem mount to the container |
| `--name` | Assign a name to the container |
| `--network` | Connect a container to a network |
| `--privileged` | Give extended privileges to this container |
| `-p, --publish` | Publish a container's port(s) to the host |
| `--pull` | Pull image before running<br/>`always`, `missing`, `never` |
| `--restart` | Restart policy to apply when a container exits <br/> `on-failure[:max-retries]`, `always`, `unless-stopped` |
| `-u, --user` | Username or UID <br/>`<name|uid>[:<group|gid>]` |
| `-v, --volume` | Bind mount a volume |
| `-w, --workdir` | Working directory inside the container |
<br />
<br />
<br />

View File

@@ -1,47 +0,0 @@
---
title: Install
tags:
- install
---
# Installing TVApp2
To install TVApp2 using docker; you will need to use either the `🗔 docker run` command, or create a `📄 docker-compose.yml` file which contains information about how to pull the latest image and spin the container up. We have provided instructions for both.
<br />
{==
Select your desired option to bring up the TVApp2 container with:
==}
<div class="grid cards" markdown>
- :material-circle: &nbsp; [docker run](docker-run.md)
---
Spin up the TVApp2 container using the `docker run` command.
This is useful for quick launches, but is not time efficient
if you plan to use this container long-term.
This requires a longer command that must be used each time
you wish to bring the container up.
- :material-circle: &nbsp; [docker compose](docker-compose.md)
---
Spin up the TVApp2 container by creating a `📄 docker-compose.yml`
file which will store all of your options such as env variables,
mounted volumes, and labels.
To bring the container up, `cd` into the folder with the
`📄 docker-compose.yml` file, and run the
command `docker compose up -d`.
</div>
<br />
<br />

View File

@@ -1,6 +0,0 @@
document$.subscribe(function() {
var tables = document.querySelectorAll("article table:not([class])")
tables.forEach(function(table) {
new Tablesort(table)
})
})

File diff suppressed because it is too large Load Diff

View File

@@ -1,164 +0,0 @@
---
title: Healthcheck
tags:
- usage
---
# Healthcheck
This docker container includes the ability to run health checks between the container api and outside services such as Portainer, or any other app that has the ability to query the endpoint `api/health`.
<br />
---
<br />
## API
<!-- md:version stable-1.4.0 -->
This container includes the ability to run health checks utilizing the built-in API. You can directly access the health check and view a json formatted result with the url `https://tvapp2.domain.lan/api/health`
=== "Example"
``` { .yaml .copy .select title="/api/health" linenums="1" }
{
"ip": "172.18.2.1",
"gateway": "172.18.0.1",
"uptime": 5903.549082501,
"message": "healthy",
"status": "healthy",
"ref": "/api/health",
"method": "GET",
"code": 200,
"timestamp": 1744386346242
}
```
<br />
Numerous aliases have been added; you can use any of the following URLs to access the same health check results as they go to the same endpoint:
- https://tvapp2.domain.lan/api/health
- https://tvapp2.domain.lan/api/status
<br />
---
<br />
## Portainer
<!-- md:version stable-1.3.0 -->
To run a health check between TVApp2 and Portainer, apply the following lines of code to your TVApp2 `docker-compose.yml`. Two examples have been provided, you can use either one; `wget` or `curl`:
=== "Using CURL"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="14-18" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- TZ=Etc/UTC
health check:
test: "curl --fail --silent http://127.0.0.1:4124/api/health | grep -i healthy || exit 1"
interval: 15s
timeout: 10s
retries: 3
```
=== "Using WGET"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="14-18" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- TZ=Etc/UTC
health check:
test: "wget -qO- http://127.0.0.1:4124/api/health | grep -i healthy || exit 1"
interval: 15s
timeout: 10s
retries: 3
```
<br />
---
<br />
## Web Interface
<!-- md:version stable-1.4.0 -->
The TVApp2 web interface is equip with its own health check which is ran every `10 minutes` by default. Users will notice a health indicator in the top right of the header navigation bar which is represented by the :octicons-heart-fill-24:{ .heart } icon.
When the health check is ran every 10 minutes; a toast notification will appear in the lower-right side of the page:
<figure markdown="span">
![Image settings](../../assets/images/health-toast.gif){ width="80%" }
<figcaption>Health check toast notification</figcaption>
</figure>
<br />
### Health Check Duration
<!-- md:control env -->
<!-- md:version stable-1.4.0 -->
<!-- md:default `600000` -->
By default, a health check between the TVApp2 container and the web interface is done every `10 minutes`, but you can change this duration to something less or more. Be aware that if you set the time too low, you will constantly be spammed with toast notifications.
To change the health check delay, add the environment variable `HEALTH_TIMER` to your TVApp2 `docker-compose.yml`. Duration is in milliseconds.
<br />
=== "Example"
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
services:
tvapp2:
container_name: tvapp2
image: ghcr.io/thebinaryninja/tvapp2:latest
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- ./config:/config
- ./app:/usr/bin/app
environment:
- HEALTH_TIMER=600000 # (1)
```
1. :information: Defines how often to perform health checks between the container and the web interface. Time is in milliseconds. <br /><br />Default value is `600000` (10 minutes)
=== "Time Chart"
| HEALTH_TIMER Value | Delay Between Checks |
| --- | --- |
| `HEALTH_TIMER=300000` | 5 minutes |
| `HEALTH_TIMER=600000` | 10 minutes |
| `HEALTH_TIMER=1200000` | 20 minutes |
| `HEALTH_TIMER=1800000` | 30 minutes |
| `HEALTH_TIMER=3600000` | 1 hour |
<br />
<br />

BIN
docs/img/002.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/img/banner-sq.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/img/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,23 +0,0 @@
# #
# Copyright (c) 2025 Aetherinox
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# #
__version__ = "9.5.13"

View File

@@ -1,21 +0,0 @@
# #
# Copyright (c) 2025 Aetherinox
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# #

View File

@@ -1,100 +0,0 @@
# #
# Copyright (c) 2025 Aetherinox
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# #
from __future__ import annotations
import codecs
import functools
import material
import os
from glob import iglob
from inspect import getfile
from markdown import Markdown
from pymdownx import emoji, twemoji_db
from xml.etree.ElementTree import Element
# -----------------------------------------------------------------------------
# Functions
# -----------------------------------------------------------------------------
# Create twemoji index
def twemoji(options: object, md: Markdown):
paths = options.get("custom_icons", [])[:]
return _load_twemoji_index(tuple(paths))
# Create emoji or icon
def to_svg(
index: str, shortname: str, alias: str, uc: str | None, alt: str,
title: str, category: str, options: object, md: Markdown
):
if not uc:
icons = md.inlinePatterns["emoji"].emoji_index["emoji"]
# Create and return element to host icon
el = Element("span", { "class": options.get("classes", index) })
el.text = md.htmlStash.store(_load(icons[shortname]["path"]))
return el
# Delegate to `pymdownx.emoji` extension
return emoji.to_svg(
index, shortname, alias, uc, alt, title, category, options, md
)
# -----------------------------------------------------------------------------
# Helper functions
# -----------------------------------------------------------------------------
# Load icon
@functools.lru_cache(maxsize = None)
def _load(file: str):
with codecs.open(file, encoding = "utf-8") as f:
return f.read()
# Load twemoji index and add icons
@functools.lru_cache(maxsize = None)
def _load_twemoji_index(paths):
index = {
"name": "twemoji",
"emoji": twemoji_db.emoji,
"aliases": twemoji_db.aliases
}
# Compute path to theme root and traverse all icon directories
root = os.path.dirname(getfile(material))
root = os.path.join(root, "templates", ".icons")
for path in [*paths, root]:
base = os.path.normpath(path)
# Index icons provided by the theme and via custom icons
glob = os.path.join(base, "**", "*.svg")
glob = iglob(os.path.normpath(glob), recursive = True)
for file in glob:
icon = file[len(base) + 1:-4].replace(os.path.sep, "-")
# Add icon to index
name = f":{icon}:"
if not any(name in index[key] for key in ["emoji", "aliases"]):
index["emoji"][name] = { "name": name, "path": file }
# Return index
return index

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M0 64L0 448c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-384c0-35.3-28.7-64-64-64L64 0C28.7 0 0 28.7 0 64zm64 48c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zm0 128c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zm0 128c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zM192 128c0-8.8 7.2-16 16-16l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16zm0 128c0-8.8 7.2-16 16-16l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16zm0 128c0-8.8 7.2-16 16-16l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16z"/><path class="fa-primary" d="M64 112c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zm0 128c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zM80 352l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32c0-8.8 7.2-16 16-16z"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M162.4 6c-1.5-3.6-5-6-8.9-6h-19c-3.9 0-7.5 2.4-8.9 6L104.9 57.7c-3.2 8-14.6 8-17.8 0L66.4 6c-1.5-3.6-5-6-8.9-6H48C21.5 0 0 21.5 0 48V256v22.4V288H9.6 374.4 384v-9.6V256 48c0-26.5-21.5-48-48-48H230.5c-3.9 0-7.5 2.4-8.9 6L200.9 57.7c-3.2 8-14.6 8-17.8 0L162.4 6z"/><path class="fa-primary" d="M0 288H384v32c0 35.3-28.7 64-64 64H256v64c0 35.3-28.7 64-64 64s-64-28.7-64-64V384H64c-35.3 0-64-28.7-64-64V288zM192 464a16 16 0 1 0 0-32 16 16 0 1 0 0 32z"/></svg>

Before

Width:  |  Height:  |  Size: 767 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M432 80a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm0 112a80 80 0 1 0 0-160 80 80 0 1 0 0 160z"/><path class="fa-primary" d="M0 320C0 426 86 512 192 512s192-86 192-192c0-91.2-130.2-262.3-166.6-308.3C211.4 4.2 202.5 0 192.9 0h-1.8c-9.6 0-18.5 4.2-24.5 11.7C130.2 57.7 0 228.8 0 320z"/></svg>

Before

Width:  |  Height:  |  Size: 594 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 512C86 512 0 426 0 320C0 228.8 130.2 57.7 166.6 11.7C172.6 4.2 181.5 0 191.1 0h1.8c9.6 0 18.5 4.2 24.5 11.7C253.8 57.7 384 228.8 384 320c0 106-86 192-192 192zm75.3-267.3c-6.2-6.2-16.4-6.2-22.6 0l-128 128c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l128-128c6.2-6.2 6.2-16.4 0-22.6zM136 288a24 24 0 1 0 0-48 24 24 0 1 0 0 48zM248 400a24 24 0 1 0 0-48 24 24 0 1 0 0 48z"/><path class="fa-primary" d="M267.3 267.3c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0l-128 128c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l128-128zM160 264a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zM272 376a24 24 0 1 0 -48 0 24 24 0 1 0 48 0z"/></svg>

Before

Width:  |  Height:  |  Size: 921 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M320 512c53.2 0 101.4-21.6 136.1-56.6l-298.3-235C140 257.1 128 292.3 128 320c0 106 86 192 192 192zM205.8 136L505.2 370.7c4.4-16.1 6.8-33.1 6.8-50.7c0-91.2-130.2-262.3-166.6-308.3C339.4 4.2 330.5 0 320.9 0h-1.8c-9.6 0-18.5 4.2-24.5 11.7C277.8 33 240.7 81.3 205.8 136zM224 336c0 44.2 35.8 80 80 80c8.8 0 16 7.2 16 16s-7.2 16-16 16c-61.9 0-112-50.1-112-112c0-8.8 7.2-16 16-16s16 7.2 16 16z"/><path class="fa-primary" d="M5.1 9.2C13.3-1.2 28.4-3.1 38.8 5.1l592 464c10.4 8.2 12.3 23.3 4.1 33.7s-23.3 12.3-33.7 4.1L9.2 42.9C-1.2 34.7-3.1 19.6 5.1 9.2z"/></svg>

Before

Width:  |  Height:  |  Size: 867 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 512C86 512 0 426 0 320C0 228.8 130.2 57.7 166.6 11.7C172.6 4.2 181.5 0 191.1 0h1.8c9.6 0 18.5 4.2 24.5 11.7C253.8 57.7 384 228.8 384 320c0 106-86 192-192 192zM96 336c0-8.8-7.2-16-16-16s-16 7.2-16 16c0 61.9 50.1 112 112 112c8.8 0 16-7.2 16-16s-7.2-16-16-16c-44.2 0-80-35.8-80-80z"/><path class="fa-primary" d="M80 320c8.8 0 16 7.2 16 16c0 44.2 35.8 80 80 80c8.8 0 16 7.2 16 16s-7.2 16-16 16c-61.9 0-112-50.1-112-112c0-8.8 7.2-16 16-16z"/></svg>

Before

Width:  |  Height:  |  Size: 761 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M576 128V384H64V128H576zM64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H576c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64z"/><path class="fa-primary" d="M104 184c0-13.3 10.7-24 24-24s24 10.7 24 24V328c0 13.3-10.7 24-24 24s-24-10.7-24-24V184z"/></svg>

Before

Width:  |  Height:  |  Size: 571 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M576 128V384H64V128H576zM64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H576c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64z"/><path class="fa-primary" d="M205.9 174.3c-3.9-8.7-12.4-14.3-21.9-14.3s-18.1 5.6-21.9 14.3l-64 144c-5.4 12.1 .1 26.3 12.2 31.7s26.3-.1 31.7-12.2l4.3-9.7h75.5l4.3 9.7c5.4 12.1 19.6 17.6 31.7 12.2s17.6-19.6 12.2-31.7l-64-144zM200.4 280H167.6L184 243.1 200.4 280zM304 184v8 64 64 8c0 13.3 10.7 24 24 24h68c33.1 0 60-26.9 60-60c0-18.6-8.5-35.3-21.8-46.3c3.7-7.8 5.8-16.5 5.8-25.7c0-33.1-26.9-60-60-60H328c-13.3 0-24 10.7-24 24zm48 24h28c6.6 0 12 5.4 12 12s-5.4 12-12 12H352V208zm0 96V280h28 16c6.6 0 12 5.4 12 12s-5.4 12-12 12H352z"/></svg>

Before

Width:  |  Height:  |  Size: 981 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M264.8 64C277.6 64 288 74.4 288 87.2c0 9.2-5.8 17.3-13.2 22.8c-11.6 8.7-18.8 20.7-18.8 34c0 26.5 28.7 48 64 48s64-21.5 64-48c0-13.3-7.2-25.3-18.8-34c-7.4-5.5-13.2-13.6-13.2-22.8C352 74.4 362.4 64 375.2 64L464 64c26.5 0 48 21.5 48 48l0 88.8c0 12.8 10.4 23.2 23.2 23.2c9.2 0 17.3-5.8 22.8-13.2c8.7-11.6 20.7-18.8 34-18.8c26.5 0 48 28.7 48 64s-21.5 64-48 64c-13.3 0-25.3-7.2-34-18.8c-5.5-7.4-13.6-13.2-22.8-13.2c-12.8 0-23.2 10.4-23.2 23.2l0 88.8c0 26.5-21.5 48-48 48l-88.8 0c-12.8 0-23.2-10.4-23.2-23.2c0-9.2 5.8-17.3 13.2-22.8c11.6-8.7 18.8-20.7 18.8-34c0-26.5-28.7-48-64-48s-64 21.5-64 48c0 13.3 7.2 25.3 18.8 34c7.4 5.5 13.2 13.6 13.2 22.8c0 12.8-10.4 23.2-23.2 23.2L176 448c-26.5 0-48-21.5-48-48l0-88.8c0-12.8-10.4-23.2-23.2-23.2c-9.2 0-17.3 5.8-22.8 13.2C73.3 312.8 61.3 320 48 320c-26.5 0-48-28.7-48-64s21.5-64 48-64c13.3 0 25.3 7.2 34 18.8c5.5 7.4 13.6 13.2 22.8 13.2c12.8 0 23.2-10.4 23.2-23.2l0-88.8c0-26.5 21.5-48 48-48l88.8 0z"/><path class="fa-primary" d=""/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 104.8c0-9.2-5.8-17.3-13.2-22.8C167.2 73.3 160 61.3 160 48c0-26.5 28.7-48 64-48s64 21.5 64 48c0 13.3-7.2 25.3-18.8 34c-7.4 5.5-13.2 13.6-13.2 22.8c0 12.8 10.4 23.2 23.2 23.2l56.8 0c26.5 0 48 21.5 48 48l0 56.8c0 12.8 10.4 23.2 23.2 23.2c9.2 0 17.3-5.8 22.8-13.2c8.7-11.6 20.7-18.8 34-18.8c26.5 0 48 28.7 48 64s-21.5 64-48 64c-13.3 0-25.3-7.2-34-18.8c-5.5-7.4-13.6-13.2-22.8-13.2c-12.8 0-23.2 10.4-23.2 23.2L384 464c0 26.5-21.5 48-48 48l-56.8 0c-12.8 0-23.2-10.4-23.2-23.2c0-9.2 5.8-17.3 13.2-22.8c11.6-8.7 18.8-20.7 18.8-34c0-26.5-28.7-48-64-48s-64 21.5-64 48c0 13.3 7.2 25.3 18.8 34c7.4 5.5 13.2 13.6 13.2 22.8c0 12.8-10.4 23.2-23.2 23.2L48 512c-26.5 0-48-21.5-48-48L0 343.2C0 330.4 10.4 320 23.2 320c9.2 0 17.3 5.8 22.8 13.2C54.7 344.8 66.7 352 80 352c26.5 0 48-28.7 48-64s-21.5-64-48-64c-13.3 0-25.3 7.2-34 18.8C40.5 250.2 32.4 256 23.2 256C10.4 256 0 245.6 0 232.8L0 176c0-26.5 21.5-48 48-48l120.8 0c12.8 0 23.2-10.4 23.2-23.2z"/><path class="fa-primary" d=""/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M0 288L0 448c0 35.3 28.7 64 64 64l160 0 0-64c0-8.8-7.2-16-16-16l-16 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l16 0c8.8 0 16-7.2 16-16l0-64-64 0c-8.8 0-16-7.2-16-16l0-16c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 16c0 8.8-7.2 16-16 16L0 288zM304 16l0 48c0 8.8 7.2 16 16 16l16 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-16 0c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l36 0c6.6 0 12 5.4 12 12l0 4c0 17.7 14.3 32 32 32s32-14.3 32-32l0-4c0-6.6 5.4-12 12-12l52 0c8.8 0 16-7.2 16-16l0-128c0-35.3-28.7-64-64-64L320 0c-8.8 0-16 7.2-16 16z"/><path class="fa-primary" d="M0 288l64 0c8.8 0 16-7.2 16-16l0-16c0-17.7 14.3-32 32-32s32 14.3 32 32l0 16c0 8.8 7.2 16 16 16l64 0 0-68c0-6.6 5.4-12 12-12l4 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-4 0c-6.6 0-12-5.4-12-12l0-52c0-8.8-7.2-16-16-16L64 64C28.7 64 0 92.7 0 128L0 288zm224 0l0 64c0 8.8-7.2 16-16 16l-16 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l16 0c8.8 0 16 7.2 16 16l0 64 160 0c35.3 0 64-28.7 64-64l0-144c0-8.8-7.2-16-16-16l-48 0c-8.8 0-16 7.2-16 16l0 16c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-16c0-8.8-7.2-16-16-16l-64 0z"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M3.4 273.7c-7.9 15.8-1.5 35 14.3 42.9L152.4 384 17.7 451.4C1.9 459.3-4.5 478.5 3.4 494.3C9 505.5 20.3 512 32 512c4.8 0 9.7-1.1 14.3-3.4L224 419.8l177.7 88.8c4.6 2.3 9.5 3.4 14.3 3.4c11.7 0 23-6.5 28.6-17.7c7.9-15.8 1.5-35-14.3-42.9L295.6 384l134.8-67.4c15.8-7.9 22.2-27.1 14.3-42.9C439 262.5 427.7 256 416 256c-4.8 0-9.7 1.1-14.3 3.4L224 348.2 46.3 259.4c-4.6-2.3-9.5-3.4-14.3-3.4c-11.7 0-23 6.5-28.6 17.7z"/><path class="fa-primary" d="M304 234.4c38.6-23 64-62.1 64-106.4C368 57.3 303.5 0 224 0S80 57.3 80 128c0 44.4 25.4 83.5 64 106.4l0 21.6c0 17.7 14.3 32 32 32l96 0c17.7 0 32-14.3 32-32l0-21.6zM136 144a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm144-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>

Before

Width:  |  Height:  |  Size: 1006 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M325.5 192L32 192c-17.7 0-32-14.3-32-32s14.3-32 32-32H325.5c-3.5 10-5.5 20.8-5.5 32s1.9 22 5.5 32zM186.5 384c3.5-10 5.5-20.8 5.5-32s-1.9-22-5.5-32H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H186.5z"/><path class="fa-primary" d="M416 192a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm0-128a96 96 0 1 0 0 192 96 96 0 1 0 0-192zM96 384a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm0-128a96 96 0 1 0 0 192 96 96 0 1 0 0-192z"/></svg>

Before

Width:  |  Height:  |  Size: 717 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M64 480c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64zM224 352c6.7 0 13-2.8 17.6-7.7l104-112c6.5-7 8.2-17.2 4.4-25.9s-12.5-14.4-22-14.4H120c-9.5 0-18.2 5.7-22 14.4s-2.1 18.9 4.4 25.9l104 112c4.5 4.9 10.9 7.7 17.6 7.7z"/><path class="fa-primary" d="M241.6 344.3c-4.5 4.9-10.9 7.7-17.6 7.7s-13-2.8-17.6-7.7l-104-112c-6.5-7-8.2-17.2-4.4-25.9s12.5-14.4 22-14.4H328c9.5 0 18.2 5.7 22 14.4s2.1 18.9-4.4 25.9l-104 112z"/></svg>

Before

Width:  |  Height:  |  Size: 786 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 128c-70.7 0-128 57.3-128 128s57.3 128 128 128H384c70.7 0 128-57.3 128-128s-57.3-128-128-128H192zM384 64c106 0 192 86 192 192s-86 192-192 192H192C86 448 0 362 0 256S86 64 192 64H384z"/><path class="fa-primary" d="M192 128a128 128 0 1 0 0 256 128 128 0 1 0 0-256z"/></svg>

Before

Width:  |  Height:  |  Size: 588 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 64C86 64 0 150 0 256S86 448 192 448H384c106 0 192-86 192-192s-86-192-192-192H192zm192 64a128 128 0 1 1 0 256 128 128 0 1 1 0-256z"/><path class="fa-primary" d="M384 128a128 128 0 1 0 0 256 128 128 0 1 0 0-256z"/></svg>

Before

Width:  |  Height:  |  Size: 536 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 128c-70.7 0-128 57.3-128 128s57.3 128 128 128H384c70.7 0 128-57.3 128-128s-57.3-128-128-128H192zM384 64c106 0 192 86 192 192s-86 192-192 192H192C86 448 0 362 0 256S86 64 192 64H384z"/><path class="fa-primary" d="M96 256a96 96 0 1 0 192 0A96 96 0 1 0 96 256z"/></svg>

Before

Width:  |  Height:  |  Size: 584 B

Some files were not shown because too many files have changed in this diff Show More