[
  {
    "path": ".github/workflows/container-build-publishing.yml",
    "content": "name: Check Tag & Build\n\n# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n# separate terms of service, privacy policy, and support\n# documentation.\n\non:\n  schedule:\n    - cron: '0 * * * *'  # 每小时检查一次\n  push:\n    branches:\n      - main  # 选择你想要的分支\n\nenv:\n  # Use docker.io for Docker Hub if empty\n  REGISTRY: ghcr.io\n  # github.repository as <account>/<repo>\n  IMAGE_NAME: ${{ github.repository }}\n\n\njobs:\n  check-tag:\n    runs-on: ubuntu-latest\n    outputs:\n        trigger: ${{ steps.if_new_tag.outputs.new_tag }}\n    steps:\n      - name: Checkout This Repository\n        uses: actions/checkout@v4\n      \n      - name: Set up Git\n        run: |\n          git config --global user.name 'github-actions[bot]'\n          git config --global user.email 'github-actions[bot]@users.noreply.github.com'\n      \n      - name: Check Latest Tag from Upstream\n        id: check_tag\n        run: |\n          UPSTREAM_LATEST_TAG=$(npm show musicn version | head -n 1)\n          echo \"Latest upstream tag: $UPSTREAM_LATEST_TAG\"\n          echo \"latest_tag=$UPSTREAM_LATEST_TAG\" >> $GITHUB_ENV\n          \n      - name: Check Last Processed Tag\n        id: check_last_tag\n        run: |\n          if [ -f .last_upstream_tag ]; then\n            LAST_PROCESSED_TAG=$(cat .last_upstream_tag)\n            echo \"Last processed tag: $LAST_PROCESSED_TAG\"\n          else\n            LAST_PROCESSED_TAG=\"none\"\n            echo \"No last processed tag found.\"\n          fi\n          echo \"last_tag=$LAST_PROCESSED_TAG\" >> $GITHUB_ENV\n\n      - name: Compare Tags\n        id: if_new_tag\n        if: ${{ env.latest_tag != env.last_tag }}\n        run: |\n          echo \"New tag detected: ${latest_tag}\"\n          echo \"new_tag=true\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Save Last Processed Tag\n        if: ${{ env.latest_tag != env.last_tag }}\n        run: echo ${latest_tag} > .last_upstream_tag\n\n      - name: Commit and Push Last Processed Tag\n        if: ${{ env.latest_tag != env.last_tag }}\n        run: |\n          git add .last_upstream_tag\n          git commit -m \"Update last processed upstream tag to ${latest_tag}\"\n          git push\n\n\n  build:\n    needs: check-tag\n    runs-on: ubuntu-latest\n    if: needs.check-tag.outputs.trigger == 'true'\n    permissions:\n      contents: read\n      packages: write\n      # This is used to complete the identity challenge\n      # with sigstore/fulcio when running outside of PRs.\n      id-token: write\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 'latest'\n\n      - name: Get Latest Tag from Upstream\n        id: get_tag\n        run: |\n          UPSTREAM_LATEST_TAG=$(npm show musicn version | head -n 1)\n          echo \"Latest upstream tag: $UPSTREAM_LATEST_TAG\"\n          echo \"latest_tag=$UPSTREAM_LATEST_TAG\" >> $GITHUB_ENV\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n        with:\n          platforms: all\n\n      - name: Setup Docker buildx\n        uses: docker/setup-buildx-action@v3\n\n      # Login against a Docker registry except on PR\n      # https://github.com/docker/login-action\n      - name: Log into registry ${{ env.REGISTRY }}\n        if: github.event_name != 'pull_request'\n        uses: docker/login-action@v3\n        with:\n          registry: ${{ env.REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      # Extract metadata (tags, labels) for Docker\n      # https://github.com/docker/metadata-action\n      - name: Extract Docker metadata\n        id: meta\n        uses: docker/metadata-action@v5\n        with:\n          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\n          flavor: |\n            latest=true\n          tags: |\n            type=raw,value=${{ env.latest_tag }}\n\n      # Build and push Docker image with Buildx (don't push on PR)\n      # https://github.com/docker/build-push-action\n      - name: Build and push Docker image\n        id: build-and-push\n        uses: docker/build-push-action@v6\n        with:\n          builder: ${{ steps.buildx.outputs.name }}\n          context: .\n          platforms: linux/amd64,linux/arm64\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}"
  },
  {
    "path": ".last_upstream_tag",
    "content": "1.5.3-beta.0\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM node:alpine\n\nWORKDIR /data\n\nRUN apk add --no-cache tini \\\n    && npm i musicn -g \\\n    && rm -rf ${HOME}/.npm\n\nENTRYPOINT [\"/sbin/tini\", \"--\"]"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 wy580477\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "## 鸣谢\n\n- [zonemeen/musicn](https://github.com/zonemeen/musicn)\n\n## 概述\n\n可播放及下载音乐的命令行工具 [musicn](https://github.com/zonemeen/musicn) 的容器版本，支持 amd64/arm64 架构。\n\n目前已不能下载无损格式。\n\n![image](https://user-images.githubusercontent.com/98247050/230909773-52d95ba7-e42e-4612-86dd-7cb363bc3f2f.png)\n\n\n## 部署\n\n  命令行 + Web 模式\n  ```\n  docker run -d --name=musicn --restart=unless-stopped -v ${PWD}/musicn:/data -p 7478:7478 ghcr.io/wy580477/musicn-container:latest msc -q\n  ```\n  仅命令行模式 （空闲时几乎不耗内存）\n  ```\n  docker run -d --name=musicn --restart=unless-stopped -v ${PWD}/musicn:/data ghcr.io/wy580477/musicn-container:latest tail -f\n  ```\n  ${PWD}/musicn 为命令行模式下载文件存放目录，默认当前目录下 musicn 文件夹。\n  \n  执行 musicn 命令:\n\n  ```\n  docker exec -it musicn msc 周杰伦\n  \n  # 设置 bash 命令别名方便使用，重新登陆 shell 后生效\n  echo \"alias msc='docker exec -it musicn msc'\" >> ~/.bashrc\n  \n  # 查看命令帮助\n  msc -h\n  \n  # 指定子目录 test 为下载目录\n  msc 周杰伦 -p ./test\n  \n  # 升级版本\n  docker container rm musicn --force && docker pull ghcr.io/wy580477/musicn-container:latest\n  # 然后重新执行安装命令\n  \n  # 容器内升级 （不推荐，万一我以后弃坑不更新 image 版本，可以用这个方法更新）\n  docker exec -it musicn npm i musicn -g\n  ```\n  更多命令用法详见： [musicn 文档](https://github.com/zonemeen/musicn#%E6%90%9C%E7%B4%A2%E7%9A%84%E9%A1%B5%E7%A0%81%E6%95%B0%E9%BB%98%E8%AE%A4%E6%98%AF%E7%AC%AC1%E9%A1%B5)\n  \n  访问 http://<宿主机 ip>:7478 可到达 Web 搜索和下载界面。(扫码访问功能不可用, 请手动输入网址访问)\n  \n  ![image](https://user-images.githubusercontent.com/98247050/230908384-99c5d283-26f6-4a9b-aa9f-104ccf7e4702.png)\n  \n### Docker-Compose 部署\n  命令行 + Web 模式\n```\nversion: '3.4'\nservices:\n\n  musicn:\n    image: ghcr.io/wy580477/musicn-container:latest\n    container_name: musicn\n    restart: unless-stopped\n    entrypoint: [\"/sbin/tini\", \"--\", \"msc\", \"-q\"]\n    ports:\n      - \"7478:7478\"\n    volumes:\n      - ./musicn:/data\n ``` \n   \n仅命令行模式\n```\nversion: '3.4'\nservices:\n\n  musicn:\n    image: ghcr.io/wy580477/musicn-container:latest\n    container_name: musicn\n    restart: unless-stopped\n    entrypoint: [\"/sbin/tini\", \"--\", \"tail\", \"-f\"]\n    volumes:\n      - ./musicn:/data\n ``` \n  \n"
  }
]