public async Task RunAsync(
            RunnerActionPluginExecutionContext context,
            CancellationToken token)
        {
            ArgUtil.NotNull(context, nameof(context));
            string artifactName = context.GetInput(DownloadArtifactInputNames.ArtifactName, required: false); // Back compat since we rename input `artifact` to `name`

            if (string.IsNullOrEmpty(artifactName))
            {
                artifactName = context.GetInput(DownloadArtifactInputNames.Name, required: true);
            }

            string targetPath = context.GetInput(DownloadArtifactInputNames.Path, required: false);
            string defaultWorkingDirectory = context.GetGitHubContext("workspace");

            if (string.IsNullOrEmpty(targetPath))
            {
                targetPath = artifactName;
            }

            targetPath = Path.IsPathFullyQualified(targetPath) ? targetPath : Path.GetFullPath(Path.Combine(defaultWorkingDirectory, targetPath));

            // Build ID
            string buildIdStr = context.Variables.GetValueOrDefault(SdkConstants.Variables.Build.BuildId)?.Value ?? string.Empty;

            if (!int.TryParse(buildIdStr, out int buildId))
            {
                throw new ArgumentException($"Run Id is not an Int32: {buildIdStr}");
            }

            context.Output($"Downloading artifact '{artifactName}' to: '{targetPath}'");

            // Definition ID is a dummy value only used by HTTP client routing purposes
            int definitionId = 1;

            var pipelinesHelper = new PipelinesServer(context.VssConnection);

            var actionsStorageArtifact = await pipelinesHelper.GetActionsStorageArtifact(definitionId, buildId, artifactName, token);

            if (actionsStorageArtifact == null)
            {
                throw new Exception($"The actions storage artifact for '{artifactName}' could not be found, or is no longer available");
            }

            string containerPath = actionsStorageArtifact.Name; // In actions storage artifacts, name equals the path
            long   containerId   = actionsStorageArtifact.ContainerId;

            FileContainerServer fileContainerServer = new FileContainerServer(context.VssConnection, projectId: new Guid(), containerId, containerPath);
            await fileContainerServer.DownloadFromContainerAsync(context, targetPath, token);

            context.Output("Artifact download finished.");
        }
Esempio n. 2
0
        public async Task RunAsync(
            RunnerActionPluginExecutionContext context,
            CancellationToken token)
        {
            string artifactName = context.GetInput(PublishArtifactInputNames.ArtifactName, required: false);  // Back compat since we rename input `artifactName` to `name`

            if (string.IsNullOrEmpty(artifactName))
            {
                artifactName = context.GetInput(PublishArtifactInputNames.Name, required: true);
            }

            string targetPath = context.GetInput(PublishArtifactInputNames.Path, required: true);
            string defaultWorkingDirectory = context.GetGitHubContext("workspace");

            targetPath = Path.IsPathFullyQualified(targetPath) ? targetPath : Path.GetFullPath(Path.Combine(defaultWorkingDirectory, targetPath));

            if (String.IsNullOrWhiteSpace(artifactName))
            {
                throw new ArgumentException($"Artifact name can not be empty string");
            }

            if (Path.GetInvalidFileNameChars().Any(x => artifactName.Contains(x)))
            {
                throw new ArgumentException($"Artifact name is not valid: {artifactName}. It cannot contain '\\', '/', \"', ':', '<', '>', '|', '*', and '?'");
            }

            // Build ID
            string buildIdStr = context.Variables.GetValueOrDefault(SdkConstants.Variables.Build.BuildId)?.Value ?? string.Empty;

            if (!int.TryParse(buildIdStr, out int buildId))
            {
                throw new ArgumentException($"Run Id is not an Int32: {buildIdStr}");
            }

            string fullPath = Path.GetFullPath(targetPath);
            bool   isFile   = File.Exists(fullPath);
            bool   isDir    = Directory.Exists(fullPath);

            if (!isFile && !isDir)
            {
                // if local path is neither file nor folder
                throw new FileNotFoundException($"Path does not exist {targetPath}");
            }

            // Container ID
            string containerIdStr = context.Variables.GetValueOrDefault(SdkConstants.Variables.Build.ContainerId)?.Value ?? string.Empty;

            if (!long.TryParse(containerIdStr, out long containerId))
            {
                throw new ArgumentException($"Container Id is not an Int64: {containerIdStr}");
            }

            context.Output($"Uploading artifact '{artifactName}' from '{fullPath}' for run #{buildId}");

            FileContainerServer fileContainerHelper = new FileContainerServer(context.VssConnection, projectId: Guid.Empty, containerId, artifactName);
            var propertiesDictionary = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            long size = 0;

            try
            {
                size = await fileContainerHelper.CopyToContainerAsync(context, fullPath, token);

                propertiesDictionary.Add("artifactsize", size.ToString());

                context.Output($"Uploaded '{size}' bytes from '{fullPath}' to server");
            }
            // if any of the results were successful, make sure to attach them to the build
            finally
            {
                // Definition ID is a dummy value only used by HTTP client routing purposes
                int definitionId = 1;

                PipelinesServer pipelinesHelper = new PipelinesServer(context.VssConnection);

                var artifact = await pipelinesHelper.AssociateActionsStorageArtifactAsync(
                    definitionId,
                    buildId,
                    containerId,
                    artifactName,
                    size,
                    token);

                context.Output($"Associated artifact {artifactName} ({artifact.ContainerId}) with run #{buildId}");
            }
        }